Completed
Branch addon-registration-fixes (fa6bd4)
by
unknown
17:40 queued 15:48
created
admin_pages/messages/Messages_Admin_Page.core.php 1 patch
Indentation   +4541 added lines, -4541 removed lines patch added patch discarded remove patch
@@ -19,2642 +19,2642 @@  discard block
 block discarded – undo
19 19
 class Messages_Admin_Page extends EE_Admin_Page
20 20
 {
21 21
 
22
-    /**
23
-     * @type EE_Message_Resource_Manager $_message_resource_manager
24
-     */
25
-    protected $_message_resource_manager;
26
-
27
-    /**
28
-     * @type string $_active_message_type_name
29
-     */
30
-    protected $_active_message_type_name = '';
31
-
32
-    /**
33
-     * @type EE_messenger $_active_messenger
34
-     */
35
-    protected $_active_messenger;
36
-    protected $_activate_state;
37
-    protected $_activate_meta_box_type;
38
-    protected $_current_message_meta_box;
39
-    protected $_current_message_meta_box_object;
40
-    protected $_context_switcher;
41
-    protected $_shortcodes = array();
42
-    protected $_active_messengers = array();
43
-    protected $_active_message_types = array();
44
-
45
-    /**
46
-     * @var EE_Message_Template_Group $_message_template_group
47
-     */
48
-    protected $_message_template_group;
49
-    protected $_m_mt_settings = array();
50
-
51
-
52
-    /**
53
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
-     * IF there is no group then it gets automatically set to the Default template pack.
55
-     *
56
-     * @since 4.5.0
57
-     *
58
-     * @var EE_Messages_Template_Pack
59
-     */
60
-    protected $_template_pack;
61
-
62
-
63
-    /**
64
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
-     * group is.  If there is no group then it automatically gets set to default.
66
-     *
67
-     * @since 4.5.0
68
-     *
69
-     * @var string
70
-     */
71
-    protected $_variation;
72
-
73
-
74
-    /**
75
-     * @param bool $routing
76
-     * @throws EE_Error
77
-     */
78
-    public function __construct($routing = true)
79
-    {
80
-        // make sure messages autoloader is running
81
-        EED_Messages::set_autoloaders();
82
-        parent::__construct($routing);
83
-    }
84
-
85
-
86
-    protected function _init_page_props()
87
-    {
88
-        $this->page_slug = EE_MSG_PG_SLUG;
89
-        $this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
-        $this->_admin_base_url = EE_MSG_ADMIN_URL;
91
-        $this->_admin_base_path = EE_MSG_ADMIN;
92
-
93
-        $this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
-            : array();
95
-
96
-        $this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
-        $this->_load_message_resource_manager();
98
-    }
99
-
100
-
101
-    /**
102
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
-     *
104
-     * @throws EE_Error
105
-     * @throws InvalidDataTypeException
106
-     * @throws InvalidInterfaceException
107
-     * @throws InvalidArgumentException
108
-     * @throws ReflectionException
109
-     */
110
-    protected function _load_message_resource_manager()
111
-    {
112
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
-    }
114
-
115
-
116
-    /**
117
-     * @deprecated 4.9.9.rc.014
118
-     * @return array
119
-     * @throws EE_Error
120
-     * @throws InvalidArgumentException
121
-     * @throws InvalidDataTypeException
122
-     * @throws InvalidInterfaceException
123
-     */
124
-    public function get_messengers_for_list_table()
125
-    {
126
-        EE_Error::doing_it_wrong(
127
-            __METHOD__,
128
-            sprintf(
129
-                esc_html__(
130
-                    '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',
131
-                    'event_espresso'
132
-                ),
133
-                'Messages_Admin_Page::get_messengers_select_input()'
134
-            ),
135
-            '4.9.9.rc.014'
136
-        );
137
-
138
-        $m_values = array();
139
-        $active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
-        // setup messengers for selects
141
-        $i = 1;
142
-        foreach ($active_messengers as $active_messenger) {
143
-            if ($active_messenger instanceof EE_Message) {
144
-                $m_values[ $i ]['id'] = $active_messenger->messenger();
145
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
-                $i++;
147
-            }
148
-        }
149
-
150
-        return $m_values;
151
-    }
152
-
153
-
154
-    /**
155
-     * @deprecated 4.9.9.rc.014
156
-     * @return array
157
-     * @throws EE_Error
158
-     * @throws InvalidArgumentException
159
-     * @throws InvalidDataTypeException
160
-     * @throws InvalidInterfaceException
161
-     */
162
-    public function get_message_types_for_list_table()
163
-    {
164
-        EE_Error::doing_it_wrong(
165
-            __METHOD__,
166
-            sprintf(
167
-                esc_html__(
168
-                    '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',
169
-                    'event_espresso'
170
-                ),
171
-                'Messages_Admin_Page::get_message_types_select_input()'
172
-            ),
173
-            '4.9.9.rc.014'
174
-        );
175
-
176
-        $mt_values = array();
177
-        $active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
-        $i = 1;
179
-        foreach ($active_messages as $active_message) {
180
-            if ($active_message instanceof EE_Message) {
181
-                $mt_values[ $i ]['id'] = $active_message->message_type();
182
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
-                $i++;
184
-            }
185
-        }
186
-
187
-        return $mt_values;
188
-    }
189
-
190
-
191
-    /**
192
-     * @deprecated 4.9.9.rc.014
193
-     * @return array
194
-     * @throws EE_Error
195
-     * @throws InvalidArgumentException
196
-     * @throws InvalidDataTypeException
197
-     * @throws InvalidInterfaceException
198
-     */
199
-    public function get_contexts_for_message_types_for_list_table()
200
-    {
201
-        EE_Error::doing_it_wrong(
202
-            __METHOD__,
203
-            sprintf(
204
-                esc_html__(
205
-                    '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',
206
-                    'event_espresso'
207
-                ),
208
-                'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
-            ),
210
-            '4.9.9.rc.014'
211
-        );
212
-
213
-        $contexts = array();
214
-        $active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
-        foreach ($active_message_contexts as $active_message) {
216
-            if ($active_message instanceof EE_Message) {
217
-                $message_type = $active_message->message_type_object();
218
-                if ($message_type instanceof EE_message_type) {
219
-                    $message_type_contexts = $message_type->get_contexts();
220
-                    foreach ($message_type_contexts as $context => $context_details) {
221
-                        $contexts[ $context ] = $context_details['label'];
222
-                    }
223
-                }
224
-            }
225
-        }
226
-
227
-        return $contexts;
228
-    }
229
-
230
-
231
-    /**
232
-     * Generate select input with provided messenger options array.
233
-     *
234
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
-     *                                 labels.
236
-     * @return string
237
-     * @throws EE_Error
238
-     */
239
-    public function get_messengers_select_input($messenger_options)
240
-    {
241
-        // if empty or just one value then just return an empty string
242
-        if (empty($messenger_options)
243
-            || ! is_array($messenger_options)
244
-            || count($messenger_options) === 1
245
-        ) {
246
-            return '';
247
-        }
248
-        // merge in default
249
-        $messenger_options = array_merge(
250
-            array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
251
-            $messenger_options
252
-        );
253
-        $input = new EE_Select_Input(
254
-            $messenger_options,
255
-            array(
256
-                'html_name'  => 'ee_messenger_filter_by',
257
-                'html_id'    => 'ee_messenger_filter_by',
258
-                'html_class' => 'wide',
259
-                'default'    => isset($this->_req_data['ee_messenger_filter_by'])
260
-                    ? sanitize_title($this->_req_data['ee_messenger_filter_by'])
261
-                    : 'none_selected',
262
-            )
263
-        );
264
-
265
-        return $input->get_html_for_input();
266
-    }
267
-
268
-
269
-    /**
270
-     * Generate select input with provided message type options array.
271
-     *
272
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
273
-     *                                    message type labels
274
-     * @return string
275
-     * @throws EE_Error
276
-     */
277
-    public function get_message_types_select_input($message_type_options)
278
-    {
279
-        // if empty or count of options is 1 then just return an empty string
280
-        if (empty($message_type_options)
281
-            || ! is_array($message_type_options)
282
-            || count($message_type_options) === 1
283
-        ) {
284
-            return '';
285
-        }
286
-        // merge in default
287
-        $message_type_options = array_merge(
288
-            array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
289
-            $message_type_options
290
-        );
291
-        $input = new EE_Select_Input(
292
-            $message_type_options,
293
-            array(
294
-                'html_name'  => 'ee_message_type_filter_by',
295
-                'html_id'    => 'ee_message_type_filter_by',
296
-                'html_class' => 'wide',
297
-                'default'    => isset($this->_req_data['ee_message_type_filter_by'])
298
-                    ? sanitize_title($this->_req_data['ee_message_type_filter_by'])
299
-                    : 'none_selected',
300
-            )
301
-        );
302
-
303
-        return $input->get_html_for_input();
304
-    }
305
-
306
-
307
-    /**
308
-     * Generate select input with provide message type contexts array.
309
-     *
310
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
311
-     *                               context label.
312
-     * @return string
313
-     * @throws EE_Error
314
-     */
315
-    public function get_contexts_for_message_types_select_input($context_options)
316
-    {
317
-        // if empty or count of options is one then just return empty string
318
-        if (empty($context_options)
319
-            || ! is_array($context_options)
320
-            || count($context_options) === 1
321
-        ) {
322
-            return '';
323
-        }
324
-        // merge in default
325
-        $context_options = array_merge(
326
-            array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
327
-            $context_options
328
-        );
329
-        $input = new EE_Select_Input(
330
-            $context_options,
331
-            array(
332
-                'html_name'  => 'ee_context_filter_by',
333
-                'html_id'    => 'ee_context_filter_by',
334
-                'html_class' => 'wide',
335
-                'default'    => isset($this->_req_data['ee_context_filter_by'])
336
-                    ? sanitize_title($this->_req_data['ee_context_filter_by'])
337
-                    : 'none_selected',
338
-            )
339
-        );
340
-
341
-        return $input->get_html_for_input();
342
-    }
343
-
344
-
345
-    protected function _ajax_hooks()
346
-    {
347
-        add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
348
-        add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
349
-        add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
350
-        add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
351
-        add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
352
-        add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
353
-    }
354
-
355
-
356
-    protected function _define_page_props()
357
-    {
358
-        $this->_admin_page_title = $this->page_label;
359
-        $this->_labels = array(
360
-            'buttons'    => array(
361
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
362
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
363
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
364
-            ),
365
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
366
-        );
367
-    }
368
-
369
-
370
-    /**
371
-     *        an array for storing key => value pairs of request actions and their corresponding methods
372
-     *
373
-     * @access protected
374
-     * @return void
375
-     */
376
-    protected function _set_page_routes()
377
-    {
378
-        $grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
379
-            ? $this->_req_data['GRP_ID']
380
-            : 0;
381
-        $grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
382
-            ? $this->_req_data['id']
383
-            : $grp_id;
384
-        $msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
385
-            ? $this->_req_data['MSG_ID']
386
-            : 0;
387
-
388
-        $this->_page_routes = array(
389
-            'default'                          => array(
390
-                'func'       => '_message_queue_list_table',
391
-                'capability' => 'ee_read_global_messages',
392
-            ),
393
-            'global_mtps'                      => array(
394
-                'func'       => '_ee_default_messages_overview_list_table',
395
-                'capability' => 'ee_read_global_messages',
396
-            ),
397
-            'custom_mtps'                      => array(
398
-                'func'       => '_custom_mtps_preview',
399
-                'capability' => 'ee_read_messages',
400
-            ),
401
-            'add_new_message_template'         => array(
402
-                'func'       => '_add_message_template',
403
-                'capability' => 'ee_edit_messages',
404
-                'noheader'   => true,
405
-            ),
406
-            'edit_message_template'            => array(
407
-                'func'       => '_edit_message_template',
408
-                'capability' => 'ee_edit_message',
409
-                'obj_id'     => $grp_id,
410
-            ),
411
-            'preview_message'                  => array(
412
-                'func'               => '_preview_message',
413
-                'capability'         => 'ee_read_message',
414
-                'obj_id'             => $grp_id,
415
-                'noheader'           => true,
416
-                'headers_sent_route' => 'display_preview_message',
417
-            ),
418
-            'display_preview_message'          => array(
419
-                'func'       => '_display_preview_message',
420
-                'capability' => 'ee_read_message',
421
-                'obj_id'     => $grp_id,
422
-            ),
423
-            'insert_message_template'          => array(
424
-                'func'       => '_insert_or_update_message_template',
425
-                'capability' => 'ee_edit_messages',
426
-                'args'       => array('new_template' => true),
427
-                'noheader'   => true,
428
-            ),
429
-            'update_message_template'          => array(
430
-                'func'       => '_insert_or_update_message_template',
431
-                'capability' => 'ee_edit_message',
432
-                'obj_id'     => $grp_id,
433
-                'args'       => array('new_template' => false),
434
-                'noheader'   => true,
435
-            ),
436
-            'trash_message_template'           => array(
437
-                'func'       => '_trash_or_restore_message_template',
438
-                'capability' => 'ee_delete_message',
439
-                'obj_id'     => $grp_id,
440
-                'args'       => array('trash' => true, 'all' => true),
441
-                'noheader'   => true,
442
-            ),
443
-            'trash_message_template_context'   => array(
444
-                'func'       => '_trash_or_restore_message_template',
445
-                'capability' => 'ee_delete_message',
446
-                'obj_id'     => $grp_id,
447
-                'args'       => array('trash' => true),
448
-                'noheader'   => true,
449
-            ),
450
-            'restore_message_template'         => array(
451
-                'func'       => '_trash_or_restore_message_template',
452
-                'capability' => 'ee_delete_message',
453
-                'obj_id'     => $grp_id,
454
-                'args'       => array('trash' => false, 'all' => true),
455
-                'noheader'   => true,
456
-            ),
457
-            'restore_message_template_context' => array(
458
-                'func'       => '_trash_or_restore_message_template',
459
-                'capability' => 'ee_delete_message',
460
-                'obj_id'     => $grp_id,
461
-                'args'       => array('trash' => false),
462
-                'noheader'   => true,
463
-            ),
464
-            'delete_message_template'          => array(
465
-                'func'       => '_delete_message_template',
466
-                'capability' => 'ee_delete_message',
467
-                'obj_id'     => $grp_id,
468
-                'noheader'   => true,
469
-            ),
470
-            'reset_to_default'                 => array(
471
-                'func'       => '_reset_to_default_template',
472
-                'capability' => 'ee_edit_message',
473
-                'obj_id'     => $grp_id,
474
-                'noheader'   => true,
475
-            ),
476
-            'settings'                         => array(
477
-                'func'       => '_settings',
478
-                'capability' => 'manage_options',
479
-            ),
480
-            'update_global_settings'           => array(
481
-                'func'       => '_update_global_settings',
482
-                'capability' => 'manage_options',
483
-                'noheader'   => true,
484
-            ),
485
-            'generate_now'                     => array(
486
-                'func'       => '_generate_now',
487
-                'capability' => 'ee_send_message',
488
-                'noheader'   => true,
489
-            ),
490
-            'generate_and_send_now'            => array(
491
-                'func'       => '_generate_and_send_now',
492
-                'capability' => 'ee_send_message',
493
-                'noheader'   => true,
494
-            ),
495
-            'queue_for_resending'              => array(
496
-                'func'       => '_queue_for_resending',
497
-                'capability' => 'ee_send_message',
498
-                'noheader'   => true,
499
-            ),
500
-            'send_now'                         => array(
501
-                'func'       => '_send_now',
502
-                'capability' => 'ee_send_message',
503
-                'noheader'   => true,
504
-            ),
505
-            'delete_ee_message'                => array(
506
-                'func'       => '_delete_ee_messages',
507
-                'capability' => 'ee_delete_messages',
508
-                'noheader'   => true,
509
-            ),
510
-            'delete_ee_messages'               => array(
511
-                'func'       => '_delete_ee_messages',
512
-                'capability' => 'ee_delete_messages',
513
-                'noheader'   => true,
514
-                'obj_id'     => $msg_id,
515
-            ),
516
-        );
517
-    }
518
-
519
-
520
-    protected function _set_page_config()
521
-    {
522
-        $this->_page_config = array(
523
-            'default'                  => array(
524
-                'nav'           => array(
525
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
526
-                    'order' => 10,
527
-                ),
528
-                'list_table'    => 'EE_Message_List_Table',
529
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
530
-                'require_nonce' => false,
531
-            ),
532
-            'global_mtps'              => array(
533
-                'nav'           => array(
534
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
535
-                    'order' => 20,
536
-                ),
537
-                'list_table'    => 'Messages_Template_List_Table',
538
-                'help_tabs'     => array(
539
-                    'messages_overview_help_tab'                                => array(
540
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
541
-                        'filename' => 'messages_overview',
542
-                    ),
543
-                    'messages_overview_messages_table_column_headings_help_tab' => array(
544
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
545
-                        'filename' => 'messages_overview_table_column_headings',
546
-                    ),
547
-                    'messages_overview_messages_filters_help_tab'               => array(
548
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
549
-                        'filename' => 'messages_overview_filters',
550
-                    ),
551
-                    'messages_overview_messages_views_help_tab'                 => array(
552
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
553
-                        'filename' => 'messages_overview_views',
554
-                    ),
555
-                    'message_overview_message_types_help_tab'                   => array(
556
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
557
-                        'filename' => 'messages_overview_types',
558
-                    ),
559
-                    'messages_overview_messengers_help_tab'                     => array(
560
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
561
-                        'filename' => 'messages_overview_messengers',
562
-                    ),
563
-                ),
564
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
565
-                // 'help_tour'     => array('Messages_Overview_Help_Tour'),
566
-                'require_nonce' => false,
567
-            ),
568
-            'custom_mtps'              => array(
569
-                'nav'           => array(
570
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
571
-                    'order' => 30,
572
-                ),
573
-                'help_tabs'     => array(),
574
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
575
-                // 'help_tour'     => array(),
576
-                'require_nonce' => false,
577
-            ),
578
-            'add_new_message_template' => array(
579
-                'nav'           => array(
580
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
581
-                    'order'      => 5,
582
-                    'persistent' => false,
583
-                ),
584
-                'require_nonce' => false,
585
-            ),
586
-            'edit_message_template'    => array(
587
-                'labels'        => array(
588
-                    'buttons'    => array(
589
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
590
-                    ),
591
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
592
-                ),
593
-                'nav'           => array(
594
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
595
-                    'order'      => 5,
596
-                    'persistent' => false,
597
-                    'url'        => '',
598
-                ),
599
-                'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
600
-                'has_metaboxes' => true,
601
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
602
-                // 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
603
-                'help_tabs'     => array(
604
-                    'edit_message_template'            => array(
605
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
606
-                        'callback' => 'edit_message_template_help_tab',
607
-                    ),
608
-                    'message_templates_help_tab'       => array(
609
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
610
-                        'filename' => 'messages_templates',
611
-                    ),
612
-                    'message_template_shortcodes'      => array(
613
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
614
-                        'callback' => 'message_template_shortcodes_help_tab',
615
-                    ),
616
-                    'message_preview_help_tab'         => array(
617
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
618
-                        'filename' => 'messages_preview',
619
-                    ),
620
-                    'messages_overview_other_help_tab' => array(
621
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
622
-                        'filename' => 'messages_overview_other',
623
-                    ),
624
-                ),
625
-                'require_nonce' => false,
626
-            ),
627
-            'display_preview_message'  => array(
628
-                'nav'           => array(
629
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
630
-                    'order'      => 5,
631
-                    'url'        => '',
632
-                    'persistent' => false,
633
-                ),
634
-                'help_tabs'     => array(
635
-                    'preview_message' => array(
636
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
637
-                        'callback' => 'preview_message_help_tab',
638
-                    ),
639
-                ),
640
-                'require_nonce' => false,
641
-            ),
642
-            'settings'                 => array(
643
-                'nav'           => array(
644
-                    'label' => esc_html__('Settings', 'event_espresso'),
645
-                    'order' => 40,
646
-                ),
647
-                'metaboxes'     => array('_messages_settings_metaboxes'),
648
-                'help_tabs'     => array(
649
-                    'messages_settings_help_tab'               => array(
650
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
651
-                        'filename' => 'messages_settings',
652
-                    ),
653
-                    'messages_settings_message_types_help_tab' => array(
654
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
655
-                        'filename' => 'messages_settings_message_types',
656
-                    ),
657
-                    'messages_settings_messengers_help_tab'    => array(
658
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
659
-                        'filename' => 'messages_settings_messengers',
660
-                    ),
661
-                ),
662
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
663
-                // 'help_tour'     => array('Messages_Settings_Help_Tour'),
664
-                'require_nonce' => false,
665
-            ),
666
-        );
667
-    }
668
-
669
-
670
-    protected function _add_screen_options()
671
-    {
672
-        // todo
673
-    }
674
-
675
-
676
-    protected function _add_screen_options_global_mtps()
677
-    {
678
-        /**
679
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
680
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
681
-         */
682
-        $page_title = $this->_admin_page_title;
683
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
684
-        $this->_per_page_screen_option();
685
-        $this->_admin_page_title = $page_title;
686
-    }
687
-
688
-
689
-    protected function _add_screen_options_default()
690
-    {
691
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
692
-        $this->_per_page_screen_option();
693
-    }
694
-
695
-
696
-    // none of the below group are currently used for Messages
697
-    protected function _add_feature_pointers()
698
-    {
699
-    }
700
-
701
-    public function admin_init()
702
-    {
703
-    }
704
-
705
-    public function admin_notices()
706
-    {
707
-    }
708
-
709
-    public function admin_footer_scripts()
710
-    {
711
-    }
712
-
713
-
714
-    public function messages_help_tab()
715
-    {
716
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
717
-    }
718
-
719
-
720
-    public function messengers_help_tab()
721
-    {
722
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
723
-    }
724
-
725
-
726
-    public function message_types_help_tab()
727
-    {
728
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
729
-    }
730
-
731
-
732
-    public function messages_overview_help_tab()
733
-    {
734
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
735
-    }
736
-
737
-
738
-    public function message_templates_help_tab()
739
-    {
740
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
741
-    }
742
-
743
-
744
-    public function edit_message_template_help_tab()
745
-    {
746
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
747
-                        . esc_attr__('Editor Title', 'event_espresso')
748
-                        . '" />';
749
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
750
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
751
-                        . '" />';
752
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
753
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
754
-                        . '" />';
755
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
756
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
757
-                        . '" />';
758
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
759
-                        . esc_attr__('Publish Metabox', 'event_espresso')
760
-                        . '" />';
761
-        EEH_Template::display_template(
762
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
763
-            $args
764
-        );
765
-    }
766
-
767
-
768
-    public function message_template_shortcodes_help_tab()
769
-    {
770
-        $this->_set_shortcodes();
771
-        $args['shortcodes'] = $this->_shortcodes;
772
-        EEH_Template::display_template(
773
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
774
-            $args
775
-        );
776
-    }
777
-
778
-
779
-    public function preview_message_help_tab()
780
-    {
781
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
782
-    }
783
-
784
-
785
-    public function settings_help_tab()
786
-    {
787
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
788
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
789
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
790
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
791
-        $args['img3'] = '<div class="switch">'
792
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
793
-                        . ' type="checkbox" checked="checked">'
794
-                        . '<label for="ee-on-off-toggle-on"></label>'
795
-                        . '</div>';
796
-        $args['img4'] = '<div class="switch">'
797
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
798
-                        . ' type="checkbox">'
799
-                        . '<label for="ee-on-off-toggle-on"></label>'
800
-                        . '</div>';
801
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
802
-    }
803
-
804
-
805
-    public function load_scripts_styles()
806
-    {
807
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
808
-        wp_enqueue_style('espresso_ee_msg');
809
-
810
-        wp_register_script(
811
-            'ee-messages-settings',
812
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
813
-            array('jquery-ui-droppable', 'ee-serialize-full-array'),
814
-            EVENT_ESPRESSO_VERSION,
815
-            true
816
-        );
817
-        wp_register_script(
818
-            'ee-msg-list-table-js',
819
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
820
-            array('ee-dialog'),
821
-            EVENT_ESPRESSO_VERSION
822
-        );
823
-    }
824
-
825
-
826
-    public function load_scripts_styles_default()
827
-    {
828
-        wp_enqueue_script('ee-msg-list-table-js');
829
-    }
830
-
831
-
832
-    public function wp_editor_css($mce_css)
833
-    {
834
-        // if we're on the edit_message_template route
835
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
836
-            $message_type_name = $this->_active_message_type_name;
837
-
838
-            // we're going to REPLACE the existing mce css
839
-            // we need to get the css file location from the active messenger
840
-            $mce_css = $this->_active_messenger->get_variation(
841
-                $this->_template_pack,
842
-                $message_type_name,
843
-                true,
844
-                'wpeditor',
845
-                $this->_variation
846
-            );
847
-        }
848
-
849
-        return $mce_css;
850
-    }
851
-
852
-
853
-    public function load_scripts_styles_edit_message_template()
854
-    {
855
-
856
-        $this->_set_shortcodes();
857
-
858
-        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
859
-            esc_html__(
860
-                '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.',
861
-                'event_espresso'
862
-            ),
863
-            $this->_message_template_group->messenger_obj()->label['singular'],
864
-            $this->_message_template_group->message_type_obj()->label['singular']
865
-        );
866
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
867
-            '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?',
868
-            'event_espresso'
869
-        );
870
-        EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
871
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
872
-            'event_espresso'
873
-        );
874
-
875
-        wp_register_script(
876
-            'ee_msgs_edit_js',
877
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
878
-            array('jquery'),
879
-            EVENT_ESPRESSO_VERSION
880
-        );
881
-
882
-        wp_enqueue_script('ee_admin_js');
883
-        wp_enqueue_script('ee_msgs_edit_js');
884
-
885
-        // add in special css for tiny_mce
886
-        add_filter('mce_css', array($this, 'wp_editor_css'));
887
-    }
888
-
889
-
890
-    public function load_scripts_styles_display_preview_message()
891
-    {
892
-
893
-        $this->_set_message_template_group();
894
-
895
-        if (isset($this->_req_data['messenger'])) {
896
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
897
-                $this->_req_data['messenger']
898
-            );
899
-        }
900
-
901
-        $message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
902
-
903
-
904
-        wp_enqueue_style(
905
-            'espresso_preview_css',
906
-            $this->_active_messenger->get_variation(
907
-                $this->_template_pack,
908
-                $message_type_name,
909
-                true,
910
-                'preview',
911
-                $this->_variation
912
-            )
913
-        );
914
-    }
915
-
916
-
917
-    public function load_scripts_styles_settings()
918
-    {
919
-        wp_register_style(
920
-            'ee-message-settings',
921
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
922
-            array(),
923
-            EVENT_ESPRESSO_VERSION
924
-        );
925
-        wp_enqueue_style('ee-text-links');
926
-        wp_enqueue_style('ee-message-settings');
927
-        wp_enqueue_script('ee-messages-settings');
928
-    }
929
-
930
-
931
-    /**
932
-     * set views array for List Table
933
-     */
934
-    public function _set_list_table_views_global_mtps()
935
-    {
936
-        $this->_views = array(
937
-            'in_use' => array(
938
-                'slug'  => 'in_use',
939
-                'label' => esc_html__('In Use', 'event_espresso'),
940
-                'count' => 0,
941
-            ),
942
-        );
943
-    }
944
-
945
-
946
-    /**
947
-     * Set views array for the Custom Template List Table
948
-     */
949
-    public function _set_list_table_views_custom_mtps()
950
-    {
951
-        $this->_set_list_table_views_global_mtps();
952
-        $this->_views['in_use']['bulk_action'] = array(
953
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
954
-        );
955
-    }
956
-
957
-
958
-    /**
959
-     * set views array for message queue list table
960
-     *
961
-     * @throws InvalidDataTypeException
962
-     * @throws InvalidInterfaceException
963
-     * @throws InvalidArgumentException
964
-     * @throws EE_Error
965
-     * @throws ReflectionException
966
-     */
967
-    public function _set_list_table_views_default()
968
-    {
969
-        EE_Registry::instance()->load_helper('Template');
970
-
971
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
972
-            'ee_send_message',
973
-            'message_list_table_bulk_actions'
974
-        )
975
-            ? array(
976
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
977
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
978
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
979
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
980
-            )
981
-            : array();
982
-
983
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
984
-            'ee_delete_messages',
985
-            'message_list_table_bulk_actions'
986
-        )
987
-            ? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
988
-            : array();
989
-
990
-
991
-        $this->_views = array(
992
-            'all' => array(
993
-                'slug'        => 'all',
994
-                'label'       => esc_html__('All', 'event_espresso'),
995
-                'count'       => 0,
996
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
997
-            ),
998
-        );
999
-
1000
-
1001
-        foreach (EEM_Message::instance()->all_statuses() as $status) {
1002
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1003
-                continue;
1004
-            }
1005
-            $status_bulk_actions = $common_bulk_actions;
1006
-            // unset bulk actions not applying to status
1007
-            if (! empty($status_bulk_actions)) {
1008
-                switch ($status) {
1009
-                    case EEM_Message::status_idle:
1010
-                    case EEM_Message::status_resend:
1011
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1012
-                        break;
1013
-
1014
-                    case EEM_Message::status_failed:
1015
-                    case EEM_Message::status_debug_only:
1016
-                    case EEM_Message::status_messenger_executing:
1017
-                        $status_bulk_actions = array();
1018
-                        break;
1019
-
1020
-                    case EEM_Message::status_incomplete:
1021
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1022
-                        break;
1023
-
1024
-                    case EEM_Message::status_retry:
1025
-                    case EEM_Message::status_sent:
1026
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1027
-                        break;
1028
-                }
1029
-            }
1030
-
1031
-            // skip adding messenger executing status to views because it will be included with the Failed view.
1032
-            if ($status === EEM_Message::status_messenger_executing) {
1033
-                continue;
1034
-            }
1035
-
1036
-            $this->_views[ strtolower($status) ] = array(
1037
-                'slug'        => strtolower($status),
1038
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1039
-                'count'       => 0,
1040
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1041
-            );
1042
-        }
1043
-    }
1044
-
1045
-
1046
-    protected function _ee_default_messages_overview_list_table()
1047
-    {
1048
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1049
-        $this->display_admin_list_table_page_with_no_sidebar();
1050
-    }
1051
-
1052
-
1053
-    protected function _message_queue_list_table()
1054
-    {
1055
-        $this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1056
-        $this->_template_args['per_column'] = 6;
1057
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1058
-        $this->_template_args['before_list_table'] = '<h3>'
1059
-                                                     . EEM_Message::instance()->get_pretty_label_for_results()
1060
-                                                     . '</h3>';
1061
-        $this->display_admin_list_table_page_with_no_sidebar();
1062
-    }
1063
-
1064
-
1065
-    protected function _message_legend_items()
1066
-    {
1067
-
1068
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1069
-        $action_items = array();
1070
-
1071
-        foreach ($action_css_classes as $action_item => $action_details) {
1072
-            if ($action_item === 'see_notifications_for') {
1073
-                continue;
1074
-            }
1075
-            $action_items[ $action_item ] = array(
1076
-                'class' => $action_details['css_class'],
1077
-                'desc'  => $action_details['label'],
1078
-            );
1079
-        }
1080
-
1081
-        /** @type array $status_items status legend setup */
1082
-        $status_items = array(
1083
-            'sent_status'                => array(
1084
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1085
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1086
-            ),
1087
-            'idle_status'                => array(
1088
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1089
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1090
-            ),
1091
-            'failed_status'              => array(
1092
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1093
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1094
-            ),
1095
-            'messenger_executing_status' => array(
1096
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1097
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1098
-            ),
1099
-            'resend_status'              => array(
1100
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1101
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1102
-            ),
1103
-            'incomplete_status'          => array(
1104
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1105
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1106
-            ),
1107
-            'retry_status'               => array(
1108
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1109
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1110
-            ),
1111
-        );
1112
-        if (EEM_Message::debug()) {
1113
-            $status_items['debug_only_status'] = array(
1114
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1115
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1116
-            );
1117
-        }
1118
-
1119
-        return array_merge($action_items, $status_items);
1120
-    }
1121
-
1122
-
1123
-    protected function _custom_mtps_preview()
1124
-    {
1125
-        $this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1126
-        $this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1127
-                                               . ' alt="' . esc_attr__(
1128
-                                                   'Preview Custom Message Templates screenshot',
1129
-                                                   'event_espresso'
1130
-                                               ) . '" />';
1131
-        $this->_template_args['preview_text'] = '<strong>'
1132
-                                                . esc_html__(
1133
-                                                    '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.',
1134
-                                                    'event_espresso'
1135
-                                                )
1136
-                                                . '</strong>';
1137
-
1138
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1139
-    }
1140
-
1141
-
1142
-    /**
1143
-     * get_message_templates
1144
-     * This gets all the message templates for listing on the overview list.
1145
-     *
1146
-     * @access public
1147
-     * @param int    $perpage the amount of templates groups to show per page
1148
-     * @param string $type    the current _view we're getting templates for
1149
-     * @param bool   $count   return count?
1150
-     * @param bool   $all     disregard any paging info (get all data);
1151
-     * @param bool   $global  whether to return just global (true) or custom templates (false)
1152
-     * @return array
1153
-     * @throws EE_Error
1154
-     * @throws InvalidArgumentException
1155
-     * @throws InvalidDataTypeException
1156
-     * @throws InvalidInterfaceException
1157
-     */
1158
-    public function get_message_templates(
1159
-        $perpage = 10,
1160
-        $type = 'in_use',
1161
-        $count = false,
1162
-        $all = false,
1163
-        $global = true
1164
-    ) {
1165
-
1166
-        $MTP = EEM_Message_Template_Group::instance();
1167
-
1168
-        $this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1169
-        $orderby = $this->_req_data['orderby'];
1170
-
1171
-        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1172
-            ? $this->_req_data['order']
1173
-            : 'ASC';
1174
-
1175
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1176
-            ? $this->_req_data['paged']
1177
-            : 1;
1178
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1179
-            ? $this->_req_data['perpage']
1180
-            : $perpage;
1181
-
1182
-        $offset = ($current_page - 1) * $per_page;
1183
-        $limit = $all ? null : array($offset, $per_page);
1184
-
1185
-
1186
-        // options will match what is in the _views array property
1187
-        switch ($type) {
1188
-            case 'in_use':
1189
-                $templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1190
-                break;
1191
-            default:
1192
-                $templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1193
-        }
1194
-
1195
-        return $templates;
1196
-    }
1197
-
1198
-
1199
-    /**
1200
-     * filters etc might need a list of installed message_types
1201
-     *
1202
-     * @return array an array of message type objects
1203
-     */
1204
-    public function get_installed_message_types()
1205
-    {
1206
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1207
-        $installed = array();
1208
-
1209
-        foreach ($installed_message_types as $message_type) {
1210
-            $installed[ $message_type->name ] = $message_type;
1211
-        }
1212
-
1213
-        return $installed;
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * _add_message_template
1219
-     *
1220
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1221
-     *
1222
-     * @param string $message_type
1223
-     * @param string $messenger
1224
-     * @param string $GRP_ID
1225
-     *
1226
-     * @throws EE_error
1227
-     */
1228
-    protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1229
-    {
1230
-        // set values override any request data
1231
-        $message_type = ! empty($message_type) ? $message_type : '';
1232
-        $message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1233
-            ? $this->_req_data['message_type']
1234
-            : $message_type;
1235
-
1236
-        $messenger = ! empty($messenger) ? $messenger : '';
1237
-        $messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1238
-            ? $this->_req_data['messenger']
1239
-            : $messenger;
1240
-
1241
-        $GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1242
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1243
-
1244
-        // we need messenger and message type.  They should be coming from the event editor. If not here then return error
1245
-        if (empty($message_type) || empty($messenger)) {
1246
-            throw new EE_Error(
1247
-                esc_html__(
1248
-                    'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1249
-                    'event_espresso'
1250
-                )
1251
-            );
1252
-        }
1253
-
1254
-        // we need the GRP_ID for the template being used as the base for the new template
1255
-        if (empty($GRP_ID)) {
1256
-            throw new EE_Error(
1257
-                esc_html__(
1258
-                    'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1259
-                    'event_espresso'
1260
-                )
1261
-            );
1262
-        }
1263
-
1264
-        // let's just make sure the template gets generated!
1265
-
1266
-        // we need to reassign some variables for what the insert is expecting
1267
-        $this->_req_data['MTP_messenger'] = $messenger;
1268
-        $this->_req_data['MTP_message_type'] = $message_type;
1269
-        $this->_req_data['GRP_ID'] = $GRP_ID;
1270
-        $this->_insert_or_update_message_template(true);
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * public wrapper for the _add_message_template method
1276
-     *
1277
-     * @param string $message_type     message type slug
1278
-     * @param string $messenger        messenger slug
1279
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1280
-     *                                 off of.
1281
-     * @throws EE_error
1282
-     */
1283
-    public function add_message_template($message_type, $messenger, $GRP_ID)
1284
-    {
1285
-        $this->_add_message_template($message_type, $messenger, $GRP_ID);
1286
-    }
1287
-
1288
-
1289
-    /**
1290
-     * _edit_message_template
1291
-     *
1292
-     * @access protected
1293
-     * @return void
1294
-     * @throws InvalidIdentifierException
1295
-     * @throws DomainException
1296
-     * @throws EE_Error
1297
-     * @throws InvalidArgumentException
1298
-     * @throws ReflectionException
1299
-     * @throws InvalidDataTypeException
1300
-     * @throws InvalidInterfaceException
1301
-     */
1302
-    protected function _edit_message_template()
1303
-    {
1304
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1305
-        $template_fields = '';
1306
-        $sidebar_fields = '';
1307
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1308
-        // valid html in the templates.
1309
-        add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1310
-
1311
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1312
-            ? absint($this->_req_data['id'])
1313
-            : false;
1314
-
1315
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1316
-        ? absint($this->_req_data['evt_id'])
1317
-        : false;
1318
-
1319
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1320
-        $message_template_group = $this->_message_template_group;
1321
-        $c_label = $message_template_group->context_label();
1322
-        $c_config = $message_template_group->contexts_config();
1323
-
1324
-        reset($c_config);
1325
-        $context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1326
-            ? strtolower($this->_req_data['context'])
1327
-            : key($c_config);
1328
-
1329
-
1330
-        if (empty($GRP_ID)) {
1331
-            $action = 'insert_message_template';
1332
-            $edit_message_template_form_url = add_query_arg(
1333
-                array('action' => $action, 'noheader' => true),
1334
-                EE_MSG_ADMIN_URL
1335
-            );
1336
-        } else {
1337
-            $action = 'update_message_template';
1338
-            $edit_message_template_form_url = add_query_arg(
1339
-                array('action' => $action, 'noheader' => true),
1340
-                EE_MSG_ADMIN_URL
1341
-            );
1342
-        }
1343
-
1344
-        // set active messenger for this view
1345
-        $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1346
-            $message_template_group->messenger()
1347
-        );
1348
-        $this->_active_message_type_name = $message_template_group->message_type();
1349
-
1350
-
1351
-        // Do we have any validation errors?
1352
-        $validators = $this->_get_transient();
1353
-        $v_fields = ! empty($validators) ? array_keys($validators) : array();
1354
-
1355
-
1356
-        // we need to assemble the title from Various details
1357
-        $context_label = sprintf(
1358
-            esc_html__('(%s %s)', 'event_espresso'),
1359
-            $c_config[ $context ]['label'],
1360
-            ucwords($c_label['label'])
1361
-        );
1362
-
1363
-        $title = sprintf(
1364
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1365
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1366
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1367
-            $context_label
1368
-        );
1369
-
1370
-        $this->_template_args['GRP_ID'] = $GRP_ID;
1371
-        $this->_template_args['message_template'] = $message_template_group;
1372
-        $this->_template_args['is_extra_fields'] = false;
1373
-
1374
-
1375
-        // let's get EEH_MSG_Template so we can get template form fields
1376
-        $template_field_structure = EEH_MSG_Template::get_fields(
1377
-            $message_template_group->messenger(),
1378
-            $message_template_group->message_type()
1379
-        );
1380
-
1381
-        if (! $template_field_structure) {
1382
-            $template_field_structure = false;
1383
-            $template_fields = esc_html__(
1384
-                'There was an error in assembling the fields for this display (you should see an error message)',
1385
-                'event_espresso'
1386
-            );
1387
-        }
1388
-
1389
-
1390
-        $message_templates = $message_template_group->context_templates();
1391
-
1392
-
1393
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1394
-        // will get handled in the "extra" array.
1395
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1396
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1397
-                unset($template_field_structure[ $context ][ $reference_field ]);
1398
-            }
1399
-        }
1400
-
1401
-        // let's loop through the template_field_structure and actually assemble the input fields!
1402
-        if (! empty($template_field_structure)) {
1403
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1404
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1405
-                // the extra array and reset them.
1406
-                if ($template_field === 'extra') {
1407
-                    $this->_template_args['is_extra_fields'] = true;
1408
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1409
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1410
-                        $content = $message_template instanceof EE_Message_Template
1411
-                            ? $message_template->get('MTP_content')
1412
-                            : '';
1413
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1414
-                            // let's verify if we need this extra field via the shortcodes parameter.
1415
-                            $continue = false;
1416
-                            if (isset($extra_array['shortcodes_required'])) {
1417
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1418
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1419
-                                        $continue = true;
1420
-                                    }
1421
-                                }
1422
-                                if ($continue) {
1423
-                                    continue;
1424
-                                }
1425
-                            }
1426
-
1427
-                            $field_id = $reference_field
1428
-                                        . '-'
1429
-                                        . $extra_field
1430
-                                        . '-content';
1431
-                            $template_form_fields[ $field_id ] = $extra_array;
1432
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1433
-                                                                         . $reference_field
1434
-                                                                         . '][content]['
1435
-                                                                         . $extra_field . ']';
1436
-                            $css_class = isset($extra_array['css_class'])
1437
-                                ? $extra_array['css_class']
1438
-                                : '';
1439
-
1440
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1441
-                                                                              && in_array($extra_field, $v_fields, true)
1442
-                                                                              &&
1443
-                                                                              (
1444
-                                                                                  is_array($validators[ $extra_field ])
1445
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1446
-                                                                              )
1447
-                                ? 'validate-error ' . $css_class
1448
-                                : $css_class;
1449
-
1450
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1451
-                                                                          && isset($content[ $extra_field ])
1452
-                                ? $content[ $extra_field ]
1453
-                                : '';
1454
-
1455
-                            // do we have a validation error?  if we do then let's use that value instead
1456
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1457
-                                ? $validators[ $extra_field ]['value']
1458
-                                : $template_form_fields[ $field_id ]['value'];
1459
-
1460
-
1461
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1462
-
1463
-                            // shortcode selector
1464
-                            $field_name_to_use = $extra_field === 'main'
1465
-                                ? 'content'
1466
-                                : $extra_field;
1467
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1468
-                                $field_name_to_use,
1469
-                                $field_id
1470
-                            );
1471
-
1472
-                            if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1473
-                                // we want to decode the entities
1474
-                                $template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1475
-                            }/**/
1476
-                        }
1477
-                        $templatefield_MTP_id = $reference_field . '-MTP_ID';
1478
-                        $templatefield_templatename_id = $reference_field . '-name';
1479
-
1480
-                        $template_form_fields[ $templatefield_MTP_id ] = array(
1481
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1482
-                            'label'      => null,
1483
-                            'input'      => 'hidden',
1484
-                            'type'       => 'int',
1485
-                            'required'   => false,
1486
-                            'validation' => false,
1487
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1488
-                            'css_class'  => '',
1489
-                            'format'     => '%d',
1490
-                            'db-col'     => 'MTP_ID',
1491
-                        );
1492
-
1493
-                        $template_form_fields[ $templatefield_templatename_id ] = array(
1494
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1495
-                            'label'      => null,
1496
-                            'input'      => 'hidden',
1497
-                            'type'       => 'string',
1498
-                            'required'   => false,
1499
-                            'validation' => true,
1500
-                            'value'      => $reference_field,
1501
-                            'css_class'  => '',
1502
-                            'format'     => '%s',
1503
-                            'db-col'     => 'MTP_template_field',
1504
-                        );
1505
-                    }
1506
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1507
-                } else {
1508
-                    $field_id = $template_field . '-content';
1509
-                    $template_form_fields[ $field_id ] = $field_setup_array;
1510
-                    $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1511
-                    $message_template = isset($message_templates[ $context ][ $template_field ])
1512
-                        ? $message_templates[ $context ][ $template_field ]
1513
-                        : null;
1514
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1515
-                                                                  && is_array($message_templates[ $context ])
1516
-                                                                  && $message_template instanceof EE_Message_Template
1517
-                        ? $message_template->get('MTP_content')
1518
-                        : '';
1519
-
1520
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1521
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1522
-                        ? $validators[ $template_field ]['value']
1523
-                        : $template_form_fields[ $field_id ]['value'];
1524
-
1525
-
1526
-                    $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1527
-                    $css_class = isset($field_setup_array['css_class'])
1528
-                        ? $field_setup_array['css_class']
1529
-                        : '';
1530
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1531
-                                                                      && in_array($template_field, $v_fields, true)
1532
-                                                                      && isset($validators[ $template_field ]['msg'])
1533
-                        ? 'validate-error ' . $css_class
1534
-                        : $css_class;
1535
-
1536
-                    // shortcode selector
1537
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1538
-                        $template_field,
1539
-                        $field_id
1540
-                    );
1541
-                }
1542
-
1543
-                // k took care of content field(s) now let's take care of others.
1544
-
1545
-                $templatefield_MTP_id = $template_field . '-MTP_ID';
1546
-                $templatefield_field_templatename_id = $template_field . '-name';
1547
-
1548
-                // foreach template field there are actually two form fields created
1549
-                $template_form_fields[ $templatefield_MTP_id ] = array(
1550
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1551
-                    'label'      => null,
1552
-                    'input'      => 'hidden',
1553
-                    'type'       => 'int',
1554
-                    'required'   => false,
1555
-                    'validation' => true,
1556
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1557
-                    'css_class'  => '',
1558
-                    'format'     => '%d',
1559
-                    'db-col'     => 'MTP_ID',
1560
-                );
1561
-
1562
-                $template_form_fields[ $templatefield_field_templatename_id ] = array(
1563
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1564
-                    'label'      => null,
1565
-                    'input'      => 'hidden',
1566
-                    'type'       => 'string',
1567
-                    'required'   => false,
1568
-                    'validation' => true,
1569
-                    'value'      => $template_field,
1570
-                    'css_class'  => '',
1571
-                    'format'     => '%s',
1572
-                    'db-col'     => 'MTP_template_field',
1573
-                );
1574
-            }
1575
-
1576
-            // add other fields
1577
-            $template_form_fields['ee-msg-current-context'] = array(
1578
-                'name'       => 'MTP_context',
1579
-                'label'      => null,
1580
-                'input'      => 'hidden',
1581
-                'type'       => 'string',
1582
-                'required'   => false,
1583
-                'validation' => true,
1584
-                'value'      => $context,
1585
-                'css_class'  => '',
1586
-                'format'     => '%s',
1587
-                'db-col'     => 'MTP_context',
1588
-            );
1589
-
1590
-            $template_form_fields['ee-msg-grp-id'] = array(
1591
-                'name'       => 'GRP_ID',
1592
-                'label'      => null,
1593
-                'input'      => 'hidden',
1594
-                'type'       => 'int',
1595
-                'required'   => false,
1596
-                'validation' => true,
1597
-                'value'      => $GRP_ID,
1598
-                'css_class'  => '',
1599
-                'format'     => '%d',
1600
-                'db-col'     => 'GRP_ID',
1601
-            );
1602
-
1603
-            $template_form_fields['ee-msg-messenger'] = array(
1604
-                'name'       => 'MTP_messenger',
1605
-                'label'      => null,
1606
-                'input'      => 'hidden',
1607
-                'type'       => 'string',
1608
-                'required'   => false,
1609
-                'validation' => true,
1610
-                'value'      => $message_template_group->messenger(),
1611
-                'css_class'  => '',
1612
-                'format'     => '%s',
1613
-                'db-col'     => 'MTP_messenger',
1614
-            );
1615
-
1616
-            $template_form_fields['ee-msg-message-type'] = array(
1617
-                'name'       => 'MTP_message_type',
1618
-                'label'      => null,
1619
-                'input'      => 'hidden',
1620
-                'type'       => 'string',
1621
-                'required'   => false,
1622
-                'validation' => true,
1623
-                'value'      => $message_template_group->message_type(),
1624
-                'css_class'  => '',
1625
-                'format'     => '%s',
1626
-                'db-col'     => 'MTP_message_type',
1627
-            );
1628
-
1629
-            $sidebar_form_fields['ee-msg-is-global'] = array(
1630
-                'name'       => 'MTP_is_global',
1631
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1632
-                'input'      => 'hidden',
1633
-                'type'       => 'int',
1634
-                'required'   => false,
1635
-                'validation' => true,
1636
-                'value'      => $message_template_group->get('MTP_is_global'),
1637
-                'css_class'  => '',
1638
-                'format'     => '%d',
1639
-                'db-col'     => 'MTP_is_global',
1640
-            );
1641
-
1642
-            $sidebar_form_fields['ee-msg-is-override'] = array(
1643
-                'name'       => 'MTP_is_override',
1644
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1645
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1646
-                'type'       => 'int',
1647
-                'required'   => false,
1648
-                'validation' => true,
1649
-                'value'      => $message_template_group->get('MTP_is_override'),
1650
-                'css_class'  => '',
1651
-                'format'     => '%d',
1652
-                'db-col'     => 'MTP_is_override',
1653
-            );
1654
-
1655
-            $sidebar_form_fields['ee-msg-is-active'] = array(
1656
-                'name'       => 'MTP_is_active',
1657
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1658
-                'input'      => 'hidden',
1659
-                'type'       => 'int',
1660
-                'required'   => false,
1661
-                'validation' => true,
1662
-                'value'      => $message_template_group->is_active(),
1663
-                'css_class'  => '',
1664
-                'format'     => '%d',
1665
-                'db-col'     => 'MTP_is_active',
1666
-            );
1667
-
1668
-            $sidebar_form_fields['ee-msg-deleted'] = array(
1669
-                'name'       => 'MTP_deleted',
1670
-                'label'      => null,
1671
-                'input'      => 'hidden',
1672
-                'type'       => 'int',
1673
-                'required'   => false,
1674
-                'validation' => true,
1675
-                'value'      => $message_template_group->get('MTP_deleted'),
1676
-                'css_class'  => '',
1677
-                'format'     => '%d',
1678
-                'db-col'     => 'MTP_deleted',
1679
-            );
1680
-            $sidebar_form_fields['ee-msg-author'] = array(
1681
-                'name'       => 'MTP_user_id',
1682
-                'label'      => esc_html__('Author', 'event_espresso'),
1683
-                'input'      => 'hidden',
1684
-                'type'       => 'int',
1685
-                'required'   => false,
1686
-                'validation' => false,
1687
-                'value'      => $message_template_group->user(),
1688
-                'format'     => '%d',
1689
-                'db-col'     => 'MTP_user_id',
1690
-            );
1691
-
1692
-            $sidebar_form_fields['ee-msg-route'] = array(
1693
-                'name'  => 'action',
1694
-                'input' => 'hidden',
1695
-                'type'  => 'string',
1696
-                'value' => $action,
1697
-            );
1698
-
1699
-            $sidebar_form_fields['ee-msg-id'] = array(
1700
-                'name'  => 'id',
1701
-                'input' => 'hidden',
1702
-                'type'  => 'int',
1703
-                'value' => $GRP_ID,
1704
-            );
1705
-            $sidebar_form_fields['ee-msg-evt-nonce'] = array(
1706
-                'name'  => $action . '_nonce',
1707
-                'input' => 'hidden',
1708
-                'type'  => 'string',
1709
-                'value' => wp_create_nonce($action . '_nonce'),
1710
-            );
1711
-
1712
-            if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1713
-                $sidebar_form_fields['ee-msg-template-switch'] = array(
1714
-                    'name'  => 'template_switch',
1715
-                    'input' => 'hidden',
1716
-                    'type'  => 'int',
1717
-                    'value' => 1,
1718
-                );
1719
-            }
1720
-
1721
-
1722
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1723
-            $sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1724
-        } //end if ( !empty($template_field_structure) )
1725
-
1726
-        // set extra content for publish box
1727
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1728
-        $this->_set_publish_post_box_vars(
1729
-            'id',
1730
-            $GRP_ID,
1731
-            false,
1732
-            add_query_arg(
1733
-                array('action' => 'global_mtps'),
1734
-                $this->_admin_base_url
1735
-            )
1736
-        );
1737
-
1738
-        // add preview button
1739
-        $preview_url = parent::add_query_args_and_nonce(
1740
-            array(
1741
-                'message_type' => $message_template_group->message_type(),
1742
-                'messenger'    => $message_template_group->messenger(),
1743
-                'context'      => $context,
1744
-                'GRP_ID'       => $GRP_ID,
1745
-                'evt_id'       => $EVT_ID,
1746
-                'action'       => 'preview_message',
1747
-            ),
1748
-            $this->_admin_base_url
1749
-        );
1750
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1751
-                          . esc_html__('Preview', 'event_espresso')
1752
-                          . '</a>';
1753
-
1754
-
1755
-        // setup context switcher
1756
-        $context_switcher_args = array(
1757
-            'page'    => 'espresso_messages',
1758
-            'action'  => 'edit_message_template',
1759
-            'id'      => $GRP_ID,
1760
-            'evt_id'  => $EVT_ID,
1761
-            'context' => $context,
1762
-            'extra'   => $preview_button,
1763
-        );
1764
-        $this->_set_context_switcher($message_template_group, $context_switcher_args);
1765
-
1766
-
1767
-        // main box
1768
-        $this->_template_args['template_fields'] = $template_fields;
1769
-        $this->_template_args['sidebar_box_id'] = 'details';
1770
-        $this->_template_args['action'] = $action;
1771
-        $this->_template_args['context'] = $context;
1772
-        $this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1773
-        $this->_template_args['learn_more_about_message_templates_link'] =
1774
-            $this->_learn_more_about_message_templates_link();
1775
-
1776
-
1777
-        $this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1778
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1779
-            $message_template_group,
1780
-            $context,
1781
-            $context_label
1782
-        );
1783
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1784
-        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1785
-
1786
-        $this->_template_path = $this->_template_args['GRP_ID']
1787
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1788
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1789
-
1790
-        // send along EE_Message_Template_Group object for further template use.
1791
-        $this->_template_args['MTP'] = $message_template_group;
1792
-
1793
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1794
-            $this->_template_path,
1795
-            $this->_template_args,
1796
-            true
1797
-        );
1798
-
1799
-
1800
-        // finally, let's set the admin_page title
1801
-        $this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1802
-
1803
-
1804
-        // we need to take care of setting the shortcodes property for use elsewhere.
1805
-        $this->_set_shortcodes();
1806
-
1807
-
1808
-        // final template wrapper
1809
-        $this->display_admin_page_with_sidebar();
1810
-    }
1811
-
1812
-
1813
-    public function filter_tinymce_init($mceInit, $editor_id)
1814
-    {
1815
-        return $mceInit;
1816
-    }
1817
-
1818
-
1819
-    public function add_context_switcher()
1820
-    {
1821
-        return $this->_context_switcher;
1822
-    }
1823
-
1824
-
1825
-    /**
1826
-     * Adds the activation/deactivation toggle for the message template context.
1827
-     *
1828
-     * @param EE_Message_Template_Group $message_template_group
1829
-     * @param string                    $context
1830
-     * @param string                    $context_label
1831
-     * @return string
1832
-     * @throws DomainException
1833
-     * @throws EE_Error
1834
-     * @throws InvalidIdentifierException
1835
-     */
1836
-    protected function add_active_context_element(
1837
-        EE_Message_Template_Group $message_template_group,
1838
-        $context,
1839
-        $context_label
1840
-    ) {
1841
-        $template_args = array(
1842
-            'context'                   => $context,
1843
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1844
-            'is_active'                 => $message_template_group->is_context_active($context),
1845
-            'on_off_action'             => $message_template_group->is_context_active($context)
1846
-                ? 'context-off'
1847
-                : 'context-on',
1848
-            'context_label'             => str_replace(array('(', ')'), '', $context_label),
1849
-            'message_template_group_id' => $message_template_group->ID(),
1850
-        );
1851
-        return EEH_Template::display_template(
1852
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1853
-            $template_args,
1854
-            true
1855
-        );
1856
-    }
1857
-
1858
-
1859
-    /**
1860
-     * Ajax callback for `toggle_context_template` ajax action.
1861
-     * Handles toggling the message context on or off.
1862
-     *
1863
-     * @throws EE_Error
1864
-     * @throws InvalidArgumentException
1865
-     * @throws InvalidDataTypeException
1866
-     * @throws InvalidIdentifierException
1867
-     * @throws InvalidInterfaceException
1868
-     */
1869
-    public function toggle_context_template()
1870
-    {
1871
-        $success = true;
1872
-        // check for required data
1873
-        if (! isset(
1874
-            $this->_req_data['message_template_group_id'],
1875
-            $this->_req_data['context'],
1876
-            $this->_req_data['status']
1877
-        )) {
1878
-            EE_Error::add_error(
1879
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1880
-                __FILE__,
1881
-                __FUNCTION__,
1882
-                __LINE__
1883
-            );
1884
-            $success = false;
1885
-        }
1886
-
1887
-        $nonce = isset($this->_req_data['toggle_context_nonce'])
1888
-            ? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1889
-            : '';
1890
-        $nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1891
-        $this->_verify_nonce($nonce, $nonce_ref);
1892
-        $status = $this->_req_data['status'];
1893
-        if ($status !== 'off' && $status !== 'on') {
1894
-            EE_Error::add_error(
1895
-                sprintf(
1896
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1897
-                    $this->_req_data['status']
1898
-                ),
1899
-                __FILE__,
1900
-                __FUNCTION__,
1901
-                __LINE__
1902
-            );
1903
-            $success = false;
1904
-        }
1905
-        $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1906
-            $this->_req_data['message_template_group_id']
1907
-        );
1908
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1909
-            EE_Error::add_error(
1910
-                sprintf(
1911
-                    esc_html__(
1912
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1913
-                        'event_espresso'
1914
-                    ),
1915
-                    $this->_req_data['message_template_group_id'],
1916
-                    'EE_Message_Template_Group'
1917
-                ),
1918
-                __FILE__,
1919
-                __FUNCTION__,
1920
-                __LINE__
1921
-            );
1922
-            $success = false;
1923
-        }
1924
-        if ($success) {
1925
-            $success = $status === 'off'
1926
-                ? $message_template_group->deactivate_context($this->_req_data['context'])
1927
-                : $message_template_group->activate_context($this->_req_data['context']);
1928
-        }
1929
-        $this->_template_args['success'] = $success;
1930
-        $this->_return_json();
1931
-    }
1932
-
1933
-
1934
-    public function _add_form_element_before()
1935
-    {
1936
-        return '<form method="post" action="'
1937
-               . $this->_template_args["edit_message_template_form_url"]
1938
-               . '" id="ee-msg-edit-frm">';
1939
-    }
1940
-
1941
-    public function _add_form_element_after()
1942
-    {
1943
-        return '</form>';
1944
-    }
1945
-
1946
-
1947
-    /**
1948
-     * This executes switching the template pack for a message template.
1949
-     *
1950
-     * @since 4.5.0
1951
-     * @throws EE_Error
1952
-     * @throws InvalidDataTypeException
1953
-     * @throws InvalidInterfaceException
1954
-     * @throws InvalidArgumentException
1955
-     * @throws ReflectionException
1956
-     */
1957
-    public function switch_template_pack()
1958
-    {
1959
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1960
-        $template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1961
-
1962
-        // verify we have needed values.
1963
-        if (empty($GRP_ID) || empty($template_pack)) {
1964
-            $this->_template_args['error'] = true;
1965
-            EE_Error::add_error(
1966
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1967
-                __FILE__,
1968
-                __FUNCTION__,
1969
-                __LINE__
1970
-            );
1971
-        } else {
1972
-            // get template, set the new template_pack and then reset to default
1973
-            /** @type EE_Message_Template_Group $message_template_group */
1974
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1975
-
1976
-            $message_template_group->set_template_pack_name($template_pack);
1977
-            $this->_req_data['msgr'] = $message_template_group->messenger();
1978
-            $this->_req_data['mt'] = $message_template_group->message_type();
1979
-
1980
-            $query_args = $this->_reset_to_default_template();
1981
-
1982
-            if (empty($query_args['id'])) {
1983
-                EE_Error::add_error(
1984
-                    esc_html__(
1985
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
1986
-                        'event_espresso'
1987
-                    ),
1988
-                    __FILE__,
1989
-                    __FUNCTION__,
1990
-                    __LINE__
1991
-                );
1992
-                $this->_template_args['error'] = true;
1993
-            } else {
1994
-                $template_label = $message_template_group->get_template_pack()->label;
1995
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1996
-                EE_Error::add_success(
1997
-                    sprintf(
1998
-                        esc_html__(
1999
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2000
-                            'event_espresso'
2001
-                        ),
2002
-                        $template_label,
2003
-                        $template_pack_labels->template_pack
2004
-                    )
2005
-                );
2006
-                // generate the redirect url for js.
2007
-                $url = self::add_query_args_and_nonce(
2008
-                    $query_args,
2009
-                    $this->_admin_base_url
2010
-                );
2011
-                $this->_template_args['data']['redirect_url'] = $url;
2012
-                $this->_template_args['success'] = true;
2013
-            }
2014
-
2015
-            $this->_return_json();
2016
-        }
2017
-    }
2018
-
2019
-
2020
-    /**
2021
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2022
-     * they want.
2023
-     *
2024
-     * @access protected
2025
-     * @return array|null
2026
-     * @throws EE_Error
2027
-     * @throws InvalidArgumentException
2028
-     * @throws InvalidDataTypeException
2029
-     * @throws InvalidInterfaceException
2030
-     */
2031
-    protected function _reset_to_default_template()
2032
-    {
2033
-
2034
-        $templates = array();
2035
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2036
-        // we need to make sure we've got the info we need.
2037
-        if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2038
-            EE_Error::add_error(
2039
-                esc_html__(
2040
-                    '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.',
2041
-                    'event_espresso'
2042
-                ),
2043
-                __FILE__,
2044
-                __FUNCTION__,
2045
-                __LINE__
2046
-            );
2047
-        }
2048
-
2049
-        // all templates will be reset to whatever the defaults are
2050
-        // for the global template matching the messenger and message type.
2051
-        $success = ! empty($GRP_ID) ? true : false;
2052
-
2053
-        if ($success) {
2054
-            // let's first determine if the incoming template is a global template,
2055
-            // if it isn't then we need to get the global template matching messenger and message type.
2056
-            // $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2057
-
2058
-
2059
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2060
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
2061
-
2062
-            if ($success) {
2063
-                // if successfully deleted, lets generate the new ones.
2064
-                // Note. We set GLOBAL to true, because resets on ANY template
2065
-                // will use the related global template defaults for regeneration.
2066
-                // This means that if a custom template is reset it resets to whatever the related global template is.
2067
-                // HOWEVER, we DO keep the template pack and template variation set
2068
-                // for the current custom template when resetting.
2069
-                $templates = $this->_generate_new_templates(
2070
-                    $this->_req_data['msgr'],
2071
-                    $this->_req_data['mt'],
2072
-                    $GRP_ID,
2073
-                    true
2074
-                );
2075
-            }
2076
-        }
2077
-
2078
-        // any error messages?
2079
-        if (! $success) {
2080
-            EE_Error::add_error(
2081
-                esc_html__(
2082
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
2083
-                    'event_espresso'
2084
-                ),
2085
-                __FILE__,
2086
-                __FUNCTION__,
2087
-                __LINE__
2088
-            );
2089
-        }
2090
-
2091
-        // all good, let's add a success message!
2092
-        if ($success && ! empty($templates)) {
2093
-            // the info for the template we generated is the first element in the returned array
2094
-            // $templates = $templates[0];
2095
-            EE_Error::overwrite_success();
2096
-            EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2097
-        }
2098
-
2099
-
2100
-        $query_args = array(
2101
-            'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2102
-            'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2103
-            'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2104
-        );
2105
-
2106
-        // if called via ajax then we return query args otherwise redirect
2107
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2108
-            return $query_args;
2109
-        } else {
2110
-            $this->_redirect_after_action(false, '', '', $query_args, true);
2111
-
2112
-            return null;
2113
-        }
2114
-    }
2115
-
2116
-
2117
-    /**
2118
-     * Retrieve and set the message preview for display.
2119
-     *
2120
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2121
-     * @return string
2122
-     * @throws ReflectionException
2123
-     * @throws EE_Error
2124
-     * @throws InvalidArgumentException
2125
-     * @throws InvalidDataTypeException
2126
-     * @throws InvalidInterfaceException
2127
-     */
2128
-    public function _preview_message($send = false)
2129
-    {
2130
-        // first make sure we've got the necessary parameters
2131
-        if (! isset(
2132
-            $this->_req_data['message_type'],
2133
-            $this->_req_data['messenger'],
2134
-            $this->_req_data['messenger'],
2135
-            $this->_req_data['GRP_ID']
2136
-        )) {
2137
-            EE_Error::add_error(
2138
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2139
-                __FILE__,
2140
-                __FUNCTION__,
2141
-                __LINE__
2142
-            );
2143
-        }
2144
-
2145
-        EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
22
+	/**
23
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
24
+	 */
25
+	protected $_message_resource_manager;
26
+
27
+	/**
28
+	 * @type string $_active_message_type_name
29
+	 */
30
+	protected $_active_message_type_name = '';
31
+
32
+	/**
33
+	 * @type EE_messenger $_active_messenger
34
+	 */
35
+	protected $_active_messenger;
36
+	protected $_activate_state;
37
+	protected $_activate_meta_box_type;
38
+	protected $_current_message_meta_box;
39
+	protected $_current_message_meta_box_object;
40
+	protected $_context_switcher;
41
+	protected $_shortcodes = array();
42
+	protected $_active_messengers = array();
43
+	protected $_active_message_types = array();
44
+
45
+	/**
46
+	 * @var EE_Message_Template_Group $_message_template_group
47
+	 */
48
+	protected $_message_template_group;
49
+	protected $_m_mt_settings = array();
50
+
51
+
52
+	/**
53
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
+	 * IF there is no group then it gets automatically set to the Default template pack.
55
+	 *
56
+	 * @since 4.5.0
57
+	 *
58
+	 * @var EE_Messages_Template_Pack
59
+	 */
60
+	protected $_template_pack;
61
+
62
+
63
+	/**
64
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
+	 * group is.  If there is no group then it automatically gets set to default.
66
+	 *
67
+	 * @since 4.5.0
68
+	 *
69
+	 * @var string
70
+	 */
71
+	protected $_variation;
72
+
73
+
74
+	/**
75
+	 * @param bool $routing
76
+	 * @throws EE_Error
77
+	 */
78
+	public function __construct($routing = true)
79
+	{
80
+		// make sure messages autoloader is running
81
+		EED_Messages::set_autoloaders();
82
+		parent::__construct($routing);
83
+	}
84
+
85
+
86
+	protected function _init_page_props()
87
+	{
88
+		$this->page_slug = EE_MSG_PG_SLUG;
89
+		$this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
+		$this->_admin_base_url = EE_MSG_ADMIN_URL;
91
+		$this->_admin_base_path = EE_MSG_ADMIN;
92
+
93
+		$this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
+			: array();
95
+
96
+		$this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
+		$this->_load_message_resource_manager();
98
+	}
99
+
100
+
101
+	/**
102
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
+	 *
104
+	 * @throws EE_Error
105
+	 * @throws InvalidDataTypeException
106
+	 * @throws InvalidInterfaceException
107
+	 * @throws InvalidArgumentException
108
+	 * @throws ReflectionException
109
+	 */
110
+	protected function _load_message_resource_manager()
111
+	{
112
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
+	}
114
+
115
+
116
+	/**
117
+	 * @deprecated 4.9.9.rc.014
118
+	 * @return array
119
+	 * @throws EE_Error
120
+	 * @throws InvalidArgumentException
121
+	 * @throws InvalidDataTypeException
122
+	 * @throws InvalidInterfaceException
123
+	 */
124
+	public function get_messengers_for_list_table()
125
+	{
126
+		EE_Error::doing_it_wrong(
127
+			__METHOD__,
128
+			sprintf(
129
+				esc_html__(
130
+					'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',
131
+					'event_espresso'
132
+				),
133
+				'Messages_Admin_Page::get_messengers_select_input()'
134
+			),
135
+			'4.9.9.rc.014'
136
+		);
137
+
138
+		$m_values = array();
139
+		$active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
+		// setup messengers for selects
141
+		$i = 1;
142
+		foreach ($active_messengers as $active_messenger) {
143
+			if ($active_messenger instanceof EE_Message) {
144
+				$m_values[ $i ]['id'] = $active_messenger->messenger();
145
+				$m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
+				$i++;
147
+			}
148
+		}
149
+
150
+		return $m_values;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @deprecated 4.9.9.rc.014
156
+	 * @return array
157
+	 * @throws EE_Error
158
+	 * @throws InvalidArgumentException
159
+	 * @throws InvalidDataTypeException
160
+	 * @throws InvalidInterfaceException
161
+	 */
162
+	public function get_message_types_for_list_table()
163
+	{
164
+		EE_Error::doing_it_wrong(
165
+			__METHOD__,
166
+			sprintf(
167
+				esc_html__(
168
+					'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',
169
+					'event_espresso'
170
+				),
171
+				'Messages_Admin_Page::get_message_types_select_input()'
172
+			),
173
+			'4.9.9.rc.014'
174
+		);
175
+
176
+		$mt_values = array();
177
+		$active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
+		$i = 1;
179
+		foreach ($active_messages as $active_message) {
180
+			if ($active_message instanceof EE_Message) {
181
+				$mt_values[ $i ]['id'] = $active_message->message_type();
182
+				$mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
+				$i++;
184
+			}
185
+		}
186
+
187
+		return $mt_values;
188
+	}
189
+
190
+
191
+	/**
192
+	 * @deprecated 4.9.9.rc.014
193
+	 * @return array
194
+	 * @throws EE_Error
195
+	 * @throws InvalidArgumentException
196
+	 * @throws InvalidDataTypeException
197
+	 * @throws InvalidInterfaceException
198
+	 */
199
+	public function get_contexts_for_message_types_for_list_table()
200
+	{
201
+		EE_Error::doing_it_wrong(
202
+			__METHOD__,
203
+			sprintf(
204
+				esc_html__(
205
+					'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',
206
+					'event_espresso'
207
+				),
208
+				'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
+			),
210
+			'4.9.9.rc.014'
211
+		);
212
+
213
+		$contexts = array();
214
+		$active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
+		foreach ($active_message_contexts as $active_message) {
216
+			if ($active_message instanceof EE_Message) {
217
+				$message_type = $active_message->message_type_object();
218
+				if ($message_type instanceof EE_message_type) {
219
+					$message_type_contexts = $message_type->get_contexts();
220
+					foreach ($message_type_contexts as $context => $context_details) {
221
+						$contexts[ $context ] = $context_details['label'];
222
+					}
223
+				}
224
+			}
225
+		}
226
+
227
+		return $contexts;
228
+	}
229
+
230
+
231
+	/**
232
+	 * Generate select input with provided messenger options array.
233
+	 *
234
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
+	 *                                 labels.
236
+	 * @return string
237
+	 * @throws EE_Error
238
+	 */
239
+	public function get_messengers_select_input($messenger_options)
240
+	{
241
+		// if empty or just one value then just return an empty string
242
+		if (empty($messenger_options)
243
+			|| ! is_array($messenger_options)
244
+			|| count($messenger_options) === 1
245
+		) {
246
+			return '';
247
+		}
248
+		// merge in default
249
+		$messenger_options = array_merge(
250
+			array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
251
+			$messenger_options
252
+		);
253
+		$input = new EE_Select_Input(
254
+			$messenger_options,
255
+			array(
256
+				'html_name'  => 'ee_messenger_filter_by',
257
+				'html_id'    => 'ee_messenger_filter_by',
258
+				'html_class' => 'wide',
259
+				'default'    => isset($this->_req_data['ee_messenger_filter_by'])
260
+					? sanitize_title($this->_req_data['ee_messenger_filter_by'])
261
+					: 'none_selected',
262
+			)
263
+		);
264
+
265
+		return $input->get_html_for_input();
266
+	}
267
+
268
+
269
+	/**
270
+	 * Generate select input with provided message type options array.
271
+	 *
272
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
273
+	 *                                    message type labels
274
+	 * @return string
275
+	 * @throws EE_Error
276
+	 */
277
+	public function get_message_types_select_input($message_type_options)
278
+	{
279
+		// if empty or count of options is 1 then just return an empty string
280
+		if (empty($message_type_options)
281
+			|| ! is_array($message_type_options)
282
+			|| count($message_type_options) === 1
283
+		) {
284
+			return '';
285
+		}
286
+		// merge in default
287
+		$message_type_options = array_merge(
288
+			array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
289
+			$message_type_options
290
+		);
291
+		$input = new EE_Select_Input(
292
+			$message_type_options,
293
+			array(
294
+				'html_name'  => 'ee_message_type_filter_by',
295
+				'html_id'    => 'ee_message_type_filter_by',
296
+				'html_class' => 'wide',
297
+				'default'    => isset($this->_req_data['ee_message_type_filter_by'])
298
+					? sanitize_title($this->_req_data['ee_message_type_filter_by'])
299
+					: 'none_selected',
300
+			)
301
+		);
302
+
303
+		return $input->get_html_for_input();
304
+	}
305
+
306
+
307
+	/**
308
+	 * Generate select input with provide message type contexts array.
309
+	 *
310
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
311
+	 *                               context label.
312
+	 * @return string
313
+	 * @throws EE_Error
314
+	 */
315
+	public function get_contexts_for_message_types_select_input($context_options)
316
+	{
317
+		// if empty or count of options is one then just return empty string
318
+		if (empty($context_options)
319
+			|| ! is_array($context_options)
320
+			|| count($context_options) === 1
321
+		) {
322
+			return '';
323
+		}
324
+		// merge in default
325
+		$context_options = array_merge(
326
+			array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
327
+			$context_options
328
+		);
329
+		$input = new EE_Select_Input(
330
+			$context_options,
331
+			array(
332
+				'html_name'  => 'ee_context_filter_by',
333
+				'html_id'    => 'ee_context_filter_by',
334
+				'html_class' => 'wide',
335
+				'default'    => isset($this->_req_data['ee_context_filter_by'])
336
+					? sanitize_title($this->_req_data['ee_context_filter_by'])
337
+					: 'none_selected',
338
+			)
339
+		);
340
+
341
+		return $input->get_html_for_input();
342
+	}
343
+
344
+
345
+	protected function _ajax_hooks()
346
+	{
347
+		add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
348
+		add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
349
+		add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
350
+		add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
351
+		add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
352
+		add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
353
+	}
354
+
355
+
356
+	protected function _define_page_props()
357
+	{
358
+		$this->_admin_page_title = $this->page_label;
359
+		$this->_labels = array(
360
+			'buttons'    => array(
361
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
362
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
363
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
364
+			),
365
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
366
+		);
367
+	}
368
+
369
+
370
+	/**
371
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
372
+	 *
373
+	 * @access protected
374
+	 * @return void
375
+	 */
376
+	protected function _set_page_routes()
377
+	{
378
+		$grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
379
+			? $this->_req_data['GRP_ID']
380
+			: 0;
381
+		$grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
382
+			? $this->_req_data['id']
383
+			: $grp_id;
384
+		$msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
385
+			? $this->_req_data['MSG_ID']
386
+			: 0;
387
+
388
+		$this->_page_routes = array(
389
+			'default'                          => array(
390
+				'func'       => '_message_queue_list_table',
391
+				'capability' => 'ee_read_global_messages',
392
+			),
393
+			'global_mtps'                      => array(
394
+				'func'       => '_ee_default_messages_overview_list_table',
395
+				'capability' => 'ee_read_global_messages',
396
+			),
397
+			'custom_mtps'                      => array(
398
+				'func'       => '_custom_mtps_preview',
399
+				'capability' => 'ee_read_messages',
400
+			),
401
+			'add_new_message_template'         => array(
402
+				'func'       => '_add_message_template',
403
+				'capability' => 'ee_edit_messages',
404
+				'noheader'   => true,
405
+			),
406
+			'edit_message_template'            => array(
407
+				'func'       => '_edit_message_template',
408
+				'capability' => 'ee_edit_message',
409
+				'obj_id'     => $grp_id,
410
+			),
411
+			'preview_message'                  => array(
412
+				'func'               => '_preview_message',
413
+				'capability'         => 'ee_read_message',
414
+				'obj_id'             => $grp_id,
415
+				'noheader'           => true,
416
+				'headers_sent_route' => 'display_preview_message',
417
+			),
418
+			'display_preview_message'          => array(
419
+				'func'       => '_display_preview_message',
420
+				'capability' => 'ee_read_message',
421
+				'obj_id'     => $grp_id,
422
+			),
423
+			'insert_message_template'          => array(
424
+				'func'       => '_insert_or_update_message_template',
425
+				'capability' => 'ee_edit_messages',
426
+				'args'       => array('new_template' => true),
427
+				'noheader'   => true,
428
+			),
429
+			'update_message_template'          => array(
430
+				'func'       => '_insert_or_update_message_template',
431
+				'capability' => 'ee_edit_message',
432
+				'obj_id'     => $grp_id,
433
+				'args'       => array('new_template' => false),
434
+				'noheader'   => true,
435
+			),
436
+			'trash_message_template'           => array(
437
+				'func'       => '_trash_or_restore_message_template',
438
+				'capability' => 'ee_delete_message',
439
+				'obj_id'     => $grp_id,
440
+				'args'       => array('trash' => true, 'all' => true),
441
+				'noheader'   => true,
442
+			),
443
+			'trash_message_template_context'   => array(
444
+				'func'       => '_trash_or_restore_message_template',
445
+				'capability' => 'ee_delete_message',
446
+				'obj_id'     => $grp_id,
447
+				'args'       => array('trash' => true),
448
+				'noheader'   => true,
449
+			),
450
+			'restore_message_template'         => array(
451
+				'func'       => '_trash_or_restore_message_template',
452
+				'capability' => 'ee_delete_message',
453
+				'obj_id'     => $grp_id,
454
+				'args'       => array('trash' => false, 'all' => true),
455
+				'noheader'   => true,
456
+			),
457
+			'restore_message_template_context' => array(
458
+				'func'       => '_trash_or_restore_message_template',
459
+				'capability' => 'ee_delete_message',
460
+				'obj_id'     => $grp_id,
461
+				'args'       => array('trash' => false),
462
+				'noheader'   => true,
463
+			),
464
+			'delete_message_template'          => array(
465
+				'func'       => '_delete_message_template',
466
+				'capability' => 'ee_delete_message',
467
+				'obj_id'     => $grp_id,
468
+				'noheader'   => true,
469
+			),
470
+			'reset_to_default'                 => array(
471
+				'func'       => '_reset_to_default_template',
472
+				'capability' => 'ee_edit_message',
473
+				'obj_id'     => $grp_id,
474
+				'noheader'   => true,
475
+			),
476
+			'settings'                         => array(
477
+				'func'       => '_settings',
478
+				'capability' => 'manage_options',
479
+			),
480
+			'update_global_settings'           => array(
481
+				'func'       => '_update_global_settings',
482
+				'capability' => 'manage_options',
483
+				'noheader'   => true,
484
+			),
485
+			'generate_now'                     => array(
486
+				'func'       => '_generate_now',
487
+				'capability' => 'ee_send_message',
488
+				'noheader'   => true,
489
+			),
490
+			'generate_and_send_now'            => array(
491
+				'func'       => '_generate_and_send_now',
492
+				'capability' => 'ee_send_message',
493
+				'noheader'   => true,
494
+			),
495
+			'queue_for_resending'              => array(
496
+				'func'       => '_queue_for_resending',
497
+				'capability' => 'ee_send_message',
498
+				'noheader'   => true,
499
+			),
500
+			'send_now'                         => array(
501
+				'func'       => '_send_now',
502
+				'capability' => 'ee_send_message',
503
+				'noheader'   => true,
504
+			),
505
+			'delete_ee_message'                => array(
506
+				'func'       => '_delete_ee_messages',
507
+				'capability' => 'ee_delete_messages',
508
+				'noheader'   => true,
509
+			),
510
+			'delete_ee_messages'               => array(
511
+				'func'       => '_delete_ee_messages',
512
+				'capability' => 'ee_delete_messages',
513
+				'noheader'   => true,
514
+				'obj_id'     => $msg_id,
515
+			),
516
+		);
517
+	}
518
+
519
+
520
+	protected function _set_page_config()
521
+	{
522
+		$this->_page_config = array(
523
+			'default'                  => array(
524
+				'nav'           => array(
525
+					'label' => esc_html__('Message Activity', 'event_espresso'),
526
+					'order' => 10,
527
+				),
528
+				'list_table'    => 'EE_Message_List_Table',
529
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
530
+				'require_nonce' => false,
531
+			),
532
+			'global_mtps'              => array(
533
+				'nav'           => array(
534
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
535
+					'order' => 20,
536
+				),
537
+				'list_table'    => 'Messages_Template_List_Table',
538
+				'help_tabs'     => array(
539
+					'messages_overview_help_tab'                                => array(
540
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
541
+						'filename' => 'messages_overview',
542
+					),
543
+					'messages_overview_messages_table_column_headings_help_tab' => array(
544
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
545
+						'filename' => 'messages_overview_table_column_headings',
546
+					),
547
+					'messages_overview_messages_filters_help_tab'               => array(
548
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
549
+						'filename' => 'messages_overview_filters',
550
+					),
551
+					'messages_overview_messages_views_help_tab'                 => array(
552
+						'title'    => esc_html__('Message Views', 'event_espresso'),
553
+						'filename' => 'messages_overview_views',
554
+					),
555
+					'message_overview_message_types_help_tab'                   => array(
556
+						'title'    => esc_html__('Message Types', 'event_espresso'),
557
+						'filename' => 'messages_overview_types',
558
+					),
559
+					'messages_overview_messengers_help_tab'                     => array(
560
+						'title'    => esc_html__('Messengers', 'event_espresso'),
561
+						'filename' => 'messages_overview_messengers',
562
+					),
563
+				),
564
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
565
+				// 'help_tour'     => array('Messages_Overview_Help_Tour'),
566
+				'require_nonce' => false,
567
+			),
568
+			'custom_mtps'              => array(
569
+				'nav'           => array(
570
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
571
+					'order' => 30,
572
+				),
573
+				'help_tabs'     => array(),
574
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
575
+				// 'help_tour'     => array(),
576
+				'require_nonce' => false,
577
+			),
578
+			'add_new_message_template' => array(
579
+				'nav'           => array(
580
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
581
+					'order'      => 5,
582
+					'persistent' => false,
583
+				),
584
+				'require_nonce' => false,
585
+			),
586
+			'edit_message_template'    => array(
587
+				'labels'        => array(
588
+					'buttons'    => array(
589
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
590
+					),
591
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
592
+				),
593
+				'nav'           => array(
594
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
595
+					'order'      => 5,
596
+					'persistent' => false,
597
+					'url'        => '',
598
+				),
599
+				'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
600
+				'has_metaboxes' => true,
601
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
602
+				// 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
603
+				'help_tabs'     => array(
604
+					'edit_message_template'            => array(
605
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
606
+						'callback' => 'edit_message_template_help_tab',
607
+					),
608
+					'message_templates_help_tab'       => array(
609
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
610
+						'filename' => 'messages_templates',
611
+					),
612
+					'message_template_shortcodes'      => array(
613
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
614
+						'callback' => 'message_template_shortcodes_help_tab',
615
+					),
616
+					'message_preview_help_tab'         => array(
617
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
618
+						'filename' => 'messages_preview',
619
+					),
620
+					'messages_overview_other_help_tab' => array(
621
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
622
+						'filename' => 'messages_overview_other',
623
+					),
624
+				),
625
+				'require_nonce' => false,
626
+			),
627
+			'display_preview_message'  => array(
628
+				'nav'           => array(
629
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
630
+					'order'      => 5,
631
+					'url'        => '',
632
+					'persistent' => false,
633
+				),
634
+				'help_tabs'     => array(
635
+					'preview_message' => array(
636
+						'title'    => esc_html__('About Previews', 'event_espresso'),
637
+						'callback' => 'preview_message_help_tab',
638
+					),
639
+				),
640
+				'require_nonce' => false,
641
+			),
642
+			'settings'                 => array(
643
+				'nav'           => array(
644
+					'label' => esc_html__('Settings', 'event_espresso'),
645
+					'order' => 40,
646
+				),
647
+				'metaboxes'     => array('_messages_settings_metaboxes'),
648
+				'help_tabs'     => array(
649
+					'messages_settings_help_tab'               => array(
650
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
651
+						'filename' => 'messages_settings',
652
+					),
653
+					'messages_settings_message_types_help_tab' => array(
654
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
655
+						'filename' => 'messages_settings_message_types',
656
+					),
657
+					'messages_settings_messengers_help_tab'    => array(
658
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
659
+						'filename' => 'messages_settings_messengers',
660
+					),
661
+				),
662
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
663
+				// 'help_tour'     => array('Messages_Settings_Help_Tour'),
664
+				'require_nonce' => false,
665
+			),
666
+		);
667
+	}
668
+
669
+
670
+	protected function _add_screen_options()
671
+	{
672
+		// todo
673
+	}
674
+
675
+
676
+	protected function _add_screen_options_global_mtps()
677
+	{
678
+		/**
679
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
680
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
681
+		 */
682
+		$page_title = $this->_admin_page_title;
683
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
684
+		$this->_per_page_screen_option();
685
+		$this->_admin_page_title = $page_title;
686
+	}
687
+
688
+
689
+	protected function _add_screen_options_default()
690
+	{
691
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
692
+		$this->_per_page_screen_option();
693
+	}
694
+
695
+
696
+	// none of the below group are currently used for Messages
697
+	protected function _add_feature_pointers()
698
+	{
699
+	}
700
+
701
+	public function admin_init()
702
+	{
703
+	}
704
+
705
+	public function admin_notices()
706
+	{
707
+	}
708
+
709
+	public function admin_footer_scripts()
710
+	{
711
+	}
712
+
713
+
714
+	public function messages_help_tab()
715
+	{
716
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
717
+	}
718
+
719
+
720
+	public function messengers_help_tab()
721
+	{
722
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
723
+	}
724
+
725
+
726
+	public function message_types_help_tab()
727
+	{
728
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
729
+	}
730
+
731
+
732
+	public function messages_overview_help_tab()
733
+	{
734
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
735
+	}
736
+
737
+
738
+	public function message_templates_help_tab()
739
+	{
740
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
741
+	}
742
+
743
+
744
+	public function edit_message_template_help_tab()
745
+	{
746
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
747
+						. esc_attr__('Editor Title', 'event_espresso')
748
+						. '" />';
749
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
750
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
751
+						. '" />';
752
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
753
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
754
+						. '" />';
755
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
756
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
757
+						. '" />';
758
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
759
+						. esc_attr__('Publish Metabox', 'event_espresso')
760
+						. '" />';
761
+		EEH_Template::display_template(
762
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
763
+			$args
764
+		);
765
+	}
766
+
767
+
768
+	public function message_template_shortcodes_help_tab()
769
+	{
770
+		$this->_set_shortcodes();
771
+		$args['shortcodes'] = $this->_shortcodes;
772
+		EEH_Template::display_template(
773
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
774
+			$args
775
+		);
776
+	}
777
+
778
+
779
+	public function preview_message_help_tab()
780
+	{
781
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
782
+	}
783
+
784
+
785
+	public function settings_help_tab()
786
+	{
787
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
788
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
789
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
790
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
791
+		$args['img3'] = '<div class="switch">'
792
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
793
+						. ' type="checkbox" checked="checked">'
794
+						. '<label for="ee-on-off-toggle-on"></label>'
795
+						. '</div>';
796
+		$args['img4'] = '<div class="switch">'
797
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
798
+						. ' type="checkbox">'
799
+						. '<label for="ee-on-off-toggle-on"></label>'
800
+						. '</div>';
801
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
802
+	}
803
+
804
+
805
+	public function load_scripts_styles()
806
+	{
807
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
808
+		wp_enqueue_style('espresso_ee_msg');
809
+
810
+		wp_register_script(
811
+			'ee-messages-settings',
812
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
813
+			array('jquery-ui-droppable', 'ee-serialize-full-array'),
814
+			EVENT_ESPRESSO_VERSION,
815
+			true
816
+		);
817
+		wp_register_script(
818
+			'ee-msg-list-table-js',
819
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
820
+			array('ee-dialog'),
821
+			EVENT_ESPRESSO_VERSION
822
+		);
823
+	}
824
+
825
+
826
+	public function load_scripts_styles_default()
827
+	{
828
+		wp_enqueue_script('ee-msg-list-table-js');
829
+	}
830
+
831
+
832
+	public function wp_editor_css($mce_css)
833
+	{
834
+		// if we're on the edit_message_template route
835
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
836
+			$message_type_name = $this->_active_message_type_name;
837
+
838
+			// we're going to REPLACE the existing mce css
839
+			// we need to get the css file location from the active messenger
840
+			$mce_css = $this->_active_messenger->get_variation(
841
+				$this->_template_pack,
842
+				$message_type_name,
843
+				true,
844
+				'wpeditor',
845
+				$this->_variation
846
+			);
847
+		}
848
+
849
+		return $mce_css;
850
+	}
851
+
852
+
853
+	public function load_scripts_styles_edit_message_template()
854
+	{
855
+
856
+		$this->_set_shortcodes();
857
+
858
+		EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
859
+			esc_html__(
860
+				'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.',
861
+				'event_espresso'
862
+			),
863
+			$this->_message_template_group->messenger_obj()->label['singular'],
864
+			$this->_message_template_group->message_type_obj()->label['singular']
865
+		);
866
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
867
+			'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?',
868
+			'event_espresso'
869
+		);
870
+		EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
871
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
872
+			'event_espresso'
873
+		);
874
+
875
+		wp_register_script(
876
+			'ee_msgs_edit_js',
877
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
878
+			array('jquery'),
879
+			EVENT_ESPRESSO_VERSION
880
+		);
881
+
882
+		wp_enqueue_script('ee_admin_js');
883
+		wp_enqueue_script('ee_msgs_edit_js');
884
+
885
+		// add in special css for tiny_mce
886
+		add_filter('mce_css', array($this, 'wp_editor_css'));
887
+	}
888
+
889
+
890
+	public function load_scripts_styles_display_preview_message()
891
+	{
892
+
893
+		$this->_set_message_template_group();
894
+
895
+		if (isset($this->_req_data['messenger'])) {
896
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
897
+				$this->_req_data['messenger']
898
+			);
899
+		}
900
+
901
+		$message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
902
+
903
+
904
+		wp_enqueue_style(
905
+			'espresso_preview_css',
906
+			$this->_active_messenger->get_variation(
907
+				$this->_template_pack,
908
+				$message_type_name,
909
+				true,
910
+				'preview',
911
+				$this->_variation
912
+			)
913
+		);
914
+	}
915
+
916
+
917
+	public function load_scripts_styles_settings()
918
+	{
919
+		wp_register_style(
920
+			'ee-message-settings',
921
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
922
+			array(),
923
+			EVENT_ESPRESSO_VERSION
924
+		);
925
+		wp_enqueue_style('ee-text-links');
926
+		wp_enqueue_style('ee-message-settings');
927
+		wp_enqueue_script('ee-messages-settings');
928
+	}
929
+
930
+
931
+	/**
932
+	 * set views array for List Table
933
+	 */
934
+	public function _set_list_table_views_global_mtps()
935
+	{
936
+		$this->_views = array(
937
+			'in_use' => array(
938
+				'slug'  => 'in_use',
939
+				'label' => esc_html__('In Use', 'event_espresso'),
940
+				'count' => 0,
941
+			),
942
+		);
943
+	}
944
+
945
+
946
+	/**
947
+	 * Set views array for the Custom Template List Table
948
+	 */
949
+	public function _set_list_table_views_custom_mtps()
950
+	{
951
+		$this->_set_list_table_views_global_mtps();
952
+		$this->_views['in_use']['bulk_action'] = array(
953
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
954
+		);
955
+	}
956
+
957
+
958
+	/**
959
+	 * set views array for message queue list table
960
+	 *
961
+	 * @throws InvalidDataTypeException
962
+	 * @throws InvalidInterfaceException
963
+	 * @throws InvalidArgumentException
964
+	 * @throws EE_Error
965
+	 * @throws ReflectionException
966
+	 */
967
+	public function _set_list_table_views_default()
968
+	{
969
+		EE_Registry::instance()->load_helper('Template');
970
+
971
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
972
+			'ee_send_message',
973
+			'message_list_table_bulk_actions'
974
+		)
975
+			? array(
976
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
977
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
978
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
979
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
980
+			)
981
+			: array();
982
+
983
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
984
+			'ee_delete_messages',
985
+			'message_list_table_bulk_actions'
986
+		)
987
+			? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
988
+			: array();
989
+
990
+
991
+		$this->_views = array(
992
+			'all' => array(
993
+				'slug'        => 'all',
994
+				'label'       => esc_html__('All', 'event_espresso'),
995
+				'count'       => 0,
996
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
997
+			),
998
+		);
999
+
1000
+
1001
+		foreach (EEM_Message::instance()->all_statuses() as $status) {
1002
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1003
+				continue;
1004
+			}
1005
+			$status_bulk_actions = $common_bulk_actions;
1006
+			// unset bulk actions not applying to status
1007
+			if (! empty($status_bulk_actions)) {
1008
+				switch ($status) {
1009
+					case EEM_Message::status_idle:
1010
+					case EEM_Message::status_resend:
1011
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1012
+						break;
1013
+
1014
+					case EEM_Message::status_failed:
1015
+					case EEM_Message::status_debug_only:
1016
+					case EEM_Message::status_messenger_executing:
1017
+						$status_bulk_actions = array();
1018
+						break;
1019
+
1020
+					case EEM_Message::status_incomplete:
1021
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1022
+						break;
1023
+
1024
+					case EEM_Message::status_retry:
1025
+					case EEM_Message::status_sent:
1026
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1027
+						break;
1028
+				}
1029
+			}
1030
+
1031
+			// skip adding messenger executing status to views because it will be included with the Failed view.
1032
+			if ($status === EEM_Message::status_messenger_executing) {
1033
+				continue;
1034
+			}
1035
+
1036
+			$this->_views[ strtolower($status) ] = array(
1037
+				'slug'        => strtolower($status),
1038
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1039
+				'count'       => 0,
1040
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1041
+			);
1042
+		}
1043
+	}
1044
+
1045
+
1046
+	protected function _ee_default_messages_overview_list_table()
1047
+	{
1048
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1049
+		$this->display_admin_list_table_page_with_no_sidebar();
1050
+	}
1051
+
1052
+
1053
+	protected function _message_queue_list_table()
1054
+	{
1055
+		$this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1056
+		$this->_template_args['per_column'] = 6;
1057
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1058
+		$this->_template_args['before_list_table'] = '<h3>'
1059
+													 . EEM_Message::instance()->get_pretty_label_for_results()
1060
+													 . '</h3>';
1061
+		$this->display_admin_list_table_page_with_no_sidebar();
1062
+	}
1063
+
1064
+
1065
+	protected function _message_legend_items()
1066
+	{
1067
+
1068
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1069
+		$action_items = array();
1070
+
1071
+		foreach ($action_css_classes as $action_item => $action_details) {
1072
+			if ($action_item === 'see_notifications_for') {
1073
+				continue;
1074
+			}
1075
+			$action_items[ $action_item ] = array(
1076
+				'class' => $action_details['css_class'],
1077
+				'desc'  => $action_details['label'],
1078
+			);
1079
+		}
1080
+
1081
+		/** @type array $status_items status legend setup */
1082
+		$status_items = array(
1083
+			'sent_status'                => array(
1084
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1085
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1086
+			),
1087
+			'idle_status'                => array(
1088
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1089
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1090
+			),
1091
+			'failed_status'              => array(
1092
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1093
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1094
+			),
1095
+			'messenger_executing_status' => array(
1096
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1097
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1098
+			),
1099
+			'resend_status'              => array(
1100
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1101
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1102
+			),
1103
+			'incomplete_status'          => array(
1104
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1105
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1106
+			),
1107
+			'retry_status'               => array(
1108
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1109
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1110
+			),
1111
+		);
1112
+		if (EEM_Message::debug()) {
1113
+			$status_items['debug_only_status'] = array(
1114
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1115
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1116
+			);
1117
+		}
1118
+
1119
+		return array_merge($action_items, $status_items);
1120
+	}
1121
+
1122
+
1123
+	protected function _custom_mtps_preview()
1124
+	{
1125
+		$this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1126
+		$this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1127
+											   . ' alt="' . esc_attr__(
1128
+												   'Preview Custom Message Templates screenshot',
1129
+												   'event_espresso'
1130
+											   ) . '" />';
1131
+		$this->_template_args['preview_text'] = '<strong>'
1132
+												. esc_html__(
1133
+													'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.',
1134
+													'event_espresso'
1135
+												)
1136
+												. '</strong>';
1137
+
1138
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1139
+	}
1140
+
1141
+
1142
+	/**
1143
+	 * get_message_templates
1144
+	 * This gets all the message templates for listing on the overview list.
1145
+	 *
1146
+	 * @access public
1147
+	 * @param int    $perpage the amount of templates groups to show per page
1148
+	 * @param string $type    the current _view we're getting templates for
1149
+	 * @param bool   $count   return count?
1150
+	 * @param bool   $all     disregard any paging info (get all data);
1151
+	 * @param bool   $global  whether to return just global (true) or custom templates (false)
1152
+	 * @return array
1153
+	 * @throws EE_Error
1154
+	 * @throws InvalidArgumentException
1155
+	 * @throws InvalidDataTypeException
1156
+	 * @throws InvalidInterfaceException
1157
+	 */
1158
+	public function get_message_templates(
1159
+		$perpage = 10,
1160
+		$type = 'in_use',
1161
+		$count = false,
1162
+		$all = false,
1163
+		$global = true
1164
+	) {
1165
+
1166
+		$MTP = EEM_Message_Template_Group::instance();
1167
+
1168
+		$this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1169
+		$orderby = $this->_req_data['orderby'];
1170
+
1171
+		$order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1172
+			? $this->_req_data['order']
1173
+			: 'ASC';
1174
+
1175
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1176
+			? $this->_req_data['paged']
1177
+			: 1;
1178
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1179
+			? $this->_req_data['perpage']
1180
+			: $perpage;
1181
+
1182
+		$offset = ($current_page - 1) * $per_page;
1183
+		$limit = $all ? null : array($offset, $per_page);
1184
+
1185
+
1186
+		// options will match what is in the _views array property
1187
+		switch ($type) {
1188
+			case 'in_use':
1189
+				$templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1190
+				break;
1191
+			default:
1192
+				$templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1193
+		}
1194
+
1195
+		return $templates;
1196
+	}
1197
+
1198
+
1199
+	/**
1200
+	 * filters etc might need a list of installed message_types
1201
+	 *
1202
+	 * @return array an array of message type objects
1203
+	 */
1204
+	public function get_installed_message_types()
1205
+	{
1206
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1207
+		$installed = array();
1208
+
1209
+		foreach ($installed_message_types as $message_type) {
1210
+			$installed[ $message_type->name ] = $message_type;
1211
+		}
1212
+
1213
+		return $installed;
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * _add_message_template
1219
+	 *
1220
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1221
+	 *
1222
+	 * @param string $message_type
1223
+	 * @param string $messenger
1224
+	 * @param string $GRP_ID
1225
+	 *
1226
+	 * @throws EE_error
1227
+	 */
1228
+	protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1229
+	{
1230
+		// set values override any request data
1231
+		$message_type = ! empty($message_type) ? $message_type : '';
1232
+		$message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1233
+			? $this->_req_data['message_type']
1234
+			: $message_type;
1235
+
1236
+		$messenger = ! empty($messenger) ? $messenger : '';
1237
+		$messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1238
+			? $this->_req_data['messenger']
1239
+			: $messenger;
1240
+
1241
+		$GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1242
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1243
+
1244
+		// we need messenger and message type.  They should be coming from the event editor. If not here then return error
1245
+		if (empty($message_type) || empty($messenger)) {
1246
+			throw new EE_Error(
1247
+				esc_html__(
1248
+					'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1249
+					'event_espresso'
1250
+				)
1251
+			);
1252
+		}
1253
+
1254
+		// we need the GRP_ID for the template being used as the base for the new template
1255
+		if (empty($GRP_ID)) {
1256
+			throw new EE_Error(
1257
+				esc_html__(
1258
+					'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1259
+					'event_espresso'
1260
+				)
1261
+			);
1262
+		}
1263
+
1264
+		// let's just make sure the template gets generated!
1265
+
1266
+		// we need to reassign some variables for what the insert is expecting
1267
+		$this->_req_data['MTP_messenger'] = $messenger;
1268
+		$this->_req_data['MTP_message_type'] = $message_type;
1269
+		$this->_req_data['GRP_ID'] = $GRP_ID;
1270
+		$this->_insert_or_update_message_template(true);
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * public wrapper for the _add_message_template method
1276
+	 *
1277
+	 * @param string $message_type     message type slug
1278
+	 * @param string $messenger        messenger slug
1279
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1280
+	 *                                 off of.
1281
+	 * @throws EE_error
1282
+	 */
1283
+	public function add_message_template($message_type, $messenger, $GRP_ID)
1284
+	{
1285
+		$this->_add_message_template($message_type, $messenger, $GRP_ID);
1286
+	}
1287
+
1288
+
1289
+	/**
1290
+	 * _edit_message_template
1291
+	 *
1292
+	 * @access protected
1293
+	 * @return void
1294
+	 * @throws InvalidIdentifierException
1295
+	 * @throws DomainException
1296
+	 * @throws EE_Error
1297
+	 * @throws InvalidArgumentException
1298
+	 * @throws ReflectionException
1299
+	 * @throws InvalidDataTypeException
1300
+	 * @throws InvalidInterfaceException
1301
+	 */
1302
+	protected function _edit_message_template()
1303
+	{
1304
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1305
+		$template_fields = '';
1306
+		$sidebar_fields = '';
1307
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1308
+		// valid html in the templates.
1309
+		add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1310
+
1311
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1312
+			? absint($this->_req_data['id'])
1313
+			: false;
1314
+
1315
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1316
+		? absint($this->_req_data['evt_id'])
1317
+		: false;
1318
+
1319
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1320
+		$message_template_group = $this->_message_template_group;
1321
+		$c_label = $message_template_group->context_label();
1322
+		$c_config = $message_template_group->contexts_config();
1323
+
1324
+		reset($c_config);
1325
+		$context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1326
+			? strtolower($this->_req_data['context'])
1327
+			: key($c_config);
1328
+
1329
+
1330
+		if (empty($GRP_ID)) {
1331
+			$action = 'insert_message_template';
1332
+			$edit_message_template_form_url = add_query_arg(
1333
+				array('action' => $action, 'noheader' => true),
1334
+				EE_MSG_ADMIN_URL
1335
+			);
1336
+		} else {
1337
+			$action = 'update_message_template';
1338
+			$edit_message_template_form_url = add_query_arg(
1339
+				array('action' => $action, 'noheader' => true),
1340
+				EE_MSG_ADMIN_URL
1341
+			);
1342
+		}
1343
+
1344
+		// set active messenger for this view
1345
+		$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1346
+			$message_template_group->messenger()
1347
+		);
1348
+		$this->_active_message_type_name = $message_template_group->message_type();
1349
+
1350
+
1351
+		// Do we have any validation errors?
1352
+		$validators = $this->_get_transient();
1353
+		$v_fields = ! empty($validators) ? array_keys($validators) : array();
1354
+
1355
+
1356
+		// we need to assemble the title from Various details
1357
+		$context_label = sprintf(
1358
+			esc_html__('(%s %s)', 'event_espresso'),
1359
+			$c_config[ $context ]['label'],
1360
+			ucwords($c_label['label'])
1361
+		);
1362
+
1363
+		$title = sprintf(
1364
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1365
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1366
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1367
+			$context_label
1368
+		);
1369
+
1370
+		$this->_template_args['GRP_ID'] = $GRP_ID;
1371
+		$this->_template_args['message_template'] = $message_template_group;
1372
+		$this->_template_args['is_extra_fields'] = false;
1373
+
1374
+
1375
+		// let's get EEH_MSG_Template so we can get template form fields
1376
+		$template_field_structure = EEH_MSG_Template::get_fields(
1377
+			$message_template_group->messenger(),
1378
+			$message_template_group->message_type()
1379
+		);
1380
+
1381
+		if (! $template_field_structure) {
1382
+			$template_field_structure = false;
1383
+			$template_fields = esc_html__(
1384
+				'There was an error in assembling the fields for this display (you should see an error message)',
1385
+				'event_espresso'
1386
+			);
1387
+		}
1388
+
1389
+
1390
+		$message_templates = $message_template_group->context_templates();
1391
+
1392
+
1393
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1394
+		// will get handled in the "extra" array.
1395
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1396
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1397
+				unset($template_field_structure[ $context ][ $reference_field ]);
1398
+			}
1399
+		}
1400
+
1401
+		// let's loop through the template_field_structure and actually assemble the input fields!
1402
+		if (! empty($template_field_structure)) {
1403
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1404
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1405
+				// the extra array and reset them.
1406
+				if ($template_field === 'extra') {
1407
+					$this->_template_args['is_extra_fields'] = true;
1408
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1409
+						$message_template = $message_templates[ $context ][ $reference_field ];
1410
+						$content = $message_template instanceof EE_Message_Template
1411
+							? $message_template->get('MTP_content')
1412
+							: '';
1413
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1414
+							// let's verify if we need this extra field via the shortcodes parameter.
1415
+							$continue = false;
1416
+							if (isset($extra_array['shortcodes_required'])) {
1417
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1418
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1419
+										$continue = true;
1420
+									}
1421
+								}
1422
+								if ($continue) {
1423
+									continue;
1424
+								}
1425
+							}
1426
+
1427
+							$field_id = $reference_field
1428
+										. '-'
1429
+										. $extra_field
1430
+										. '-content';
1431
+							$template_form_fields[ $field_id ] = $extra_array;
1432
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1433
+																		 . $reference_field
1434
+																		 . '][content]['
1435
+																		 . $extra_field . ']';
1436
+							$css_class = isset($extra_array['css_class'])
1437
+								? $extra_array['css_class']
1438
+								: '';
1439
+
1440
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1441
+																			  && in_array($extra_field, $v_fields, true)
1442
+																			  &&
1443
+																			  (
1444
+																				  is_array($validators[ $extra_field ])
1445
+																				  && isset($validators[ $extra_field ]['msg'])
1446
+																			  )
1447
+								? 'validate-error ' . $css_class
1448
+								: $css_class;
1449
+
1450
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1451
+																		  && isset($content[ $extra_field ])
1452
+								? $content[ $extra_field ]
1453
+								: '';
1454
+
1455
+							// do we have a validation error?  if we do then let's use that value instead
1456
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1457
+								? $validators[ $extra_field ]['value']
1458
+								: $template_form_fields[ $field_id ]['value'];
1459
+
1460
+
1461
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1462
+
1463
+							// shortcode selector
1464
+							$field_name_to_use = $extra_field === 'main'
1465
+								? 'content'
1466
+								: $extra_field;
1467
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1468
+								$field_name_to_use,
1469
+								$field_id
1470
+							);
1471
+
1472
+							if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1473
+								// we want to decode the entities
1474
+								$template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1475
+							}/**/
1476
+						}
1477
+						$templatefield_MTP_id = $reference_field . '-MTP_ID';
1478
+						$templatefield_templatename_id = $reference_field . '-name';
1479
+
1480
+						$template_form_fields[ $templatefield_MTP_id ] = array(
1481
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1482
+							'label'      => null,
1483
+							'input'      => 'hidden',
1484
+							'type'       => 'int',
1485
+							'required'   => false,
1486
+							'validation' => false,
1487
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1488
+							'css_class'  => '',
1489
+							'format'     => '%d',
1490
+							'db-col'     => 'MTP_ID',
1491
+						);
1492
+
1493
+						$template_form_fields[ $templatefield_templatename_id ] = array(
1494
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1495
+							'label'      => null,
1496
+							'input'      => 'hidden',
1497
+							'type'       => 'string',
1498
+							'required'   => false,
1499
+							'validation' => true,
1500
+							'value'      => $reference_field,
1501
+							'css_class'  => '',
1502
+							'format'     => '%s',
1503
+							'db-col'     => 'MTP_template_field',
1504
+						);
1505
+					}
1506
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1507
+				} else {
1508
+					$field_id = $template_field . '-content';
1509
+					$template_form_fields[ $field_id ] = $field_setup_array;
1510
+					$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1511
+					$message_template = isset($message_templates[ $context ][ $template_field ])
1512
+						? $message_templates[ $context ][ $template_field ]
1513
+						: null;
1514
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1515
+																  && is_array($message_templates[ $context ])
1516
+																  && $message_template instanceof EE_Message_Template
1517
+						? $message_template->get('MTP_content')
1518
+						: '';
1519
+
1520
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1521
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1522
+						? $validators[ $template_field ]['value']
1523
+						: $template_form_fields[ $field_id ]['value'];
1524
+
1525
+
1526
+					$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1527
+					$css_class = isset($field_setup_array['css_class'])
1528
+						? $field_setup_array['css_class']
1529
+						: '';
1530
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1531
+																	  && in_array($template_field, $v_fields, true)
1532
+																	  && isset($validators[ $template_field ]['msg'])
1533
+						? 'validate-error ' . $css_class
1534
+						: $css_class;
1535
+
1536
+					// shortcode selector
1537
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1538
+						$template_field,
1539
+						$field_id
1540
+					);
1541
+				}
1542
+
1543
+				// k took care of content field(s) now let's take care of others.
1544
+
1545
+				$templatefield_MTP_id = $template_field . '-MTP_ID';
1546
+				$templatefield_field_templatename_id = $template_field . '-name';
1547
+
1548
+				// foreach template field there are actually two form fields created
1549
+				$template_form_fields[ $templatefield_MTP_id ] = array(
1550
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1551
+					'label'      => null,
1552
+					'input'      => 'hidden',
1553
+					'type'       => 'int',
1554
+					'required'   => false,
1555
+					'validation' => true,
1556
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1557
+					'css_class'  => '',
1558
+					'format'     => '%d',
1559
+					'db-col'     => 'MTP_ID',
1560
+				);
1561
+
1562
+				$template_form_fields[ $templatefield_field_templatename_id ] = array(
1563
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1564
+					'label'      => null,
1565
+					'input'      => 'hidden',
1566
+					'type'       => 'string',
1567
+					'required'   => false,
1568
+					'validation' => true,
1569
+					'value'      => $template_field,
1570
+					'css_class'  => '',
1571
+					'format'     => '%s',
1572
+					'db-col'     => 'MTP_template_field',
1573
+				);
1574
+			}
1575
+
1576
+			// add other fields
1577
+			$template_form_fields['ee-msg-current-context'] = array(
1578
+				'name'       => 'MTP_context',
1579
+				'label'      => null,
1580
+				'input'      => 'hidden',
1581
+				'type'       => 'string',
1582
+				'required'   => false,
1583
+				'validation' => true,
1584
+				'value'      => $context,
1585
+				'css_class'  => '',
1586
+				'format'     => '%s',
1587
+				'db-col'     => 'MTP_context',
1588
+			);
1589
+
1590
+			$template_form_fields['ee-msg-grp-id'] = array(
1591
+				'name'       => 'GRP_ID',
1592
+				'label'      => null,
1593
+				'input'      => 'hidden',
1594
+				'type'       => 'int',
1595
+				'required'   => false,
1596
+				'validation' => true,
1597
+				'value'      => $GRP_ID,
1598
+				'css_class'  => '',
1599
+				'format'     => '%d',
1600
+				'db-col'     => 'GRP_ID',
1601
+			);
1602
+
1603
+			$template_form_fields['ee-msg-messenger'] = array(
1604
+				'name'       => 'MTP_messenger',
1605
+				'label'      => null,
1606
+				'input'      => 'hidden',
1607
+				'type'       => 'string',
1608
+				'required'   => false,
1609
+				'validation' => true,
1610
+				'value'      => $message_template_group->messenger(),
1611
+				'css_class'  => '',
1612
+				'format'     => '%s',
1613
+				'db-col'     => 'MTP_messenger',
1614
+			);
1615
+
1616
+			$template_form_fields['ee-msg-message-type'] = array(
1617
+				'name'       => 'MTP_message_type',
1618
+				'label'      => null,
1619
+				'input'      => 'hidden',
1620
+				'type'       => 'string',
1621
+				'required'   => false,
1622
+				'validation' => true,
1623
+				'value'      => $message_template_group->message_type(),
1624
+				'css_class'  => '',
1625
+				'format'     => '%s',
1626
+				'db-col'     => 'MTP_message_type',
1627
+			);
1628
+
1629
+			$sidebar_form_fields['ee-msg-is-global'] = array(
1630
+				'name'       => 'MTP_is_global',
1631
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1632
+				'input'      => 'hidden',
1633
+				'type'       => 'int',
1634
+				'required'   => false,
1635
+				'validation' => true,
1636
+				'value'      => $message_template_group->get('MTP_is_global'),
1637
+				'css_class'  => '',
1638
+				'format'     => '%d',
1639
+				'db-col'     => 'MTP_is_global',
1640
+			);
1641
+
1642
+			$sidebar_form_fields['ee-msg-is-override'] = array(
1643
+				'name'       => 'MTP_is_override',
1644
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1645
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1646
+				'type'       => 'int',
1647
+				'required'   => false,
1648
+				'validation' => true,
1649
+				'value'      => $message_template_group->get('MTP_is_override'),
1650
+				'css_class'  => '',
1651
+				'format'     => '%d',
1652
+				'db-col'     => 'MTP_is_override',
1653
+			);
1654
+
1655
+			$sidebar_form_fields['ee-msg-is-active'] = array(
1656
+				'name'       => 'MTP_is_active',
1657
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1658
+				'input'      => 'hidden',
1659
+				'type'       => 'int',
1660
+				'required'   => false,
1661
+				'validation' => true,
1662
+				'value'      => $message_template_group->is_active(),
1663
+				'css_class'  => '',
1664
+				'format'     => '%d',
1665
+				'db-col'     => 'MTP_is_active',
1666
+			);
1667
+
1668
+			$sidebar_form_fields['ee-msg-deleted'] = array(
1669
+				'name'       => 'MTP_deleted',
1670
+				'label'      => null,
1671
+				'input'      => 'hidden',
1672
+				'type'       => 'int',
1673
+				'required'   => false,
1674
+				'validation' => true,
1675
+				'value'      => $message_template_group->get('MTP_deleted'),
1676
+				'css_class'  => '',
1677
+				'format'     => '%d',
1678
+				'db-col'     => 'MTP_deleted',
1679
+			);
1680
+			$sidebar_form_fields['ee-msg-author'] = array(
1681
+				'name'       => 'MTP_user_id',
1682
+				'label'      => esc_html__('Author', 'event_espresso'),
1683
+				'input'      => 'hidden',
1684
+				'type'       => 'int',
1685
+				'required'   => false,
1686
+				'validation' => false,
1687
+				'value'      => $message_template_group->user(),
1688
+				'format'     => '%d',
1689
+				'db-col'     => 'MTP_user_id',
1690
+			);
1691
+
1692
+			$sidebar_form_fields['ee-msg-route'] = array(
1693
+				'name'  => 'action',
1694
+				'input' => 'hidden',
1695
+				'type'  => 'string',
1696
+				'value' => $action,
1697
+			);
1698
+
1699
+			$sidebar_form_fields['ee-msg-id'] = array(
1700
+				'name'  => 'id',
1701
+				'input' => 'hidden',
1702
+				'type'  => 'int',
1703
+				'value' => $GRP_ID,
1704
+			);
1705
+			$sidebar_form_fields['ee-msg-evt-nonce'] = array(
1706
+				'name'  => $action . '_nonce',
1707
+				'input' => 'hidden',
1708
+				'type'  => 'string',
1709
+				'value' => wp_create_nonce($action . '_nonce'),
1710
+			);
1711
+
1712
+			if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1713
+				$sidebar_form_fields['ee-msg-template-switch'] = array(
1714
+					'name'  => 'template_switch',
1715
+					'input' => 'hidden',
1716
+					'type'  => 'int',
1717
+					'value' => 1,
1718
+				);
1719
+			}
1720
+
1721
+
1722
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1723
+			$sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1724
+		} //end if ( !empty($template_field_structure) )
1725
+
1726
+		// set extra content for publish box
1727
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1728
+		$this->_set_publish_post_box_vars(
1729
+			'id',
1730
+			$GRP_ID,
1731
+			false,
1732
+			add_query_arg(
1733
+				array('action' => 'global_mtps'),
1734
+				$this->_admin_base_url
1735
+			)
1736
+		);
1737
+
1738
+		// add preview button
1739
+		$preview_url = parent::add_query_args_and_nonce(
1740
+			array(
1741
+				'message_type' => $message_template_group->message_type(),
1742
+				'messenger'    => $message_template_group->messenger(),
1743
+				'context'      => $context,
1744
+				'GRP_ID'       => $GRP_ID,
1745
+				'evt_id'       => $EVT_ID,
1746
+				'action'       => 'preview_message',
1747
+			),
1748
+			$this->_admin_base_url
1749
+		);
1750
+		$preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1751
+						  . esc_html__('Preview', 'event_espresso')
1752
+						  . '</a>';
1753
+
1754
+
1755
+		// setup context switcher
1756
+		$context_switcher_args = array(
1757
+			'page'    => 'espresso_messages',
1758
+			'action'  => 'edit_message_template',
1759
+			'id'      => $GRP_ID,
1760
+			'evt_id'  => $EVT_ID,
1761
+			'context' => $context,
1762
+			'extra'   => $preview_button,
1763
+		);
1764
+		$this->_set_context_switcher($message_template_group, $context_switcher_args);
1765
+
1766
+
1767
+		// main box
1768
+		$this->_template_args['template_fields'] = $template_fields;
1769
+		$this->_template_args['sidebar_box_id'] = 'details';
1770
+		$this->_template_args['action'] = $action;
1771
+		$this->_template_args['context'] = $context;
1772
+		$this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1773
+		$this->_template_args['learn_more_about_message_templates_link'] =
1774
+			$this->_learn_more_about_message_templates_link();
1775
+
1776
+
1777
+		$this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1778
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1779
+			$message_template_group,
1780
+			$context,
1781
+			$context_label
1782
+		);
1783
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1784
+		$this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1785
+
1786
+		$this->_template_path = $this->_template_args['GRP_ID']
1787
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1788
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1789
+
1790
+		// send along EE_Message_Template_Group object for further template use.
1791
+		$this->_template_args['MTP'] = $message_template_group;
1792
+
1793
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1794
+			$this->_template_path,
1795
+			$this->_template_args,
1796
+			true
1797
+		);
1798
+
1799
+
1800
+		// finally, let's set the admin_page title
1801
+		$this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1802
+
1803
+
1804
+		// we need to take care of setting the shortcodes property for use elsewhere.
1805
+		$this->_set_shortcodes();
1806
+
1807
+
1808
+		// final template wrapper
1809
+		$this->display_admin_page_with_sidebar();
1810
+	}
1811
+
1812
+
1813
+	public function filter_tinymce_init($mceInit, $editor_id)
1814
+	{
1815
+		return $mceInit;
1816
+	}
1817
+
1818
+
1819
+	public function add_context_switcher()
1820
+	{
1821
+		return $this->_context_switcher;
1822
+	}
1823
+
1824
+
1825
+	/**
1826
+	 * Adds the activation/deactivation toggle for the message template context.
1827
+	 *
1828
+	 * @param EE_Message_Template_Group $message_template_group
1829
+	 * @param string                    $context
1830
+	 * @param string                    $context_label
1831
+	 * @return string
1832
+	 * @throws DomainException
1833
+	 * @throws EE_Error
1834
+	 * @throws InvalidIdentifierException
1835
+	 */
1836
+	protected function add_active_context_element(
1837
+		EE_Message_Template_Group $message_template_group,
1838
+		$context,
1839
+		$context_label
1840
+	) {
1841
+		$template_args = array(
1842
+			'context'                   => $context,
1843
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1844
+			'is_active'                 => $message_template_group->is_context_active($context),
1845
+			'on_off_action'             => $message_template_group->is_context_active($context)
1846
+				? 'context-off'
1847
+				: 'context-on',
1848
+			'context_label'             => str_replace(array('(', ')'), '', $context_label),
1849
+			'message_template_group_id' => $message_template_group->ID(),
1850
+		);
1851
+		return EEH_Template::display_template(
1852
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1853
+			$template_args,
1854
+			true
1855
+		);
1856
+	}
1857
+
1858
+
1859
+	/**
1860
+	 * Ajax callback for `toggle_context_template` ajax action.
1861
+	 * Handles toggling the message context on or off.
1862
+	 *
1863
+	 * @throws EE_Error
1864
+	 * @throws InvalidArgumentException
1865
+	 * @throws InvalidDataTypeException
1866
+	 * @throws InvalidIdentifierException
1867
+	 * @throws InvalidInterfaceException
1868
+	 */
1869
+	public function toggle_context_template()
1870
+	{
1871
+		$success = true;
1872
+		// check for required data
1873
+		if (! isset(
1874
+			$this->_req_data['message_template_group_id'],
1875
+			$this->_req_data['context'],
1876
+			$this->_req_data['status']
1877
+		)) {
1878
+			EE_Error::add_error(
1879
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1880
+				__FILE__,
1881
+				__FUNCTION__,
1882
+				__LINE__
1883
+			);
1884
+			$success = false;
1885
+		}
1886
+
1887
+		$nonce = isset($this->_req_data['toggle_context_nonce'])
1888
+			? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1889
+			: '';
1890
+		$nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1891
+		$this->_verify_nonce($nonce, $nonce_ref);
1892
+		$status = $this->_req_data['status'];
1893
+		if ($status !== 'off' && $status !== 'on') {
1894
+			EE_Error::add_error(
1895
+				sprintf(
1896
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1897
+					$this->_req_data['status']
1898
+				),
1899
+				__FILE__,
1900
+				__FUNCTION__,
1901
+				__LINE__
1902
+			);
1903
+			$success = false;
1904
+		}
1905
+		$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1906
+			$this->_req_data['message_template_group_id']
1907
+		);
1908
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1909
+			EE_Error::add_error(
1910
+				sprintf(
1911
+					esc_html__(
1912
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1913
+						'event_espresso'
1914
+					),
1915
+					$this->_req_data['message_template_group_id'],
1916
+					'EE_Message_Template_Group'
1917
+				),
1918
+				__FILE__,
1919
+				__FUNCTION__,
1920
+				__LINE__
1921
+			);
1922
+			$success = false;
1923
+		}
1924
+		if ($success) {
1925
+			$success = $status === 'off'
1926
+				? $message_template_group->deactivate_context($this->_req_data['context'])
1927
+				: $message_template_group->activate_context($this->_req_data['context']);
1928
+		}
1929
+		$this->_template_args['success'] = $success;
1930
+		$this->_return_json();
1931
+	}
1932
+
1933
+
1934
+	public function _add_form_element_before()
1935
+	{
1936
+		return '<form method="post" action="'
1937
+			   . $this->_template_args["edit_message_template_form_url"]
1938
+			   . '" id="ee-msg-edit-frm">';
1939
+	}
1940
+
1941
+	public function _add_form_element_after()
1942
+	{
1943
+		return '</form>';
1944
+	}
1945
+
1946
+
1947
+	/**
1948
+	 * This executes switching the template pack for a message template.
1949
+	 *
1950
+	 * @since 4.5.0
1951
+	 * @throws EE_Error
1952
+	 * @throws InvalidDataTypeException
1953
+	 * @throws InvalidInterfaceException
1954
+	 * @throws InvalidArgumentException
1955
+	 * @throws ReflectionException
1956
+	 */
1957
+	public function switch_template_pack()
1958
+	{
1959
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1960
+		$template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1961
+
1962
+		// verify we have needed values.
1963
+		if (empty($GRP_ID) || empty($template_pack)) {
1964
+			$this->_template_args['error'] = true;
1965
+			EE_Error::add_error(
1966
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1967
+				__FILE__,
1968
+				__FUNCTION__,
1969
+				__LINE__
1970
+			);
1971
+		} else {
1972
+			// get template, set the new template_pack and then reset to default
1973
+			/** @type EE_Message_Template_Group $message_template_group */
1974
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1975
+
1976
+			$message_template_group->set_template_pack_name($template_pack);
1977
+			$this->_req_data['msgr'] = $message_template_group->messenger();
1978
+			$this->_req_data['mt'] = $message_template_group->message_type();
1979
+
1980
+			$query_args = $this->_reset_to_default_template();
1981
+
1982
+			if (empty($query_args['id'])) {
1983
+				EE_Error::add_error(
1984
+					esc_html__(
1985
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
1986
+						'event_espresso'
1987
+					),
1988
+					__FILE__,
1989
+					__FUNCTION__,
1990
+					__LINE__
1991
+				);
1992
+				$this->_template_args['error'] = true;
1993
+			} else {
1994
+				$template_label = $message_template_group->get_template_pack()->label;
1995
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1996
+				EE_Error::add_success(
1997
+					sprintf(
1998
+						esc_html__(
1999
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2000
+							'event_espresso'
2001
+						),
2002
+						$template_label,
2003
+						$template_pack_labels->template_pack
2004
+					)
2005
+				);
2006
+				// generate the redirect url for js.
2007
+				$url = self::add_query_args_and_nonce(
2008
+					$query_args,
2009
+					$this->_admin_base_url
2010
+				);
2011
+				$this->_template_args['data']['redirect_url'] = $url;
2012
+				$this->_template_args['success'] = true;
2013
+			}
2014
+
2015
+			$this->_return_json();
2016
+		}
2017
+	}
2018
+
2019
+
2020
+	/**
2021
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2022
+	 * they want.
2023
+	 *
2024
+	 * @access protected
2025
+	 * @return array|null
2026
+	 * @throws EE_Error
2027
+	 * @throws InvalidArgumentException
2028
+	 * @throws InvalidDataTypeException
2029
+	 * @throws InvalidInterfaceException
2030
+	 */
2031
+	protected function _reset_to_default_template()
2032
+	{
2033
+
2034
+		$templates = array();
2035
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2036
+		// we need to make sure we've got the info we need.
2037
+		if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2038
+			EE_Error::add_error(
2039
+				esc_html__(
2040
+					'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.',
2041
+					'event_espresso'
2042
+				),
2043
+				__FILE__,
2044
+				__FUNCTION__,
2045
+				__LINE__
2046
+			);
2047
+		}
2048
+
2049
+		// all templates will be reset to whatever the defaults are
2050
+		// for the global template matching the messenger and message type.
2051
+		$success = ! empty($GRP_ID) ? true : false;
2052
+
2053
+		if ($success) {
2054
+			// let's first determine if the incoming template is a global template,
2055
+			// if it isn't then we need to get the global template matching messenger and message type.
2056
+			// $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2057
+
2058
+
2059
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2060
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
2061
+
2062
+			if ($success) {
2063
+				// if successfully deleted, lets generate the new ones.
2064
+				// Note. We set GLOBAL to true, because resets on ANY template
2065
+				// will use the related global template defaults for regeneration.
2066
+				// This means that if a custom template is reset it resets to whatever the related global template is.
2067
+				// HOWEVER, we DO keep the template pack and template variation set
2068
+				// for the current custom template when resetting.
2069
+				$templates = $this->_generate_new_templates(
2070
+					$this->_req_data['msgr'],
2071
+					$this->_req_data['mt'],
2072
+					$GRP_ID,
2073
+					true
2074
+				);
2075
+			}
2076
+		}
2077
+
2078
+		// any error messages?
2079
+		if (! $success) {
2080
+			EE_Error::add_error(
2081
+				esc_html__(
2082
+					'Something went wrong with deleting existing templates. Unable to reset to default',
2083
+					'event_espresso'
2084
+				),
2085
+				__FILE__,
2086
+				__FUNCTION__,
2087
+				__LINE__
2088
+			);
2089
+		}
2090
+
2091
+		// all good, let's add a success message!
2092
+		if ($success && ! empty($templates)) {
2093
+			// the info for the template we generated is the first element in the returned array
2094
+			// $templates = $templates[0];
2095
+			EE_Error::overwrite_success();
2096
+			EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2097
+		}
2098
+
2099
+
2100
+		$query_args = array(
2101
+			'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2102
+			'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2103
+			'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2104
+		);
2105
+
2106
+		// if called via ajax then we return query args otherwise redirect
2107
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2108
+			return $query_args;
2109
+		} else {
2110
+			$this->_redirect_after_action(false, '', '', $query_args, true);
2111
+
2112
+			return null;
2113
+		}
2114
+	}
2115
+
2116
+
2117
+	/**
2118
+	 * Retrieve and set the message preview for display.
2119
+	 *
2120
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2121
+	 * @return string
2122
+	 * @throws ReflectionException
2123
+	 * @throws EE_Error
2124
+	 * @throws InvalidArgumentException
2125
+	 * @throws InvalidDataTypeException
2126
+	 * @throws InvalidInterfaceException
2127
+	 */
2128
+	public function _preview_message($send = false)
2129
+	{
2130
+		// first make sure we've got the necessary parameters
2131
+		if (! isset(
2132
+			$this->_req_data['message_type'],
2133
+			$this->_req_data['messenger'],
2134
+			$this->_req_data['messenger'],
2135
+			$this->_req_data['GRP_ID']
2136
+		)) {
2137
+			EE_Error::add_error(
2138
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2139
+				__FILE__,
2140
+				__FUNCTION__,
2141
+				__LINE__
2142
+			);
2143
+		}
2144
+
2145
+		EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
2146 2146
         
2147
-        // if we have an evt_id set on the request, use it.
2148
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2149
-        ? absint($this->_req_data['evt_id'])
2150
-        : false;
2151
-
2152
-
2153
-        // get the preview!
2154
-        $preview = EED_Messages::preview_message(
2155
-            $this->_req_data['message_type'],
2156
-            $this->_req_data['context'],
2157
-            $this->_req_data['messenger'],
2158
-            $send
2159
-        );
2160
-
2161
-        if ($send) {
2162
-            return $preview;
2163
-        }
2164
-
2165
-        // let's add a button to go back to the edit view
2166
-        $query_args = array(
2167
-            'id'      => $this->_req_data['GRP_ID'],
2168
-            'evt_id'  => $EVT_ID,
2169
-            'context' => $this->_req_data['context'],
2170
-            'action'  => 'edit_message_template',
2171
-        );
2172
-        $go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2173
-        $preview_button = '<a href="'
2174
-                          . $go_back_url
2175
-                          . '" class="button-secondary messages-preview-go-back-button">'
2176
-                          . esc_html__('Go Back to Edit', 'event_espresso')
2177
-                          . '</a>';
2178
-        $message_types = $this->get_installed_message_types();
2179
-        $active_messenger = $this->_message_resource_manager->get_active_messenger(
2180
-            $this->_req_data['messenger']
2181
-        );
2182
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2183
-            ? ucwords($active_messenger->label['singular'])
2184
-            : esc_html__('Unknown Messenger', 'event_espresso');
2185
-        // let's provide a helpful title for context
2186
-        $preview_title = sprintf(
2187
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2188
-            $active_messenger_label,
2189
-            ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2190
-        );
2191
-        if (empty($preview)) {
2192
-            $this->noEventsErrorMessage();
2193
-        }
2194
-        // setup display of preview.
2195
-        $this->_admin_page_title = $preview_title;
2196
-        $this->_template_args['admin_page_title'] = $preview_title;
2197
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2198
-        $this->_template_args['data']['force_json'] = true;
2199
-
2200
-        return '';
2201
-    }
2202
-
2203
-
2204
-    /**
2205
-     * Used to set an error if there are no events available for generating a preview/test send.
2206
-     *
2207
-     * @param bool $test_send  Whether the error should be generated for the context of a test send.
2208
-     */
2209
-    protected function noEventsErrorMessage($test_send = false)
2210
-    {
2211
-        $events_url = parent::add_query_args_and_nonce(
2212
-            array(
2213
-                'action' => 'default',
2214
-                'page'   => 'espresso_events',
2215
-            ),
2216
-            admin_url('admin.php')
2217
-        );
2218
-        $message = $test_send
2219
-            ? __(
2220
-                '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!',
2221
-                'event_espresso'
2222
-            )
2223
-            : __(
2224
-                '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!',
2225
-                'event_espresso'
2226
-            );
2227
-
2228
-        EE_Error::add_attention(
2229
-            sprintf(
2230
-                $message,
2231
-                "<a href='{$events_url}'>",
2232
-                '</a>'
2233
-            )
2234
-        );
2235
-    }
2236
-
2237
-
2238
-    /**
2239
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2240
-     * gets called automatically.
2241
-     *
2242
-     * @since 4.5.0
2243
-     *
2244
-     * @return string
2245
-     */
2246
-    protected function _display_preview_message()
2247
-    {
2248
-        $this->display_admin_page_with_no_sidebar();
2249
-    }
2250
-
2251
-
2252
-    /**
2253
-     * registers metaboxes that should show up on the "edit_message_template" page
2254
-     *
2255
-     * @access protected
2256
-     * @return void
2257
-     */
2258
-    protected function _register_edit_meta_boxes()
2259
-    {
2260
-        add_meta_box(
2261
-            'mtp_valid_shortcodes',
2262
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2263
-            array($this, 'shortcode_meta_box'),
2264
-            $this->_current_screen->id,
2265
-            'side',
2266
-            'default'
2267
-        );
2268
-        add_meta_box(
2269
-            'mtp_extra_actions',
2270
-            esc_html__('Extra Actions', 'event_espresso'),
2271
-            array($this, 'extra_actions_meta_box'),
2272
-            $this->_current_screen->id,
2273
-            'side',
2274
-            'high'
2275
-        );
2276
-        add_meta_box(
2277
-            'mtp_templates',
2278
-            esc_html__('Template Styles', 'event_espresso'),
2279
-            array($this, 'template_pack_meta_box'),
2280
-            $this->_current_screen->id,
2281
-            'side',
2282
-            'high'
2283
-        );
2284
-    }
2285
-
2286
-
2287
-    /**
2288
-     * metabox content for all template pack and variation selection.
2289
-     *
2290
-     * @since 4.5.0
2291
-     * @return string
2292
-     * @throws DomainException
2293
-     * @throws EE_Error
2294
-     * @throws InvalidArgumentException
2295
-     * @throws ReflectionException
2296
-     * @throws InvalidDataTypeException
2297
-     * @throws InvalidInterfaceException
2298
-     */
2299
-    public function template_pack_meta_box()
2300
-    {
2301
-        $this->_set_message_template_group();
2302
-
2303
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2304
-
2305
-        $tp_select_values = array();
2306
-
2307
-        foreach ($tp_collection as $tp) {
2308
-            // only include template packs that support this messenger and message type!
2309
-            $supports = $tp->get_supports();
2310
-            if (! isset($supports[ $this->_message_template_group->messenger() ])
2311
-                || ! in_array(
2312
-                    $this->_message_template_group->message_type(),
2313
-                    $supports[ $this->_message_template_group->messenger() ],
2314
-                    true
2315
-                )
2316
-            ) {
2317
-                // not supported
2318
-                continue;
2319
-            }
2320
-
2321
-            $tp_select_values[] = array(
2322
-                'text' => $tp->label,
2323
-                'id'   => $tp->dbref,
2324
-            );
2325
-        }
2326
-
2327
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2328
-        // the default template pack.  This still allows for the odd template pack to override.
2329
-        if (empty($tp_select_values)) {
2330
-            $tp_select_values[] = array(
2331
-                'text' => esc_html__('Default', 'event_espresso'),
2332
-                'id'   => 'default',
2333
-            );
2334
-        }
2335
-
2336
-        // setup variation select values for the currently selected template.
2337
-        $variations = $this->_message_template_group->get_template_pack()->get_variations(
2338
-            $this->_message_template_group->messenger(),
2339
-            $this->_message_template_group->message_type()
2340
-        );
2341
-        $variations_select_values = array();
2342
-        foreach ($variations as $variation => $label) {
2343
-            $variations_select_values[] = array(
2344
-                'text' => $label,
2345
-                'id'   => $variation,
2346
-            );
2347
-        }
2348
-
2349
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2350
-
2351
-        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2352
-            'MTP_template_pack',
2353
-            $tp_select_values,
2354
-            $this->_message_template_group->get_template_pack_name()
2355
-        );
2356
-        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
2357
-            'MTP_template_variation',
2358
-            $variations_select_values,
2359
-            $this->_message_template_group->get_template_pack_variation()
2360
-        );
2361
-        $template_args['template_pack_label'] = $template_pack_labels->template_pack;
2362
-        $template_args['template_variation_label'] = $template_pack_labels->template_variation;
2363
-        $template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2364
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2365
-
2366
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2367
-
2368
-        EEH_Template::display_template($template, $template_args);
2369
-    }
2370
-
2371
-
2372
-    /**
2373
-     * This meta box holds any extra actions related to Message Templates
2374
-     * For now, this includes Resetting templates to defaults and sending a test email.
2375
-     *
2376
-     * @access  public
2377
-     * @return void
2378
-     * @throws EE_Error
2379
-     */
2380
-    public function extra_actions_meta_box()
2381
-    {
2382
-        $template_form_fields = array();
2383
-
2384
-        $extra_args = array(
2385
-            'msgr'   => $this->_message_template_group->messenger(),
2386
-            'mt'     => $this->_message_template_group->message_type(),
2387
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2388
-        );
2389
-        // first we need to see if there are any fields
2390
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2391
-
2392
-        if (! empty($fields)) {
2393
-            // yup there be fields
2394
-            foreach ($fields as $field => $config) {
2395
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2396
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2397
-                $default = isset($config['default']) ? $config['default'] : '';
2398
-                $default = isset($config['value']) ? $config['value'] : $default;
2399
-
2400
-                // if type is hidden and the value is empty
2401
-                // something may have gone wrong so let's correct with the defaults
2402
-                $fix = $config['input'] === 'hidden'
2403
-                       && isset($existing[ $field ])
2404
-                       && empty($existing[ $field ])
2405
-                    ? $default
2406
-                    : '';
2407
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2408
-                    ? $existing[ $field ]
2409
-                    : $fix;
2410
-
2411
-                $template_form_fields[ $field_id ] = array(
2412
-                    'name'       => 'test_settings_fld[' . $field . ']',
2413
-                    'label'      => $config['label'],
2414
-                    'input'      => $config['input'],
2415
-                    'type'       => $config['type'],
2416
-                    'required'   => $config['required'],
2417
-                    'validation' => $config['validation'],
2418
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2419
-                    'css_class'  => $config['css_class'],
2420
-                    'options'    => isset($config['options']) ? $config['options'] : array(),
2421
-                    'default'    => $default,
2422
-                    'format'     => $config['format'],
2423
-                );
2424
-            }
2425
-        }
2426
-
2427
-        $test_settings_fields = ! empty($template_form_fields)
2428
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2429
-            : '';
2430
-
2431
-        $test_settings_html = '';
2432
-        // print out $test_settings_fields
2433
-        if (! empty($test_settings_fields)) {
2434
-            echo $test_settings_fields;
2435
-            $test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2436
-            $test_settings_html .= 'name="test_button" value="';
2437
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2438
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2439
-        }
2440
-
2441
-        // and button
2442
-        $test_settings_html .= '<p>'
2443
-                               . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2444
-                               . '</p>';
2445
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2446
-        $test_settings_html .= $this->get_action_link_or_button(
2447
-            'reset_to_default',
2448
-            'reset',
2449
-            $extra_args,
2450
-            'button-primary reset-default-button'
2451
-        );
2452
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2453
-        echo $test_settings_html;
2454
-    }
2455
-
2456
-
2457
-    /**
2458
-     * This returns the shortcode selector skeleton for a given context and field.
2459
-     *
2460
-     * @since 4.9.rc.000
2461
-     * @param string $field           The name of the field retrieving shortcodes for.
2462
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2463
-     * @return string
2464
-     * @throws DomainException
2465
-     * @throws EE_Error
2466
-     * @throws InvalidArgumentException
2467
-     * @throws ReflectionException
2468
-     * @throws InvalidDataTypeException
2469
-     * @throws InvalidInterfaceException
2470
-     */
2471
-    protected function _get_shortcode_selector($field, $linked_input_id)
2472
-    {
2473
-        $template_args = array(
2474
-            'shortcodes'      => $this->_get_shortcodes(array($field), true),
2475
-            'fieldname'       => $field,
2476
-            'linked_input_id' => $linked_input_id,
2477
-        );
2478
-
2479
-        return EEH_Template::display_template(
2480
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2481
-            $template_args,
2482
-            true
2483
-        );
2484
-    }
2485
-
2486
-
2487
-    /**
2488
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2489
-     * page)
2490
-     *
2491
-     * @access public
2492
-     * @return void
2493
-     * @throws EE_Error
2494
-     * @throws InvalidArgumentException
2495
-     * @throws ReflectionException
2496
-     * @throws InvalidDataTypeException
2497
-     * @throws InvalidInterfaceException
2498
-     */
2499
-    public function shortcode_meta_box()
2500
-    {
2501
-        $shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2502
-        // $messenger = $this->_message_template_group->messenger_obj();
2503
-        // now let's set the content depending on the status of the shortcodes array
2504
-        if (empty($shortcodes)) {
2505
-            $content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2506
-            echo $content;
2507
-        } else {
2508
-            // $alt = 0;
2509
-            ?>
2147
+		// if we have an evt_id set on the request, use it.
2148
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2149
+		? absint($this->_req_data['evt_id'])
2150
+		: false;
2151
+
2152
+
2153
+		// get the preview!
2154
+		$preview = EED_Messages::preview_message(
2155
+			$this->_req_data['message_type'],
2156
+			$this->_req_data['context'],
2157
+			$this->_req_data['messenger'],
2158
+			$send
2159
+		);
2160
+
2161
+		if ($send) {
2162
+			return $preview;
2163
+		}
2164
+
2165
+		// let's add a button to go back to the edit view
2166
+		$query_args = array(
2167
+			'id'      => $this->_req_data['GRP_ID'],
2168
+			'evt_id'  => $EVT_ID,
2169
+			'context' => $this->_req_data['context'],
2170
+			'action'  => 'edit_message_template',
2171
+		);
2172
+		$go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2173
+		$preview_button = '<a href="'
2174
+						  . $go_back_url
2175
+						  . '" class="button-secondary messages-preview-go-back-button">'
2176
+						  . esc_html__('Go Back to Edit', 'event_espresso')
2177
+						  . '</a>';
2178
+		$message_types = $this->get_installed_message_types();
2179
+		$active_messenger = $this->_message_resource_manager->get_active_messenger(
2180
+			$this->_req_data['messenger']
2181
+		);
2182
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2183
+			? ucwords($active_messenger->label['singular'])
2184
+			: esc_html__('Unknown Messenger', 'event_espresso');
2185
+		// let's provide a helpful title for context
2186
+		$preview_title = sprintf(
2187
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2188
+			$active_messenger_label,
2189
+			ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2190
+		);
2191
+		if (empty($preview)) {
2192
+			$this->noEventsErrorMessage();
2193
+		}
2194
+		// setup display of preview.
2195
+		$this->_admin_page_title = $preview_title;
2196
+		$this->_template_args['admin_page_title'] = $preview_title;
2197
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2198
+		$this->_template_args['data']['force_json'] = true;
2199
+
2200
+		return '';
2201
+	}
2202
+
2203
+
2204
+	/**
2205
+	 * Used to set an error if there are no events available for generating a preview/test send.
2206
+	 *
2207
+	 * @param bool $test_send  Whether the error should be generated for the context of a test send.
2208
+	 */
2209
+	protected function noEventsErrorMessage($test_send = false)
2210
+	{
2211
+		$events_url = parent::add_query_args_and_nonce(
2212
+			array(
2213
+				'action' => 'default',
2214
+				'page'   => 'espresso_events',
2215
+			),
2216
+			admin_url('admin.php')
2217
+		);
2218
+		$message = $test_send
2219
+			? __(
2220
+				'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!',
2221
+				'event_espresso'
2222
+			)
2223
+			: __(
2224
+				'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!',
2225
+				'event_espresso'
2226
+			);
2227
+
2228
+		EE_Error::add_attention(
2229
+			sprintf(
2230
+				$message,
2231
+				"<a href='{$events_url}'>",
2232
+				'</a>'
2233
+			)
2234
+		);
2235
+	}
2236
+
2237
+
2238
+	/**
2239
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2240
+	 * gets called automatically.
2241
+	 *
2242
+	 * @since 4.5.0
2243
+	 *
2244
+	 * @return string
2245
+	 */
2246
+	protected function _display_preview_message()
2247
+	{
2248
+		$this->display_admin_page_with_no_sidebar();
2249
+	}
2250
+
2251
+
2252
+	/**
2253
+	 * registers metaboxes that should show up on the "edit_message_template" page
2254
+	 *
2255
+	 * @access protected
2256
+	 * @return void
2257
+	 */
2258
+	protected function _register_edit_meta_boxes()
2259
+	{
2260
+		add_meta_box(
2261
+			'mtp_valid_shortcodes',
2262
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2263
+			array($this, 'shortcode_meta_box'),
2264
+			$this->_current_screen->id,
2265
+			'side',
2266
+			'default'
2267
+		);
2268
+		add_meta_box(
2269
+			'mtp_extra_actions',
2270
+			esc_html__('Extra Actions', 'event_espresso'),
2271
+			array($this, 'extra_actions_meta_box'),
2272
+			$this->_current_screen->id,
2273
+			'side',
2274
+			'high'
2275
+		);
2276
+		add_meta_box(
2277
+			'mtp_templates',
2278
+			esc_html__('Template Styles', 'event_espresso'),
2279
+			array($this, 'template_pack_meta_box'),
2280
+			$this->_current_screen->id,
2281
+			'side',
2282
+			'high'
2283
+		);
2284
+	}
2285
+
2286
+
2287
+	/**
2288
+	 * metabox content for all template pack and variation selection.
2289
+	 *
2290
+	 * @since 4.5.0
2291
+	 * @return string
2292
+	 * @throws DomainException
2293
+	 * @throws EE_Error
2294
+	 * @throws InvalidArgumentException
2295
+	 * @throws ReflectionException
2296
+	 * @throws InvalidDataTypeException
2297
+	 * @throws InvalidInterfaceException
2298
+	 */
2299
+	public function template_pack_meta_box()
2300
+	{
2301
+		$this->_set_message_template_group();
2302
+
2303
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2304
+
2305
+		$tp_select_values = array();
2306
+
2307
+		foreach ($tp_collection as $tp) {
2308
+			// only include template packs that support this messenger and message type!
2309
+			$supports = $tp->get_supports();
2310
+			if (! isset($supports[ $this->_message_template_group->messenger() ])
2311
+				|| ! in_array(
2312
+					$this->_message_template_group->message_type(),
2313
+					$supports[ $this->_message_template_group->messenger() ],
2314
+					true
2315
+				)
2316
+			) {
2317
+				// not supported
2318
+				continue;
2319
+			}
2320
+
2321
+			$tp_select_values[] = array(
2322
+				'text' => $tp->label,
2323
+				'id'   => $tp->dbref,
2324
+			);
2325
+		}
2326
+
2327
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2328
+		// the default template pack.  This still allows for the odd template pack to override.
2329
+		if (empty($tp_select_values)) {
2330
+			$tp_select_values[] = array(
2331
+				'text' => esc_html__('Default', 'event_espresso'),
2332
+				'id'   => 'default',
2333
+			);
2334
+		}
2335
+
2336
+		// setup variation select values for the currently selected template.
2337
+		$variations = $this->_message_template_group->get_template_pack()->get_variations(
2338
+			$this->_message_template_group->messenger(),
2339
+			$this->_message_template_group->message_type()
2340
+		);
2341
+		$variations_select_values = array();
2342
+		foreach ($variations as $variation => $label) {
2343
+			$variations_select_values[] = array(
2344
+				'text' => $label,
2345
+				'id'   => $variation,
2346
+			);
2347
+		}
2348
+
2349
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2350
+
2351
+		$template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2352
+			'MTP_template_pack',
2353
+			$tp_select_values,
2354
+			$this->_message_template_group->get_template_pack_name()
2355
+		);
2356
+		$template_args['variations_selector'] = EEH_Form_Fields::select_input(
2357
+			'MTP_template_variation',
2358
+			$variations_select_values,
2359
+			$this->_message_template_group->get_template_pack_variation()
2360
+		);
2361
+		$template_args['template_pack_label'] = $template_pack_labels->template_pack;
2362
+		$template_args['template_variation_label'] = $template_pack_labels->template_variation;
2363
+		$template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2364
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2365
+
2366
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2367
+
2368
+		EEH_Template::display_template($template, $template_args);
2369
+	}
2370
+
2371
+
2372
+	/**
2373
+	 * This meta box holds any extra actions related to Message Templates
2374
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2375
+	 *
2376
+	 * @access  public
2377
+	 * @return void
2378
+	 * @throws EE_Error
2379
+	 */
2380
+	public function extra_actions_meta_box()
2381
+	{
2382
+		$template_form_fields = array();
2383
+
2384
+		$extra_args = array(
2385
+			'msgr'   => $this->_message_template_group->messenger(),
2386
+			'mt'     => $this->_message_template_group->message_type(),
2387
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2388
+		);
2389
+		// first we need to see if there are any fields
2390
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2391
+
2392
+		if (! empty($fields)) {
2393
+			// yup there be fields
2394
+			foreach ($fields as $field => $config) {
2395
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2396
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2397
+				$default = isset($config['default']) ? $config['default'] : '';
2398
+				$default = isset($config['value']) ? $config['value'] : $default;
2399
+
2400
+				// if type is hidden and the value is empty
2401
+				// something may have gone wrong so let's correct with the defaults
2402
+				$fix = $config['input'] === 'hidden'
2403
+					   && isset($existing[ $field ])
2404
+					   && empty($existing[ $field ])
2405
+					? $default
2406
+					: '';
2407
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2408
+					? $existing[ $field ]
2409
+					: $fix;
2410
+
2411
+				$template_form_fields[ $field_id ] = array(
2412
+					'name'       => 'test_settings_fld[' . $field . ']',
2413
+					'label'      => $config['label'],
2414
+					'input'      => $config['input'],
2415
+					'type'       => $config['type'],
2416
+					'required'   => $config['required'],
2417
+					'validation' => $config['validation'],
2418
+					'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2419
+					'css_class'  => $config['css_class'],
2420
+					'options'    => isset($config['options']) ? $config['options'] : array(),
2421
+					'default'    => $default,
2422
+					'format'     => $config['format'],
2423
+				);
2424
+			}
2425
+		}
2426
+
2427
+		$test_settings_fields = ! empty($template_form_fields)
2428
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2429
+			: '';
2430
+
2431
+		$test_settings_html = '';
2432
+		// print out $test_settings_fields
2433
+		if (! empty($test_settings_fields)) {
2434
+			echo $test_settings_fields;
2435
+			$test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2436
+			$test_settings_html .= 'name="test_button" value="';
2437
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2438
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2439
+		}
2440
+
2441
+		// and button
2442
+		$test_settings_html .= '<p>'
2443
+							   . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2444
+							   . '</p>';
2445
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2446
+		$test_settings_html .= $this->get_action_link_or_button(
2447
+			'reset_to_default',
2448
+			'reset',
2449
+			$extra_args,
2450
+			'button-primary reset-default-button'
2451
+		);
2452
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2453
+		echo $test_settings_html;
2454
+	}
2455
+
2456
+
2457
+	/**
2458
+	 * This returns the shortcode selector skeleton for a given context and field.
2459
+	 *
2460
+	 * @since 4.9.rc.000
2461
+	 * @param string $field           The name of the field retrieving shortcodes for.
2462
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2463
+	 * @return string
2464
+	 * @throws DomainException
2465
+	 * @throws EE_Error
2466
+	 * @throws InvalidArgumentException
2467
+	 * @throws ReflectionException
2468
+	 * @throws InvalidDataTypeException
2469
+	 * @throws InvalidInterfaceException
2470
+	 */
2471
+	protected function _get_shortcode_selector($field, $linked_input_id)
2472
+	{
2473
+		$template_args = array(
2474
+			'shortcodes'      => $this->_get_shortcodes(array($field), true),
2475
+			'fieldname'       => $field,
2476
+			'linked_input_id' => $linked_input_id,
2477
+		);
2478
+
2479
+		return EEH_Template::display_template(
2480
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2481
+			$template_args,
2482
+			true
2483
+		);
2484
+	}
2485
+
2486
+
2487
+	/**
2488
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2489
+	 * page)
2490
+	 *
2491
+	 * @access public
2492
+	 * @return void
2493
+	 * @throws EE_Error
2494
+	 * @throws InvalidArgumentException
2495
+	 * @throws ReflectionException
2496
+	 * @throws InvalidDataTypeException
2497
+	 * @throws InvalidInterfaceException
2498
+	 */
2499
+	public function shortcode_meta_box()
2500
+	{
2501
+		$shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2502
+		// $messenger = $this->_message_template_group->messenger_obj();
2503
+		// now let's set the content depending on the status of the shortcodes array
2504
+		if (empty($shortcodes)) {
2505
+			$content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2506
+			echo $content;
2507
+		} else {
2508
+			// $alt = 0;
2509
+			?>
2510 2510
             <div style="float:right; margin-top:10px"><?php
2511
-                            echo $this->_get_help_tab_link('message_template_shortcodes');
2512
-                            ?></div>
2511
+							echo $this->_get_help_tab_link('message_template_shortcodes');
2512
+							?></div>
2513 2513
             <p class="small-text"><?php
2514
-                                  printf(
2515
-                                      esc_html__(
2516
-                                          'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2517
-                                          'event_espresso'
2518
-                                      ),
2519
-                                      '<span class="dashicons dashicons-menu"></span>'
2520
-                                  );
2521
-                                ?>
2514
+								  printf(
2515
+									  esc_html__(
2516
+										  'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2517
+										  'event_espresso'
2518
+									  ),
2519
+									  '<span class="dashicons dashicons-menu"></span>'
2520
+								  );
2521
+								?>
2522 2522
             </p>
2523 2523
             <?php
2524
-        }
2525
-    }
2526
-
2527
-
2528
-    /**
2529
-     * used to set the $_shortcodes property for when its needed elsewhere.
2530
-     *
2531
-     * @access protected
2532
-     * @return void
2533
-     * @throws EE_Error
2534
-     * @throws InvalidArgumentException
2535
-     * @throws ReflectionException
2536
-     * @throws InvalidDataTypeException
2537
-     * @throws InvalidInterfaceException
2538
-     */
2539
-    protected function _set_shortcodes()
2540
-    {
2541
-
2542
-        // no need to run this if the property is already set
2543
-        if (! empty($this->_shortcodes)) {
2544
-            return;
2545
-        }
2546
-
2547
-        $this->_shortcodes = $this->_get_shortcodes();
2548
-    }
2549
-
2550
-
2551
-    /**
2552
-     * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2553
-     * property)
2554
-     *
2555
-     * @access  protected
2556
-     * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2557
-     *                         for. Defaults to all (for the given context)
2558
-     * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2559
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2560
-     *                         true just an array of shortcode/label pairs.
2561
-     * @throws EE_Error
2562
-     * @throws InvalidArgumentException
2563
-     * @throws ReflectionException
2564
-     * @throws InvalidDataTypeException
2565
-     * @throws InvalidInterfaceException
2566
-     */
2567
-    protected function _get_shortcodes($fields = array(), $merged = true)
2568
-    {
2569
-        $this->_set_message_template_group();
2570
-
2571
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2572
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2573
-            ? absint($this->_req_data['id'])
2574
-            : false;
2575
-        $context = isset($this->_req_data['context'])
2576
-            ? $this->_req_data['context']
2577
-            : key($this->_message_template_group->contexts_config());
2578
-
2579
-        return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2580
-    }
2581
-
2582
-
2583
-    /**
2584
-     * This sets the _message_template property (containing the called message_template object)
2585
-     *
2586
-     * @access protected
2587
-     * @return void
2588
-     * @throws EE_Error
2589
-     * @throws InvalidArgumentException
2590
-     * @throws ReflectionException
2591
-     * @throws InvalidDataTypeException
2592
-     * @throws InvalidInterfaceException
2593
-     */
2594
-    protected function _set_message_template_group()
2595
-    {
2596
-
2597
-        if (! empty($this->_message_template_group)) {
2598
-            return;
2599
-        } //get out if this is already set.
2600
-
2601
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2602
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2603
-
2604
-        // let's get the message templates
2605
-        $MTP = EEM_Message_Template_Group::instance();
2606
-
2607
-        if (empty($GRP_ID)) {
2608
-            $this->_message_template_group = $MTP->create_default_object();
2609
-        } else {
2610
-            $this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2611
-        }
2612
-
2613
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2614
-        $this->_variation = $this->_message_template_group->get_template_pack_variation();
2615
-    }
2616
-
2617
-
2618
-    /**
2619
-     * sets up a context switcher for edit forms
2620
-     *
2621
-     * @access  protected
2622
-     * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2623
-     * @param array                      $args                  various things the context switcher needs.
2624
-     * @throws EE_Error
2625
-     */
2626
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2627
-    {
2628
-        $context_details = $template_group_object->contexts_config();
2629
-        $context_label = $template_group_object->context_label();
2630
-        ob_start();
2631
-        ?>
2524
+		}
2525
+	}
2526
+
2527
+
2528
+	/**
2529
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2530
+	 *
2531
+	 * @access protected
2532
+	 * @return void
2533
+	 * @throws EE_Error
2534
+	 * @throws InvalidArgumentException
2535
+	 * @throws ReflectionException
2536
+	 * @throws InvalidDataTypeException
2537
+	 * @throws InvalidInterfaceException
2538
+	 */
2539
+	protected function _set_shortcodes()
2540
+	{
2541
+
2542
+		// no need to run this if the property is already set
2543
+		if (! empty($this->_shortcodes)) {
2544
+			return;
2545
+		}
2546
+
2547
+		$this->_shortcodes = $this->_get_shortcodes();
2548
+	}
2549
+
2550
+
2551
+	/**
2552
+	 * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2553
+	 * property)
2554
+	 *
2555
+	 * @access  protected
2556
+	 * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2557
+	 *                         for. Defaults to all (for the given context)
2558
+	 * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2559
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2560
+	 *                         true just an array of shortcode/label pairs.
2561
+	 * @throws EE_Error
2562
+	 * @throws InvalidArgumentException
2563
+	 * @throws ReflectionException
2564
+	 * @throws InvalidDataTypeException
2565
+	 * @throws InvalidInterfaceException
2566
+	 */
2567
+	protected function _get_shortcodes($fields = array(), $merged = true)
2568
+	{
2569
+		$this->_set_message_template_group();
2570
+
2571
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2572
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2573
+			? absint($this->_req_data['id'])
2574
+			: false;
2575
+		$context = isset($this->_req_data['context'])
2576
+			? $this->_req_data['context']
2577
+			: key($this->_message_template_group->contexts_config());
2578
+
2579
+		return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2580
+	}
2581
+
2582
+
2583
+	/**
2584
+	 * This sets the _message_template property (containing the called message_template object)
2585
+	 *
2586
+	 * @access protected
2587
+	 * @return void
2588
+	 * @throws EE_Error
2589
+	 * @throws InvalidArgumentException
2590
+	 * @throws ReflectionException
2591
+	 * @throws InvalidDataTypeException
2592
+	 * @throws InvalidInterfaceException
2593
+	 */
2594
+	protected function _set_message_template_group()
2595
+	{
2596
+
2597
+		if (! empty($this->_message_template_group)) {
2598
+			return;
2599
+		} //get out if this is already set.
2600
+
2601
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2602
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2603
+
2604
+		// let's get the message templates
2605
+		$MTP = EEM_Message_Template_Group::instance();
2606
+
2607
+		if (empty($GRP_ID)) {
2608
+			$this->_message_template_group = $MTP->create_default_object();
2609
+		} else {
2610
+			$this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2611
+		}
2612
+
2613
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2614
+		$this->_variation = $this->_message_template_group->get_template_pack_variation();
2615
+	}
2616
+
2617
+
2618
+	/**
2619
+	 * sets up a context switcher for edit forms
2620
+	 *
2621
+	 * @access  protected
2622
+	 * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2623
+	 * @param array                      $args                  various things the context switcher needs.
2624
+	 * @throws EE_Error
2625
+	 */
2626
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2627
+	{
2628
+		$context_details = $template_group_object->contexts_config();
2629
+		$context_label = $template_group_object->context_label();
2630
+		ob_start();
2631
+		?>
2632 2632
         <div class="ee-msg-switcher-container">
2633 2633
             <form method="get" action="<?php echo EE_MSG_ADMIN_URL; ?>" id="ee-msg-context-switcher-frm">
2634 2634
                 <?php
2635
-                foreach ($args as $name => $value) {
2636
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2637
-                        continue;
2638
-                    }
2639
-                    ?>
2635
+				foreach ($args as $name => $value) {
2636
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2637
+						continue;
2638
+					}
2639
+					?>
2640 2640
                     <input type="hidden" name="<?php echo $name; ?>" value="<?php echo $value; ?>"/>
2641 2641
                     <?php
2642
-                }
2643
-                // setup nonce_url
2644
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2645
-                ?>
2642
+				}
2643
+				// setup nonce_url
2644
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2645
+				?>
2646 2646
                 <select name="context">
2647 2647
                     <?php
2648
-                    $context_templates = $template_group_object->context_templates();
2649
-                    if (is_array($context_templates)) :
2650
-                        foreach ($context_templates as $context => $template_fields) :
2651
-                            $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2652
-                            ?>
2648
+					$context_templates = $template_group_object->context_templates();
2649
+					if (is_array($context_templates)) :
2650
+						foreach ($context_templates as $context => $template_fields) :
2651
+							$checked = ($context === $args['context']) ? 'selected="selected"' : '';
2652
+							?>
2653 2653
                             <option value="<?php echo $context; ?>" <?php echo $checked; ?>>
2654 2654
                                 <?php echo $context_details[ $context ]['label']; ?>
2655 2655
                             </option>
2656 2656
                         <?php endforeach;
2657
-                    endif; ?>
2657
+					endif; ?>
2658 2658
                 </select>
2659 2659
                 <?php $button_text = sprintf(__('Switch %s', 'event_espresso'), ucwords($context_label['label'])); ?>
2660 2660
                 <input id="submit-msg-context-switcher-sbmt" class="button-secondary" type="submit"
@@ -2663,1925 +2663,1925 @@  discard block
 block discarded – undo
2663 2663
             <?php echo $args['extra']; ?>
2664 2664
         </div> <!-- end .ee-msg-switcher-container -->
2665 2665
         <?php
2666
-        $output = ob_get_contents();
2667
-        ob_clean();
2668
-        $this->_context_switcher = $output;
2669
-    }
2670
-
2671
-
2672
-    /**
2673
-     * utility for sanitizing new values coming in.
2674
-     * Note: this is only used when updating a context.
2675
-     *
2676
-     * @access protected
2677
-     *
2678
-     * @param int $index This helps us know which template field to select from the request array.
2679
-     *
2680
-     * @return array
2681
-     */
2682
-    protected function _set_message_template_column_values($index)
2683
-    {
2684
-        if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2685
-            foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2686
-                $this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2687
-            }
2688
-        }
2689
-
2690
-
2691
-        $set_column_values = array(
2692
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2693
-            'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2694
-            'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2695
-            'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2696
-            'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2697
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2698
-            'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2699
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2700
-            'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2701
-                ? absint($this->_req_data['MTP_is_global'])
2702
-                : 0,
2703
-            'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2704
-                ? absint($this->_req_data['MTP_is_override'])
2705
-                : 0,
2706
-            'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2707
-            'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2708
-        );
2709
-
2710
-
2711
-        return $set_column_values;
2712
-    }
2713
-
2714
-
2715
-    protected function _insert_or_update_message_template($new = false)
2716
-    {
2717
-
2718
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2719
-        $success = 0;
2720
-        $override = false;
2721
-
2722
-        // setup notices description
2723
-        $messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2724
-
2725
-        // need the message type and messenger objects to be able to use the labels for the notices
2726
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2727
-        $messenger_label = $messenger_object instanceof EE_messenger
2728
-            ? ucwords($messenger_object->label['singular'])
2729
-            : '';
2730
-
2731
-        $message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2732
-            ? $this->_req_data['MTP_message_type']
2733
-            : '';
2734
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2735
-
2736
-        $message_type_label = $message_type_object instanceof EE_message_type
2737
-            ? ucwords($message_type_object->label['singular'])
2738
-            : '';
2739
-
2740
-        $context_slug = ! empty($this->_req_data['MTP_context'])
2741
-            ? $this->_req_data['MTP_context']
2742
-            : '';
2743
-        $context = ucwords(str_replace('_', ' ', $context_slug));
2744
-
2745
-        $item_desc = $messenger_label && $message_type_label
2746
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2747
-            : '';
2748
-        $item_desc .= 'Message Template';
2749
-        $query_args = array();
2750
-        $edit_array = array();
2751
-        $action_desc = '';
2752
-
2753
-        // if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2754
-        // user to edit.
2755
-        if ($new) {
2756
-            $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2757
-            if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2758
-                if (empty($edit_array)) {
2759
-                    $success = 0;
2760
-                } else {
2761
-                    $success = 1;
2762
-                    $edit_array = $edit_array[0];
2763
-                    $query_args = array(
2764
-                        'id'      => $edit_array['GRP_ID'],
2765
-                        'context' => $edit_array['MTP_context'],
2766
-                        'action'  => 'edit_message_template',
2767
-                    );
2768
-                }
2769
-            }
2770
-            $action_desc = 'created';
2771
-        } else {
2772
-            $MTPG = EEM_Message_Template_Group::instance();
2773
-            $MTP = EEM_Message_Template::instance();
2774
-
2775
-
2776
-            // run update for each template field in displayed context
2777
-            if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2778
-                EE_Error::add_error(
2779
-                    esc_html__(
2780
-                        'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2781
-                        'event_espresso'
2782
-                    ),
2783
-                    __FILE__,
2784
-                    __FUNCTION__,
2785
-                    __LINE__
2786
-                );
2787
-                $success = 0;
2788
-            } else {
2789
-                // first validate all fields!
2790
-                // this filter allows client code to add its own validation to the template fields as well.
2791
-                // returning an empty array means everything passed validation.
2792
-                // errors in validation should be represented in an array with the following shape:
2793
-                // array(
2794
-                //   'fieldname' => array(
2795
-                //          'msg' => 'error message'
2796
-                //          'value' => 'value for field producing error'
2797
-                // )
2798
-                $custom_validation = (array) apply_filters(
2799
-                    'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2800
-                    array(),
2801
-                    $this->_req_data['MTP_template_fields'],
2802
-                    $context_slug,
2803
-                    $messenger_slug,
2804
-                    $message_type_slug
2805
-                );
2806
-
2807
-                $system_validation = $MTPG->validate(
2808
-                    $this->_req_data['MTP_template_fields'],
2809
-                    $context_slug,
2810
-                    $messenger_slug,
2811
-                    $message_type_slug
2812
-                );
2813
-
2814
-                $system_validation = ! is_array($system_validation) && $system_validation ? array()
2815
-                    : $system_validation;
2816
-                $validates = array_merge($custom_validation, $system_validation);
2817
-
2818
-                // if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2819
-                // appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2820
-                //  WE need to make sure there is no actual error messages in validates.
2821
-                if (is_array($validates) && ! empty($validates)) {
2822
-                    // add the transient so when the form loads we know which fields to highlight
2823
-                    $this->_add_transient('edit_message_template', $validates);
2824
-
2825
-                    $success = 0;
2826
-
2827
-                    // setup notices
2828
-                    foreach ($validates as $field => $error) {
2829
-                        if (isset($error['msg'])) {
2830
-                            EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2831
-                        }
2832
-                    }
2833
-                } else {
2834
-                    $set_column_values = array();
2835
-                    foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2836
-                        $set_column_values = $this->_set_message_template_column_values($template_field);
2837
-
2838
-                        $where_cols_n_values = array(
2839
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2840
-                        );
2841
-                        // if they aren't allowed to use all JS, restrict them to just posty-y tags
2842
-                        if (! current_user_can('unfiltered_html')) {
2843
-                            if (is_array($set_column_values['MTP_content'])) {
2844
-                                foreach ($set_column_values['MTP_content'] as $key => $value) {
2845
-                                    // remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2846
-                                    // only removes slashes from double-quotes, so attributes using single quotes always
2847
-                                    // appear invalid.) But currently the models expect slashed data, so after wp_kses
2848
-                                    // runs we need to re-slash the data. Sheesh. See
2849
-                                    // https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2850
-                                    $set_column_values['MTP_content'][ $key ] = addslashes(
2851
-                                        wp_kses(
2852
-                                            stripslashes($value),
2853
-                                            wp_kses_allowed_html('post')
2854
-                                        )
2855
-                                    );
2856
-                                }
2857
-                            } else {
2858
-                                $set_column_values['MTP_content'] = wp_kses(
2859
-                                    $set_column_values['MTP_content'],
2860
-                                    wp_kses_allowed_html('post')
2861
-                                );
2862
-                            }
2863
-                        }
2864
-                        $message_template_fields = array(
2865
-                            'GRP_ID'             => $set_column_values['GRP_ID'],
2866
-                            'MTP_template_field' => $set_column_values['MTP_template_field'],
2867
-                            'MTP_context'        => $set_column_values['MTP_context'],
2868
-                            'MTP_content'        => $set_column_values['MTP_content'],
2869
-                        );
2870
-                        if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2871
-                            if ($updated === false) {
2872
-                                EE_Error::add_error(
2873
-                                    sprintf(
2874
-                                        esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2875
-                                        $template_field
2876
-                                    ),
2877
-                                    __FILE__,
2878
-                                    __FUNCTION__,
2879
-                                    __LINE__
2880
-                                );
2881
-                            } else {
2882
-                                $success = 1;
2883
-                            }
2884
-                        } else {
2885
-                            // only do this logic if we don't have a MTP_ID for this field
2886
-                            if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2887
-                                // this has already been through the template field validator and sanitized, so it will be
2888
-                                // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2889
-                                // message template field in a messenger/message type and existing users don't have the
2890
-                                // default setup for it.
2891
-                                // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2892
-                                $updated = $MTP->insert($message_template_fields);
2893
-                                if (! $updated || is_wp_error($updated)) {
2894
-                                    EE_Error::add_error(
2895
-                                        sprintf(
2896
-                                            esc_html__('%s field could not be updated.', 'event_espresso'),
2897
-                                            $template_field
2898
-                                        ),
2899
-                                        __FILE__,
2900
-                                        __FUNCTION__,
2901
-                                        __LINE__
2902
-                                    );
2903
-                                    $success = 0;
2904
-                                } else {
2905
-                                    $success = 1;
2906
-                                }
2907
-                            }
2908
-                        }
2909
-                        $action_desc = 'updated';
2910
-                    }
2911
-
2912
-                    // we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2913
-                    $mtpg_fields = array(
2914
-                        'MTP_user_id'      => $set_column_values['MTP_user_id'],
2915
-                        'MTP_messenger'    => $set_column_values['MTP_messenger'],
2916
-                        'MTP_message_type' => $set_column_values['MTP_message_type'],
2917
-                        'MTP_is_global'    => $set_column_values['MTP_is_global'],
2918
-                        'MTP_is_override'  => $set_column_values['MTP_is_override'],
2919
-                        'MTP_deleted'      => $set_column_values['MTP_deleted'],
2920
-                        'MTP_is_active'    => $set_column_values['MTP_is_active'],
2921
-                        'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2922
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2923
-                            : '',
2924
-                        'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2925
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2926
-                            : '',
2927
-                    );
2928
-
2929
-                    $mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2930
-                    $updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2931
-
2932
-                    if ($updated === false) {
2933
-                        EE_Error::add_error(
2934
-                            sprintf(
2935
-                                esc_html__(
2936
-                                    'The Message Template Group (%d) was NOT updated for some reason',
2937
-                                    'event_espresso'
2938
-                                ),
2939
-                                $set_column_values['GRP_ID']
2940
-                            ),
2941
-                            __FILE__,
2942
-                            __FUNCTION__,
2943
-                            __LINE__
2944
-                        );
2945
-                    } else {
2946
-                        // k now we need to ensure the template_pack and template_variation fields are set.
2947
-                        $template_pack = ! empty($this->_req_data['MTP_template_pack'])
2948
-                            ? $this->_req_data['MTP_template_pack']
2949
-                            : 'default';
2950
-
2951
-                        $template_variation = ! empty($this->_req_data['MTP_template_variation'])
2952
-                            ? $this->_req_data['MTP_template_variation']
2953
-                            : 'default';
2954
-
2955
-                        $mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2956
-                        if ($mtpg_obj instanceof EE_Message_Template_Group) {
2957
-                            $mtpg_obj->set_template_pack_name($template_pack);
2958
-                            $mtpg_obj->set_template_pack_variation($template_variation);
2959
-                        }
2960
-                        $success = 1;
2961
-                    }
2962
-                }
2963
-            }
2964
-        }
2965
-
2966
-        // we return things differently if doing ajax
2967
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2968
-            $this->_template_args['success'] = $success;
2969
-            $this->_template_args['error'] = ! $success ? true : false;
2970
-            $this->_template_args['content'] = '';
2971
-            $this->_template_args['data'] = array(
2972
-                'grpID'        => $edit_array['GRP_ID'],
2973
-                'templateName' => $edit_array['template_name'],
2974
-            );
2975
-            if ($success) {
2976
-                EE_Error::overwrite_success();
2977
-                EE_Error::add_success(
2978
-                    esc_html__(
2979
-                        '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.',
2980
-                        'event_espresso'
2981
-                    )
2982
-                );
2983
-            }
2984
-
2985
-            $this->_return_json();
2986
-        }
2987
-
2988
-
2989
-        // was a test send triggered?
2990
-        if (isset($this->_req_data['test_button'])) {
2991
-            EE_Error::overwrite_success();
2992
-            $this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2993
-            $override = true;
2994
-        }
2995
-
2996
-        if (empty($query_args)) {
2997
-            $query_args = array(
2998
-                'id'      => $this->_req_data['GRP_ID'],
2999
-                'context' => $context_slug,
3000
-                'action'  => 'edit_message_template',
3001
-            );
3002
-        }
3003
-
3004
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3005
-    }
3006
-
3007
-
3008
-    /**
3009
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
3010
-     *
3011
-     * @param  string $context      what context being tested
3012
-     * @param  string $messenger    messenger being tested
3013
-     * @param  string $message_type message type being tested
3014
-     * @throws EE_Error
3015
-     * @throws InvalidArgumentException
3016
-     * @throws InvalidDataTypeException
3017
-     * @throws InvalidInterfaceException
3018
-     */
3019
-    protected function _do_test_send($context, $messenger, $message_type)
3020
-    {
3021
-        // set things up for preview
3022
-        $this->_req_data['messenger'] = $messenger;
3023
-        $this->_req_data['message_type'] = $message_type;
3024
-        $this->_req_data['context'] = $context;
3025
-        $this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3026
-        $active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3027
-
3028
-        // let's save any existing fields that might be required by the messenger
3029
-        if (isset($this->_req_data['test_settings_fld'])
3030
-            && $active_messenger instanceof EE_messenger
3031
-            && apply_filters(
3032
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3033
-                true,
3034
-                $this->_req_data['test_settings_fld'],
3035
-                $active_messenger
3036
-            )
3037
-        ) {
3038
-            $active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3039
-        }
3040
-
3041
-        /**
3042
-         * Use filter to add additional controls on whether message can send or not
3043
-         */
3044
-        if (apply_filters(
3045
-            'FHEE__Messages_Admin_Page__do_test_send__can_send',
3046
-            true,
3047
-            $context,
3048
-            $this->_req_data,
3049
-            $messenger,
3050
-            $message_type
3051
-        )) {
3052
-            if (EEM_Event::instance()->count() > 0) {
3053
-                $success = $this->_preview_message(true);
3054
-                if ($success) {
3055
-                    EE_Error::add_success(__('Test message sent', 'event_espresso'));
3056
-                } else {
3057
-                    EE_Error::add_error(
3058
-                        esc_html__('The test message was not sent', 'event_espresso'),
3059
-                        __FILE__,
3060
-                        __FUNCTION__,
3061
-                        __LINE__
3062
-                    );
3063
-                }
3064
-            } else {
3065
-                $this->noEventsErrorMessage(true);
3066
-            }
3067
-        }
3068
-    }
3069
-
3070
-
3071
-    /**
3072
-     * _generate_new_templates
3073
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3074
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3075
-     * for the event.
3076
-     *
3077
-     *
3078
-     * @param  string $messenger     the messenger we are generating templates for
3079
-     * @param array   $message_types array of message types that the templates are generated for.
3080
-     * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3081
-     *                               indicate the message_template_group being used as the base.
3082
-     *
3083
-     * @param bool    $global
3084
-     *
3085
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
3086
-     *                               encountering problems.
3087
-     * @throws EE_Error
3088
-     */
3089
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3090
-    {
3091
-
3092
-        // if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3093
-        // just don't generate any templates.
3094
-        if (empty($message_types)) {
3095
-            return true;
3096
-        }
3097
-
3098
-        return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3099
-    }
3100
-
3101
-
3102
-    /**
3103
-     * [_trash_or_restore_message_template]
3104
-     *
3105
-     * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3106
-     * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3107
-     *                        an individual context (FALSE).
3108
-     * @return void
3109
-     * @throws EE_Error
3110
-     * @throws InvalidArgumentException
3111
-     * @throws InvalidDataTypeException
3112
-     * @throws InvalidInterfaceException
3113
-     */
3114
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
3115
-    {
3116
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3117
-        $MTP = EEM_Message_Template_Group::instance();
3118
-
3119
-        $success = 1;
3120
-
3121
-        // incoming GRP_IDs
3122
-        if ($all) {
3123
-            // Checkboxes
3124
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3125
-                // if array has more than one element then success message should be plural.
3126
-                // todo: what about nonce?
3127
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3128
-
3129
-                // cycle through checkboxes
3130
-                while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3131
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3132
-                    if (! $trashed_or_restored) {
3133
-                        $success = 0;
3134
-                    }
3135
-                }
3136
-            } else {
3137
-                // grab single GRP_ID and handle
3138
-                $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3139
-                if (! empty($GRP_ID)) {
3140
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3141
-                    if (! $trashed_or_restored) {
3142
-                        $success = 0;
3143
-                    }
3144
-                } else {
3145
-                    $success = 0;
3146
-                }
3147
-            }
3148
-        }
3149
-
3150
-        $action_desc = $trash
3151
-            ? esc_html__('moved to the trash', 'event_espresso')
3152
-            : esc_html__('restored', 'event_espresso');
3153
-
3154
-        $action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3155
-
3156
-        $item_desc = $all ? _n(
3157
-            'Message Template Group',
3158
-            'Message Template Groups',
3159
-            $success,
3160
-            'event_espresso'
3161
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3162
-
3163
-        $item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3164
-            'template',
3165
-            'templates',
3166
-            $success,
3167
-            'event_espresso'
3168
-        ) : $item_desc;
3169
-
3170
-        $this->_redirect_after_action($success, $item_desc, $action_desc, array());
3171
-    }
3172
-
3173
-
3174
-    /**
3175
-     * [_delete_message_template]
3176
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3177
-     *
3178
-     * @return void
3179
-     * @throws EE_Error
3180
-     * @throws InvalidArgumentException
3181
-     * @throws InvalidDataTypeException
3182
-     * @throws InvalidInterfaceException
3183
-     */
3184
-    protected function _delete_message_template()
3185
-    {
3186
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3187
-
3188
-        // checkboxes
3189
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3190
-            // if array has more than one element then success message should be plural
3191
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3192
-
3193
-            // cycle through bulk action checkboxes
3194
-            while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3195
-                $success = $this->_delete_mtp_permanently($GRP_ID);
3196
-            }
3197
-        } else {
3198
-            // grab single grp_id and delete
3199
-            $GRP_ID = absint($this->_req_data['id']);
3200
-            $success = $this->_delete_mtp_permanently($GRP_ID);
3201
-        }
3202
-
3203
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3204
-    }
3205
-
3206
-
3207
-    /**
3208
-     * helper for permanently deleting a mtP group and all related message_templates
3209
-     *
3210
-     * @param  int  $GRP_ID        The group being deleted
3211
-     * @param  bool $include_group whether to delete the Message Template Group as well.
3212
-     * @return bool boolean to indicate the success of the deletes or not.
3213
-     * @throws EE_Error
3214
-     * @throws InvalidArgumentException
3215
-     * @throws InvalidDataTypeException
3216
-     * @throws InvalidInterfaceException
3217
-     */
3218
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3219
-    {
3220
-        $success = 1;
3221
-        $MTPG = EEM_Message_Template_Group::instance();
3222
-        // first let's GET this group
3223
-        $MTG = $MTPG->get_one_by_ID($GRP_ID);
3224
-        // then delete permanently all the related Message Templates
3225
-        $deleted = $MTG->delete_related_permanently('Message_Template');
3226
-
3227
-        if ($deleted === 0) {
3228
-            $success = 0;
3229
-        }
3230
-
3231
-        // now delete permanently this particular group
3232
-
3233
-        if ($include_group && ! $MTG->delete_permanently()) {
3234
-            $success = 0;
3235
-        }
3236
-
3237
-        return $success;
3238
-    }
3239
-
3240
-
3241
-    /**
3242
-     *    _learn_more_about_message_templates_link
3243
-     *
3244
-     * @access protected
3245
-     * @return string
3246
-     */
3247
-    protected function _learn_more_about_message_templates_link()
3248
-    {
3249
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3250
-               . esc_html__('learn more about how message templates works', 'event_espresso')
3251
-               . '</a>';
3252
-    }
3253
-
3254
-
3255
-    /**
3256
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3257
-     * ajax and other routes.
3258
-     *
3259
-     * @return void
3260
-     * @throws DomainException
3261
-     */
3262
-    protected function _settings()
3263
-    {
3264
-
3265
-
3266
-        $this->_set_m_mt_settings();
3267
-
3268
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3269
-            ? $this->_req_data['selected_messenger']
3270
-            : 'email';
3271
-
3272
-        // let's setup the messenger tabs
3273
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3274
-            $this->_m_mt_settings['messenger_tabs'],
3275
-            'messenger_links',
3276
-            '|',
3277
-            $selected_messenger
3278
-        );
3279
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3280
-        $this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3281
-
3282
-        $this->display_admin_page_with_sidebar();
3283
-    }
3284
-
3285
-
3286
-    /**
3287
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3288
-     *
3289
-     * @access protected
3290
-     * @return void
3291
-     * @throws DomainException
3292
-     */
3293
-    protected function _set_m_mt_settings()
3294
-    {
3295
-        // first if this is already set then lets get out no need to regenerate data.
3296
-        if (! empty($this->_m_mt_settings)) {
3297
-            return;
3298
-        }
3299
-
3300
-        // get all installed messengers and message_types
3301
-        /** @type EE_messenger[] $messengers */
3302
-        $messengers = $this->_message_resource_manager->installed_messengers();
3303
-        /** @type EE_message_type[] $message_types */
3304
-        $message_types = $this->_message_resource_manager->installed_message_types();
3305
-
3306
-
3307
-        // assemble the array for the _tab_text_links helper
3308
-
3309
-        foreach ($messengers as $messenger) {
3310
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3311
-                'label' => ucwords($messenger->label['singular']),
3312
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3313
-                    ? 'messenger-active'
3314
-                    : '',
3315
-                'href'  => $messenger->name,
3316
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3317
-                'slug'  => $messenger->name,
3318
-                'obj'   => $messenger,
3319
-            );
3320
-
3321
-
3322
-            $message_types_for_messenger = $messenger->get_valid_message_types();
3323
-
3324
-            foreach ($message_types as $message_type) {
3325
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3326
-                // it shouldn't show in either the inactive OR active metabox.
3327
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3328
-                    continue;
3329
-                }
3330
-
3331
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3332
-                    $messenger->name,
3333
-                    $message_type->name
3334
-                )
3335
-                    ? 'active'
3336
-                    : 'inactive';
3337
-
3338
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3339
-                    'label'    => ucwords($message_type->label['singular']),
3340
-                    'class'    => 'message-type-' . $a_or_i,
3341
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3342
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3343
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3344
-                    'title'    => $a_or_i === 'active'
3345
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3346
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3347
-                    'content'  => $a_or_i === 'active'
3348
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
3349
-                        : $this->_message_type_settings_content($message_type, $messenger),
3350
-                    'slug'     => $message_type->name,
3351
-                    'active'   => $a_or_i === 'active',
3352
-                    'obj'      => $message_type,
3353
-                );
3354
-            }
3355
-        }
3356
-    }
3357
-
3358
-
3359
-    /**
3360
-     * This just prepares the content for the message type settings
3361
-     *
3362
-     * @param  EE_message_type $message_type The message type object
3363
-     * @param  EE_messenger    $messenger    The messenger object
3364
-     * @param  boolean         $active       Whether the message type is active or not
3365
-     * @return string html output for the content
3366
-     * @throws DomainException
3367
-     */
3368
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
3369
-    {
3370
-        // get message type fields
3371
-        $fields = $message_type->get_admin_settings_fields();
3372
-        $settings_template_args['template_form_fields'] = '';
3373
-
3374
-        if (! empty($fields) && $active) {
3375
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3376
-            foreach ($fields as $fldname => $fldprops) {
3377
-                $field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3378
-                $template_form_field[ $field_id ] = array(
3379
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3380
-                    'label'      => $fldprops['label'],
3381
-                    'input'      => $fldprops['field_type'],
3382
-                    'type'       => $fldprops['value_type'],
3383
-                    'required'   => $fldprops['required'],
3384
-                    'validation' => $fldprops['validation'],
3385
-                    'value'      => isset($existing_settings[ $fldname ])
3386
-                        ? $existing_settings[ $fldname ]
3387
-                        : $fldprops['default'],
3388
-                    'options'    => isset($fldprops['options'])
3389
-                        ? $fldprops['options']
3390
-                        : array(),
3391
-                    'default'    => isset($existing_settings[ $fldname ])
3392
-                        ? $existing_settings[ $fldname ]
3393
-                        : $fldprops['default'],
3394
-                    'css_class'  => 'no-drag',
3395
-                    'format'     => $fldprops['format'],
3396
-                );
3397
-            }
3398
-
3399
-
3400
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3401
-                ? $this->_generate_admin_form_fields(
3402
-                    $template_form_field,
3403
-                    'string',
3404
-                    'ee_mt_activate_form'
3405
-                )
3406
-                : '';
3407
-        }
3408
-
3409
-        $settings_template_args['description'] = $message_type->description;
3410
-        // we also need some hidden fields
3411
-        $settings_template_args['hidden_fields'] = array(
3412
-            'message_type_settings[messenger]'    => array(
3413
-                'type'  => 'hidden',
3414
-                'value' => $messenger->name,
3415
-            ),
3416
-            'message_type_settings[message_type]' => array(
3417
-                'type'  => 'hidden',
3418
-                'value' => $message_type->name,
3419
-            ),
3420
-            'type'                                => array(
3421
-                'type'  => 'hidden',
3422
-                'value' => 'message_type',
3423
-            ),
3424
-        );
3425
-
3426
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3427
-            $settings_template_args['hidden_fields'],
3428
-            'array'
3429
-        );
3430
-        $settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3431
-            ? ' hidden'
3432
-            : '';
3433
-
3434
-
3435
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3436
-        $content = EEH_Template::display_template($template, $settings_template_args, true);
3437
-
3438
-        return $content;
3439
-    }
3440
-
3441
-
3442
-    /**
3443
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3444
-     *
3445
-     * @access protected
3446
-     * @return void
3447
-     * @throws DomainException
3448
-     */
3449
-    protected function _messages_settings_metaboxes()
3450
-    {
3451
-        $this->_set_m_mt_settings();
3452
-        $m_boxes = $mt_boxes = array();
3453
-        $m_template_args = $mt_template_args = array();
3454
-
3455
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3456
-            ? $this->_req_data['selected_messenger']
3457
-            : 'email';
3458
-
3459
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3460
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3461
-                $hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3462
-                $hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3463
-                // messenger meta boxes
3464
-                $active = $selected_messenger === $messenger;
3465
-                $active_mt_tabs = isset(
3466
-                    $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3467
-                )
3468
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3469
-                    : '';
3470
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3471
-                    esc_html__('%s Settings', 'event_espresso'),
3472
-                    $tab_array['label']
3473
-                );
3474
-                $m_template_args[ $messenger . '_a_box' ] = array(
3475
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3476
-                    'inactive_message_types' => isset(
3477
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3478
-                    )
3479
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3480
-                        : '',
3481
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3482
-                    'hidden'                 => $active ? '' : ' hidden',
3483
-                    'hide_on_message'        => $hide_on_message,
3484
-                    'messenger'              => $messenger,
3485
-                    'active'                 => $active,
3486
-                );
3487
-                // message type meta boxes
3488
-                // (which is really just the inactive container for each messenger
3489
-                // showing inactive message types for that messenger)
3490
-                $mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3491
-                $mt_template_args[ $messenger . '_i_box' ] = array(
3492
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3493
-                    'inactive_message_types' => isset(
3494
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3495
-                    )
3496
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3497
-                        : '',
3498
-                    'hidden'                 => $active ? '' : ' hidden',
3499
-                    'hide_on_message'        => $hide_on_message,
3500
-                    'hide_off_message'       => $hide_off_message,
3501
-                    'messenger'              => $messenger,
3502
-                    'active'                 => $active,
3503
-                );
3504
-            }
3505
-        }
3506
-
3507
-
3508
-        // register messenger metaboxes
3509
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3510
-        foreach ($m_boxes as $box => $label) {
3511
-            $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3512
-            $msgr = str_replace('_a_box', '', $box);
3513
-            add_meta_box(
3514
-                'espresso_' . $msgr . '_settings',
3515
-                $label,
3516
-                function ($post, $metabox) {
3517
-                    echo EEH_Template::display_template(
3518
-                        $metabox["args"]["template_path"],
3519
-                        $metabox["args"]["template_args"],
3520
-                        true
3521
-                    );
3522
-                },
3523
-                $this->_current_screen->id,
3524
-                'normal',
3525
-                'high',
3526
-                $callback_args
3527
-            );
3528
-        }
3529
-
3530
-        // register message type metaboxes
3531
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3532
-        foreach ($mt_boxes as $box => $label) {
3533
-            $callback_args = array(
3534
-                'template_path' => $mt_template_path,
3535
-                'template_args' => $mt_template_args[ $box ],
3536
-            );
3537
-            $mt = str_replace('_i_box', '', $box);
3538
-            add_meta_box(
3539
-                'espresso_' . $mt . '_inactive_mts',
3540
-                $label,
3541
-                function ($post, $metabox) {
3542
-                    echo EEH_Template::display_template(
3543
-                        $metabox["args"]["template_path"],
3544
-                        $metabox["args"]["template_args"],
3545
-                        true
3546
-                    );
3547
-                },
3548
-                $this->_current_screen->id,
3549
-                'side',
3550
-                'high',
3551
-                $callback_args
3552
-            );
3553
-        }
3554
-
3555
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3556
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3557
-        if (is_main_site()) {
3558
-            add_meta_box(
3559
-                'espresso_global_message_settings',
3560
-                esc_html__('Global Message Settings', 'event_espresso'),
3561
-                array($this, 'global_messages_settings_metabox_content'),
3562
-                $this->_current_screen->id,
3563
-                'normal',
3564
-                'low',
3565
-                array()
3566
-            );
3567
-        }
3568
-    }
3569
-
3570
-
3571
-    /**
3572
-     *  This generates the content for the global messages settings metabox.
3573
-     *
3574
-     * @return string
3575
-     * @throws EE_Error
3576
-     * @throws InvalidArgumentException
3577
-     * @throws ReflectionException
3578
-     * @throws InvalidDataTypeException
3579
-     * @throws InvalidInterfaceException
3580
-     */
3581
-    public function global_messages_settings_metabox_content()
3582
-    {
3583
-        $form = $this->_generate_global_settings_form();
3584
-        echo $form->form_open(
3585
-            $this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3586
-            'POST'
3587
-        )
3588
-             . $form->get_html()
3589
-             . $form->form_close();
3590
-    }
3591
-
3592
-
3593
-    /**
3594
-     * This generates and returns the form object for the global messages settings.
3595
-     *
3596
-     * @return EE_Form_Section_Proper
3597
-     * @throws EE_Error
3598
-     * @throws InvalidArgumentException
3599
-     * @throws ReflectionException
3600
-     * @throws InvalidDataTypeException
3601
-     * @throws InvalidInterfaceException
3602
-     */
3603
-    protected function _generate_global_settings_form()
3604
-    {
3605
-        EE_Registry::instance()->load_helper('HTML');
3606
-        /** @var EE_Network_Core_Config $network_config */
3607
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3608
-
3609
-        return new EE_Form_Section_Proper(
3610
-            array(
3611
-                'name'            => 'global_messages_settings',
3612
-                'html_id'         => 'global_messages_settings',
3613
-                'html_class'      => 'form-table',
3614
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3615
-                'subsections'     => apply_filters(
3616
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3617
-                    array(
3618
-                        'do_messages_on_same_request' => new EE_Select_Input(
3619
-                            array(
3620
-                                true  => esc_html__("On the same request", "event_espresso"),
3621
-                                false => esc_html__("On a separate request", "event_espresso"),
3622
-                            ),
3623
-                            array(
3624
-                                'default'         => $network_config->do_messages_on_same_request,
3625
-                                'html_label_text' => esc_html__(
3626
-                                    'Generate and send all messages:',
3627
-                                    'event_espresso'
3628
-                                ),
3629
-                                'html_help_text'  => esc_html__(
3630
-                                    '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.',
3631
-                                    'event_espresso'
3632
-                                ),
3633
-                            )
3634
-                        ),
3635
-                        'delete_threshold'            => new EE_Select_Input(
3636
-                            array(
3637
-                                0  => esc_html__('Forever', 'event_espresso'),
3638
-                                3  => esc_html__('3 Months', 'event_espresso'),
3639
-                                6  => esc_html__('6 Months', 'event_espresso'),
3640
-                                9  => esc_html__('9 Months', 'event_espresso'),
3641
-                                12 => esc_html__('12 Months', 'event_espresso'),
3642
-                                24 => esc_html__('24 Months', 'event_espresso'),
3643
-                                36 => esc_html__('36 Months', 'event_espresso'),
3644
-                            ),
3645
-                            array(
3646
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3647
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3648
-                                'html_help_text'  => esc_html__(
3649
-                                    'You can control how long a record of processed messages is kept via this option.',
3650
-                                    'event_espresso'
3651
-                                ),
3652
-                            )
3653
-                        ),
3654
-                        'update_settings'             => new EE_Submit_Input(
3655
-                            array(
3656
-                                'default'         => esc_html__('Update', 'event_espresso'),
3657
-                                'html_label_text' => '&nbsp',
3658
-                            )
3659
-                        ),
3660
-                    )
3661
-                ),
3662
-            )
3663
-        );
3664
-    }
3665
-
3666
-
3667
-    /**
3668
-     * This handles updating the global settings set on the admin page.
3669
-     *
3670
-     * @throws EE_Error
3671
-     * @throws InvalidDataTypeException
3672
-     * @throws InvalidInterfaceException
3673
-     * @throws InvalidArgumentException
3674
-     * @throws ReflectionException
3675
-     */
3676
-    protected function _update_global_settings()
3677
-    {
3678
-        /** @var EE_Network_Core_Config $network_config */
3679
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3680
-        $messages_config = EE_Registry::instance()->CFG->messages;
3681
-        $form = $this->_generate_global_settings_form();
3682
-        if ($form->was_submitted()) {
3683
-            $form->receive_form_submission();
3684
-            if ($form->is_valid()) {
3685
-                $valid_data = $form->valid_data();
3686
-                foreach ($valid_data as $property => $value) {
3687
-                    $setter = 'set_' . $property;
3688
-                    if (method_exists($network_config, $setter)) {
3689
-                        $network_config->{$setter}($value);
3690
-                    } elseif (property_exists($network_config, $property)
3691
-                        && $network_config->{$property} !== $value
3692
-                    ) {
3693
-                        $network_config->{$property} = $value;
3694
-                    } elseif (property_exists($messages_config, $property)
3695
-                        && $messages_config->{$property} !== $value
3696
-                    ) {
3697
-                        $messages_config->{$property} = $value;
3698
-                    }
3699
-                }
3700
-                // only update if the form submission was valid!
3701
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3702
-                EE_Registry::instance()->CFG->update_espresso_config();
3703
-                EE_Error::overwrite_success();
3704
-                EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3705
-            }
3706
-        }
3707
-        $this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3708
-    }
3709
-
3710
-
3711
-    /**
3712
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3713
-     *
3714
-     * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3715
-     * @return string html formatted tabs
3716
-     * @throws DomainException
3717
-     */
3718
-    protected function _get_mt_tabs($tab_array)
3719
-    {
3720
-        $tab_array = (array) $tab_array;
3721
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3722
-        $tabs = '';
3723
-
3724
-        foreach ($tab_array as $tab) {
3725
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3726
-        }
3727
-
3728
-        return $tabs;
3729
-    }
3730
-
3731
-
3732
-    /**
3733
-     * This prepares the content of the messenger meta box admin settings
3734
-     *
3735
-     * @param  EE_messenger $messenger The messenger we're setting up content for
3736
-     * @return string html formatted content
3737
-     * @throws DomainException
3738
-     */
3739
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3740
-    {
3741
-
3742
-        $fields = $messenger->get_admin_settings_fields();
3743
-        $settings_template_args['template_form_fields'] = '';
3744
-
3745
-        // is $messenger active?
3746
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3747
-
3748
-
3749
-        if (! empty($fields)) {
3750
-            $existing_settings = $messenger->get_existing_admin_settings();
3751
-
3752
-            foreach ($fields as $fldname => $fldprops) {
3753
-                $field_id = $messenger->name . '-' . $fldname;
3754
-                $template_form_field[ $field_id ] = array(
3755
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3756
-                    'label'      => $fldprops['label'],
3757
-                    'input'      => $fldprops['field_type'],
3758
-                    'type'       => $fldprops['value_type'],
3759
-                    'required'   => $fldprops['required'],
3760
-                    'validation' => $fldprops['validation'],
3761
-                    'value'      => isset($existing_settings[ $field_id ])
3762
-                        ? $existing_settings[ $field_id ]
3763
-                        : $fldprops['default'],
3764
-                    'css_class'  => '',
3765
-                    'format'     => $fldprops['format'],
3766
-                );
3767
-            }
3768
-
3769
-
3770
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3771
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3772
-                : '';
3773
-        }
3774
-
3775
-        // we also need some hidden fields
3776
-        $settings_template_args['hidden_fields'] = array(
3777
-            'messenger_settings[messenger]' => array(
3778
-                'type'  => 'hidden',
3779
-                'value' => $messenger->name,
3780
-            ),
3781
-            'type'                          => array(
3782
-                'type'  => 'hidden',
3783
-                'value' => 'messenger',
3784
-            ),
3785
-        );
3786
-
3787
-        // make sure any active message types that are existing are included in the hidden fields
3788
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3789
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3790
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3791
-                    'type'  => 'hidden',
3792
-                    'value' => $mt,
3793
-                );
3794
-            }
3795
-        }
3796
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3797
-            $settings_template_args['hidden_fields'],
3798
-            'array'
3799
-        );
3800
-        $active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3801
-
3802
-        $settings_template_args['messenger'] = $messenger->name;
3803
-        $settings_template_args['description'] = $messenger->description;
3804
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3805
-
3806
-
3807
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3808
-            $messenger->name
3809
-        )
3810
-            ? $settings_template_args['show_hide_edit_form']
3811
-            : ' hidden';
3812
-
3813
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3814
-            ? ' hidden'
3815
-            : $settings_template_args['show_hide_edit_form'];
3816
-
3817
-
3818
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3819
-        $settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3820
-        $settings_template_args['on_off_status'] = $active ? true : false;
3821
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3822
-        $content = EEH_Template::display_template(
3823
-            $template,
3824
-            $settings_template_args,
3825
-            true
3826
-        );
3827
-
3828
-        return $content;
3829
-    }
3830
-
3831
-
3832
-    /**
3833
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3834
-     *
3835
-     * @throws DomainException
3836
-     * @throws EE_Error
3837
-     * @throws InvalidDataTypeException
3838
-     * @throws InvalidInterfaceException
3839
-     * @throws InvalidArgumentException
3840
-     * @throws ReflectionException
3841
-     */
3842
-    public function activate_messenger_toggle()
3843
-    {
3844
-        $success = true;
3845
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3846
-        // let's check that we have required data
3847
-        if (! isset($this->_req_data['messenger'])) {
3848
-            EE_Error::add_error(
3849
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3850
-                __FILE__,
3851
-                __FUNCTION__,
3852
-                __LINE__
3853
-            );
3854
-            $success = false;
3855
-        }
3856
-
3857
-        // do a nonce check here since we're not arriving via a normal route
3858
-        $nonce = isset($this->_req_data['activate_nonce'])
3859
-            ? sanitize_text_field($this->_req_data['activate_nonce'])
3860
-            : '';
3861
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3862
-
3863
-        $this->_verify_nonce($nonce, $nonce_ref);
3864
-
3865
-
3866
-        if (! isset($this->_req_data['status'])) {
3867
-            EE_Error::add_error(
3868
-                esc_html__(
3869
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3870
-                    'event_espresso'
3871
-                ),
3872
-                __FILE__,
3873
-                __FUNCTION__,
3874
-                __LINE__
3875
-            );
3876
-            $success = false;
3877
-        }
3878
-
3879
-        // do check to verify we have a valid status.
3880
-        $status = $this->_req_data['status'];
3881
-
3882
-        if ($status !== 'off' && $status !== 'on') {
3883
-            EE_Error::add_error(
3884
-                sprintf(
3885
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3886
-                    $this->_req_data['status']
3887
-                ),
3888
-                __FILE__,
3889
-                __FUNCTION__,
3890
-                __LINE__
3891
-            );
3892
-            $success = false;
3893
-        }
3894
-
3895
-        if ($success) {
3896
-            // made it here?  Stop dawdling then!!
3897
-            $success = $status === 'off'
3898
-                ? $this->_deactivate_messenger($this->_req_data['messenger'])
3899
-                : $this->_activate_messenger($this->_req_data['messenger']);
3900
-        }
3901
-
3902
-        $this->_template_args['success'] = $success;
3903
-
3904
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
3905
-        $this->_return_json();
3906
-    }
3907
-
3908
-
3909
-    /**
3910
-     * used by ajax from the messages settings page to activate|deactivate a message type
3911
-     *
3912
-     * @throws DomainException
3913
-     * @throws EE_Error
3914
-     * @throws ReflectionException
3915
-     * @throws InvalidDataTypeException
3916
-     * @throws InvalidInterfaceException
3917
-     * @throws InvalidArgumentException
3918
-     */
3919
-    public function activate_mt_toggle()
3920
-    {
3921
-        $success = true;
3922
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3923
-
3924
-        // let's make sure we have the necessary data
3925
-        if (! isset($this->_req_data['message_type'])) {
3926
-            EE_Error::add_error(
3927
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3928
-                __FILE__,
3929
-                __FUNCTION__,
3930
-                __LINE__
3931
-            );
3932
-            $success = false;
3933
-        }
3934
-
3935
-        if (! isset($this->_req_data['messenger'])) {
3936
-            EE_Error::add_error(
3937
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3938
-                __FILE__,
3939
-                __FUNCTION__,
3940
-                __LINE__
3941
-            );
3942
-            $success = false;
3943
-        }
3944
-
3945
-        if (! isset($this->_req_data['status'])) {
3946
-            EE_Error::add_error(
3947
-                esc_html__(
3948
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3949
-                    'event_espresso'
3950
-                ),
3951
-                __FILE__,
3952
-                __FUNCTION__,
3953
-                __LINE__
3954
-            );
3955
-            $success = false;
3956
-        }
3957
-
3958
-
3959
-        // do check to verify we have a valid status.
3960
-        $status = $this->_req_data['status'];
3961
-
3962
-        if ($status !== 'activate' && $status !== 'deactivate') {
3963
-            EE_Error::add_error(
3964
-                sprintf(
3965
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3966
-                    $this->_req_data['status']
3967
-                ),
3968
-                __FILE__,
3969
-                __FUNCTION__,
3970
-                __LINE__
3971
-            );
3972
-            $success = false;
3973
-        }
3974
-
3975
-
3976
-        // do a nonce check here since we're not arriving via a normal route
3977
-        $nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3978
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3979
-
3980
-        $this->_verify_nonce($nonce, $nonce_ref);
3981
-
3982
-        if ($success) {
3983
-            // made it here? um, what are you waiting for then?
3984
-            $success = $status === 'deactivate'
3985
-                ? $this->_deactivate_message_type_for_messenger(
3986
-                    $this->_req_data['messenger'],
3987
-                    $this->_req_data['message_type']
3988
-                )
3989
-                : $this->_activate_message_type_for_messenger(
3990
-                    $this->_req_data['messenger'],
3991
-                    $this->_req_data['message_type']
3992
-                );
3993
-        }
3994
-
3995
-        $this->_template_args['success'] = $success;
3996
-        $this->_return_json();
3997
-    }
3998
-
3999
-
4000
-    /**
4001
-     * Takes care of processing activating a messenger and preparing the appropriate response.
4002
-     *
4003
-     * @param string $messenger_name The name of the messenger being activated
4004
-     * @return bool
4005
-     * @throws DomainException
4006
-     * @throws EE_Error
4007
-     * @throws InvalidArgumentException
4008
-     * @throws ReflectionException
4009
-     * @throws InvalidDataTypeException
4010
-     * @throws InvalidInterfaceException
4011
-     */
4012
-    protected function _activate_messenger($messenger_name)
4013
-    {
4014
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4015
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4016
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
4017
-            ? $active_messenger->get_default_message_types()
4018
-            : array();
4019
-
4020
-        // ensure is active
4021
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4022
-
4023
-        // set response_data for reload
4024
-        foreach ($message_types_to_activate as $message_type_name) {
4025
-            /** @var EE_message_type $message_type */
4026
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4027
-            if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4028
-                $messenger_name,
4029
-                $message_type_name
4030
-            )
4031
-                && $message_type instanceof EE_message_type
4032
-            ) {
4033
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
4034
-                if ($message_type->get_admin_settings_fields()) {
4035
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
4036
-                }
4037
-            }
4038
-        }
4039
-
4040
-        // add success message for activating messenger
4041
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4042
-    }
4043
-
4044
-
4045
-    /**
4046
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
4047
-     *
4048
-     * @param string $messenger_name The name of the messenger being activated
4049
-     * @return bool
4050
-     * @throws DomainException
4051
-     * @throws EE_Error
4052
-     * @throws InvalidArgumentException
4053
-     * @throws ReflectionException
4054
-     * @throws InvalidDataTypeException
4055
-     * @throws InvalidInterfaceException
4056
-     */
4057
-    protected function _deactivate_messenger($messenger_name)
4058
-    {
4059
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4060
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4061
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
4062
-
4063
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4064
-    }
4065
-
4066
-
4067
-    /**
4068
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4069
-     *
4070
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
4071
-     * @param string $message_type_name The name of the message type being activated for the messenger
4072
-     * @return bool
4073
-     * @throws DomainException
4074
-     * @throws EE_Error
4075
-     * @throws InvalidArgumentException
4076
-     * @throws ReflectionException
4077
-     * @throws InvalidDataTypeException
4078
-     * @throws InvalidInterfaceException
4079
-     */
4080
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4081
-    {
4082
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4083
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4084
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4085
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4086
-
4087
-        // ensure is active
4088
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4089
-
4090
-        // set response for load
4091
-        if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4092
-            $messenger_name,
4093
-            $message_type_name
4094
-        )
4095
-        ) {
4096
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
4097
-            if ($message_type_to_activate->get_admin_settings_fields()) {
4098
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
4099
-            }
4100
-        }
4101
-
4102
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
4103
-            $active_messenger,
4104
-            $message_type_to_activate
4105
-        );
4106
-    }
4107
-
4108
-
4109
-    /**
4110
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4111
-     *
4112
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4113
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
4114
-     * @return bool
4115
-     * @throws DomainException
4116
-     * @throws EE_Error
4117
-     * @throws InvalidArgumentException
4118
-     * @throws ReflectionException
4119
-     * @throws InvalidDataTypeException
4120
-     * @throws InvalidInterfaceException
4121
-     */
4122
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4123
-    {
4124
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4125
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4126
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4127
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4128
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4129
-
4130
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4131
-            $active_messenger,
4132
-            $message_type_to_deactivate
4133
-        );
4134
-    }
4135
-
4136
-
4137
-    /**
4138
-     * This just initializes the defaults for activating messenger and message type responses.
4139
-     */
4140
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
4141
-    {
4142
-        $this->_template_args['data']['active_mts'] = array();
4143
-        $this->_template_args['data']['mt_reload'] = array();
4144
-    }
4145
-
4146
-
4147
-    /**
4148
-     * Setup appropriate response for activating a messenger and/or message types
4149
-     *
4150
-     * @param EE_messenger         $messenger
4151
-     * @param EE_message_type|null $message_type
4152
-     * @return bool
4153
-     * @throws DomainException
4154
-     * @throws EE_Error
4155
-     * @throws InvalidArgumentException
4156
-     * @throws ReflectionException
4157
-     * @throws InvalidDataTypeException
4158
-     * @throws InvalidInterfaceException
4159
-     */
4160
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
4161
-        $messenger,
4162
-        EE_Message_Type $message_type = null
4163
-    ) {
4164
-        // if $messenger isn't a valid messenger object then get out.
4165
-        if (! $messenger instanceof EE_Messenger) {
4166
-            EE_Error::add_error(
4167
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4168
-                __FILE__,
4169
-                __FUNCTION__,
4170
-                __LINE__
4171
-            );
4172
-
4173
-            return false;
4174
-        }
4175
-        // activated
4176
-        if ($this->_template_args['data']['active_mts']) {
4177
-            EE_Error::overwrite_success();
4178
-            // activated a message type with the messenger
4179
-            if ($message_type instanceof EE_message_type) {
4180
-                EE_Error::add_success(
4181
-                    sprintf(
4182
-                        esc_html__(
4183
-                            '%s message type has been successfully activated with the %s messenger',
4184
-                            'event_espresso'
4185
-                        ),
4186
-                        ucwords($message_type->label['singular']),
4187
-                        ucwords($messenger->label['singular'])
4188
-                    )
4189
-                );
4190
-
4191
-                // if message type was invoice then let's make sure we activate the invoice payment method.
4192
-                if ($message_type->name === 'invoice') {
4193
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
4194
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4195
-                    if ($pm instanceof EE_Payment_Method) {
4196
-                        EE_Error::add_attention(
4197
-                            esc_html__(
4198
-                                '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.',
4199
-                                'event_espresso'
4200
-                            )
4201
-                        );
4202
-                    }
4203
-                }
4204
-                // just toggles the entire messenger
4205
-            } else {
4206
-                EE_Error::add_success(
4207
-                    sprintf(
4208
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4209
-                        ucwords($messenger->label['singular'])
4210
-                    )
4211
-                );
4212
-            }
4213
-
4214
-            return true;
4215
-
4216
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4217
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4218
-            // in which case we just give a success message for the messenger being successfully activated.
4219
-        } else {
4220
-            if (! $messenger->get_default_message_types()) {
4221
-                // messenger doesn't have any default message types so still a success.
4222
-                EE_Error::add_success(
4223
-                    sprintf(
4224
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4225
-                        ucwords($messenger->label['singular'])
4226
-                    )
4227
-                );
4228
-
4229
-                return true;
4230
-            } else {
4231
-                EE_Error::add_error(
4232
-                    $message_type instanceof EE_message_type
4233
-                        ? sprintf(
4234
-                            esc_html__(
4235
-                                '%s message type was not successfully activated with the %s messenger',
4236
-                                'event_espresso'
4237
-                            ),
4238
-                            ucwords($message_type->label['singular']),
4239
-                            ucwords($messenger->label['singular'])
4240
-                        )
4241
-                        : sprintf(
4242
-                            esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4243
-                            ucwords($messenger->label['singular'])
4244
-                        ),
4245
-                    __FILE__,
4246
-                    __FUNCTION__,
4247
-                    __LINE__
4248
-                );
4249
-
4250
-                return false;
4251
-            }
4252
-        }
4253
-    }
4254
-
4255
-
4256
-    /**
4257
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
4258
-     *
4259
-     * @param EE_messenger         $messenger
4260
-     * @param EE_message_type|null $message_type
4261
-     * @return bool
4262
-     * @throws DomainException
4263
-     * @throws EE_Error
4264
-     * @throws InvalidArgumentException
4265
-     * @throws ReflectionException
4266
-     * @throws InvalidDataTypeException
4267
-     * @throws InvalidInterfaceException
4268
-     */
4269
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4270
-        $messenger,
4271
-        EE_message_type $message_type = null
4272
-    ) {
4273
-        EE_Error::overwrite_success();
4274
-
4275
-        // if $messenger isn't a valid messenger object then get out.
4276
-        if (! $messenger instanceof EE_Messenger) {
4277
-            EE_Error::add_error(
4278
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4279
-                __FILE__,
4280
-                __FUNCTION__,
4281
-                __LINE__
4282
-            );
4283
-
4284
-            return false;
4285
-        }
4286
-
4287
-        if ($message_type instanceof EE_message_type) {
4288
-            $message_type_name = $message_type->name;
4289
-            EE_Error::add_success(
4290
-                sprintf(
4291
-                    esc_html__(
4292
-                        '%s message type has been successfully deactivated for the %s messenger.',
4293
-                        'event_espresso'
4294
-                    ),
4295
-                    ucwords($message_type->label['singular']),
4296
-                    ucwords($messenger->label['singular'])
4297
-                )
4298
-            );
4299
-        } else {
4300
-            $message_type_name = '';
4301
-            EE_Error::add_success(
4302
-                sprintf(
4303
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4304
-                    ucwords($messenger->label['singular'])
4305
-                )
4306
-            );
4307
-        }
4308
-
4309
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4310
-        if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4311
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
4312
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4313
-            if ($count_updated > 0) {
4314
-                $msg = $message_type_name === 'invoice'
4315
-                    ? esc_html__(
4316
-                        '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.',
4317
-                        'event_espresso'
4318
-                    )
4319
-                    : esc_html__(
4320
-                        '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.',
4321
-                        'event_espresso'
4322
-                    );
4323
-                EE_Error::add_attention($msg);
4324
-            }
4325
-        }
4326
-
4327
-        return true;
4328
-    }
4329
-
4330
-
4331
-    /**
4332
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4333
-     *
4334
-     * @throws DomainException
4335
-     */
4336
-    public function update_mt_form()
4337
-    {
4338
-        if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4339
-            EE_Error::add_error(
4340
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4341
-                __FILE__,
4342
-                __FUNCTION__,
4343
-                __LINE__
4344
-            );
4345
-            $this->_return_json();
4346
-        }
4347
-
4348
-        $message_types = $this->get_installed_message_types();
4349
-
4350
-        $message_type = $message_types[ $this->_req_data['message_type'] ];
4351
-        $messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4352
-
4353
-        $content = $this->_message_type_settings_content(
4354
-            $message_type,
4355
-            $messenger,
4356
-            true
4357
-        );
4358
-        $this->_template_args['success'] = true;
4359
-        $this->_template_args['content'] = $content;
4360
-        $this->_return_json();
4361
-    }
4362
-
4363
-
4364
-    /**
4365
-     * this handles saving the settings for a messenger or message type
4366
-     *
4367
-     */
4368
-    public function save_settings()
4369
-    {
4370
-        if (! isset($this->_req_data['type'])) {
4371
-            EE_Error::add_error(
4372
-                esc_html__(
4373
-                    'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4374
-                    'event_espresso'
4375
-                ),
4376
-                __FILE__,
4377
-                __FUNCTION__,
4378
-                __LINE__
4379
-            );
4380
-            $this->_template_args['error'] = true;
4381
-            $this->_return_json();
4382
-        }
4383
-
4384
-
4385
-        if ($this->_req_data['type'] === 'messenger') {
4386
-            // this should be an array.
4387
-            $settings = $this->_req_data['messenger_settings'];
4388
-            $messenger = $settings['messenger'];
4389
-            // let's setup the settings data
4390
-            foreach ($settings as $key => $value) {
4391
-                switch ($key) {
4392
-                    case 'messenger':
4393
-                        unset($settings['messenger']);
4394
-                        break;
4395
-                    case 'message_types':
4396
-                        unset($settings['message_types']);
4397
-                        break;
4398
-                    default:
4399
-                        $settings[ $key ] = $value;
4400
-                        break;
4401
-                }
4402
-            }
4403
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4404
-        } elseif ($this->_req_data['type'] === 'message_type') {
4405
-            $settings = $this->_req_data['message_type_settings'];
4406
-            $messenger = $settings['messenger'];
4407
-            $message_type = $settings['message_type'];
4408
-
4409
-            foreach ($settings as $key => $value) {
4410
-                switch ($key) {
4411
-                    case 'messenger':
4412
-                        unset($settings['messenger']);
4413
-                        break;
4414
-                    case 'message_type':
4415
-                        unset($settings['message_type']);
4416
-                        break;
4417
-                    default:
4418
-                        $settings[ $key ] = $value;
4419
-                        break;
4420
-                }
4421
-            }
4422
-
4423
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4424
-        }
4425
-
4426
-        // okay we should have the data all setup.  Now we just update!
4427
-        $success = $this->_message_resource_manager->update_active_messengers_option();
4428
-
4429
-        if ($success) {
4430
-            EE_Error::add_success(__('Settings updated', 'event_espresso'));
4431
-        } else {
4432
-            EE_Error::add_error(
4433
-                esc_html__(
4434
-                    'Settings did not get updated',
4435
-                    'event_espresso'
4436
-                ),
4437
-                __FILE__,
4438
-                __FUNCTION__,
4439
-                __LINE__
4440
-            );
4441
-        }
4442
-
4443
-        $this->_template_args['success'] = $success;
4444
-        $this->_return_json();
4445
-    }
4446
-
4447
-
4448
-
4449
-
4450
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4451
-
4452
-
4453
-    /**
4454
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4455
-     * However, this does not send immediately, it just queues for sending.
4456
-     *
4457
-     * @since 4.9.0
4458
-     * @throws EE_Error
4459
-     * @throws InvalidDataTypeException
4460
-     * @throws InvalidInterfaceException
4461
-     * @throws InvalidArgumentException
4462
-     * @throws ReflectionException
4463
-     */
4464
-    protected function _generate_now()
4465
-    {
4466
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4467
-        $this->_redirect_after_action(false, '', '', array(), true);
4468
-    }
4469
-
4470
-
4471
-    /**
4472
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4473
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4474
-     *
4475
-     * @since 4.9.0
4476
-     * @throws EE_Error
4477
-     * @throws InvalidDataTypeException
4478
-     * @throws InvalidInterfaceException
4479
-     * @throws InvalidArgumentException
4480
-     * @throws ReflectionException
4481
-     */
4482
-    protected function _generate_and_send_now()
4483
-    {
4484
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4485
-        $this->_redirect_after_action(false, '', '', array(), true);
4486
-    }
4487
-
4488
-
4489
-    /**
4490
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4491
-     *
4492
-     * @since 4.9.0
4493
-     * @throws EE_Error
4494
-     * @throws InvalidDataTypeException
4495
-     * @throws InvalidInterfaceException
4496
-     * @throws InvalidArgumentException
4497
-     * @throws ReflectionException
4498
-     */
4499
-    protected function _queue_for_resending()
4500
-    {
4501
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4502
-        $this->_redirect_after_action(false, '', '', array(), true);
4503
-    }
4504
-
4505
-
4506
-    /**
4507
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4508
-     *
4509
-     * @since 4.9.0
4510
-     * @throws EE_Error
4511
-     * @throws InvalidDataTypeException
4512
-     * @throws InvalidInterfaceException
4513
-     * @throws InvalidArgumentException
4514
-     * @throws ReflectionException
4515
-     */
4516
-    protected function _send_now()
4517
-    {
4518
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4519
-        $this->_redirect_after_action(false, '', '', array(), true);
4520
-    }
4521
-
4522
-
4523
-    /**
4524
-     * Deletes EE_messages for IDs in the request.
4525
-     *
4526
-     * @since 4.9.0
4527
-     * @throws EE_Error
4528
-     * @throws InvalidDataTypeException
4529
-     * @throws InvalidInterfaceException
4530
-     * @throws InvalidArgumentException
4531
-     */
4532
-    protected function _delete_ee_messages()
4533
-    {
4534
-        $msg_ids = $this->_get_msg_ids_from_request();
4535
-        $deleted_count = 0;
4536
-        foreach ($msg_ids as $msg_id) {
4537
-            if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4538
-                $deleted_count++;
4539
-            }
4540
-        }
4541
-        if ($deleted_count) {
4542
-            EE_Error::add_success(
4543
-                esc_html(
4544
-                    _n(
4545
-                        'Message successfully deleted',
4546
-                        'Messages successfully deleted',
4547
-                        $deleted_count,
4548
-                        'event_espresso'
4549
-                    )
4550
-                )
4551
-            );
4552
-            $this->_redirect_after_action(
4553
-                false,
4554
-                '',
4555
-                '',
4556
-                array(),
4557
-                true
4558
-            );
4559
-        } else {
4560
-            EE_Error::add_error(
4561
-                _n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4562
-                __FILE__,
4563
-                __FUNCTION__,
4564
-                __LINE__
4565
-            );
4566
-            $this->_redirect_after_action(false, '', '', array(), true);
4567
-        }
4568
-    }
4569
-
4570
-
4571
-    /**
4572
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4573
-     *
4574
-     * @since 4.9.0
4575
-     * @return array
4576
-     */
4577
-    protected function _get_msg_ids_from_request()
4578
-    {
4579
-        if (! isset($this->_req_data['MSG_ID'])) {
4580
-            return array();
4581
-        }
4582
-
4583
-        return is_array($this->_req_data['MSG_ID'])
4584
-            ? array_keys($this->_req_data['MSG_ID'])
4585
-            : array($this->_req_data['MSG_ID']);
4586
-    }
2666
+		$output = ob_get_contents();
2667
+		ob_clean();
2668
+		$this->_context_switcher = $output;
2669
+	}
2670
+
2671
+
2672
+	/**
2673
+	 * utility for sanitizing new values coming in.
2674
+	 * Note: this is only used when updating a context.
2675
+	 *
2676
+	 * @access protected
2677
+	 *
2678
+	 * @param int $index This helps us know which template field to select from the request array.
2679
+	 *
2680
+	 * @return array
2681
+	 */
2682
+	protected function _set_message_template_column_values($index)
2683
+	{
2684
+		if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2685
+			foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2686
+				$this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2687
+			}
2688
+		}
2689
+
2690
+
2691
+		$set_column_values = array(
2692
+			'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2693
+			'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2694
+			'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2695
+			'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2696
+			'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2697
+			'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2698
+			'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2699
+			'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2700
+			'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2701
+				? absint($this->_req_data['MTP_is_global'])
2702
+				: 0,
2703
+			'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2704
+				? absint($this->_req_data['MTP_is_override'])
2705
+				: 0,
2706
+			'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2707
+			'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2708
+		);
2709
+
2710
+
2711
+		return $set_column_values;
2712
+	}
2713
+
2714
+
2715
+	protected function _insert_or_update_message_template($new = false)
2716
+	{
2717
+
2718
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2719
+		$success = 0;
2720
+		$override = false;
2721
+
2722
+		// setup notices description
2723
+		$messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2724
+
2725
+		// need the message type and messenger objects to be able to use the labels for the notices
2726
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2727
+		$messenger_label = $messenger_object instanceof EE_messenger
2728
+			? ucwords($messenger_object->label['singular'])
2729
+			: '';
2730
+
2731
+		$message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2732
+			? $this->_req_data['MTP_message_type']
2733
+			: '';
2734
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2735
+
2736
+		$message_type_label = $message_type_object instanceof EE_message_type
2737
+			? ucwords($message_type_object->label['singular'])
2738
+			: '';
2739
+
2740
+		$context_slug = ! empty($this->_req_data['MTP_context'])
2741
+			? $this->_req_data['MTP_context']
2742
+			: '';
2743
+		$context = ucwords(str_replace('_', ' ', $context_slug));
2744
+
2745
+		$item_desc = $messenger_label && $message_type_label
2746
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2747
+			: '';
2748
+		$item_desc .= 'Message Template';
2749
+		$query_args = array();
2750
+		$edit_array = array();
2751
+		$action_desc = '';
2752
+
2753
+		// if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2754
+		// user to edit.
2755
+		if ($new) {
2756
+			$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2757
+			if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2758
+				if (empty($edit_array)) {
2759
+					$success = 0;
2760
+				} else {
2761
+					$success = 1;
2762
+					$edit_array = $edit_array[0];
2763
+					$query_args = array(
2764
+						'id'      => $edit_array['GRP_ID'],
2765
+						'context' => $edit_array['MTP_context'],
2766
+						'action'  => 'edit_message_template',
2767
+					);
2768
+				}
2769
+			}
2770
+			$action_desc = 'created';
2771
+		} else {
2772
+			$MTPG = EEM_Message_Template_Group::instance();
2773
+			$MTP = EEM_Message_Template::instance();
2774
+
2775
+
2776
+			// run update for each template field in displayed context
2777
+			if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2778
+				EE_Error::add_error(
2779
+					esc_html__(
2780
+						'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2781
+						'event_espresso'
2782
+					),
2783
+					__FILE__,
2784
+					__FUNCTION__,
2785
+					__LINE__
2786
+				);
2787
+				$success = 0;
2788
+			} else {
2789
+				// first validate all fields!
2790
+				// this filter allows client code to add its own validation to the template fields as well.
2791
+				// returning an empty array means everything passed validation.
2792
+				// errors in validation should be represented in an array with the following shape:
2793
+				// array(
2794
+				//   'fieldname' => array(
2795
+				//          'msg' => 'error message'
2796
+				//          'value' => 'value for field producing error'
2797
+				// )
2798
+				$custom_validation = (array) apply_filters(
2799
+					'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2800
+					array(),
2801
+					$this->_req_data['MTP_template_fields'],
2802
+					$context_slug,
2803
+					$messenger_slug,
2804
+					$message_type_slug
2805
+				);
2806
+
2807
+				$system_validation = $MTPG->validate(
2808
+					$this->_req_data['MTP_template_fields'],
2809
+					$context_slug,
2810
+					$messenger_slug,
2811
+					$message_type_slug
2812
+				);
2813
+
2814
+				$system_validation = ! is_array($system_validation) && $system_validation ? array()
2815
+					: $system_validation;
2816
+				$validates = array_merge($custom_validation, $system_validation);
2817
+
2818
+				// if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2819
+				// appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2820
+				//  WE need to make sure there is no actual error messages in validates.
2821
+				if (is_array($validates) && ! empty($validates)) {
2822
+					// add the transient so when the form loads we know which fields to highlight
2823
+					$this->_add_transient('edit_message_template', $validates);
2824
+
2825
+					$success = 0;
2826
+
2827
+					// setup notices
2828
+					foreach ($validates as $field => $error) {
2829
+						if (isset($error['msg'])) {
2830
+							EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2831
+						}
2832
+					}
2833
+				} else {
2834
+					$set_column_values = array();
2835
+					foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2836
+						$set_column_values = $this->_set_message_template_column_values($template_field);
2837
+
2838
+						$where_cols_n_values = array(
2839
+							'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2840
+						);
2841
+						// if they aren't allowed to use all JS, restrict them to just posty-y tags
2842
+						if (! current_user_can('unfiltered_html')) {
2843
+							if (is_array($set_column_values['MTP_content'])) {
2844
+								foreach ($set_column_values['MTP_content'] as $key => $value) {
2845
+									// remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2846
+									// only removes slashes from double-quotes, so attributes using single quotes always
2847
+									// appear invalid.) But currently the models expect slashed data, so after wp_kses
2848
+									// runs we need to re-slash the data. Sheesh. See
2849
+									// https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2850
+									$set_column_values['MTP_content'][ $key ] = addslashes(
2851
+										wp_kses(
2852
+											stripslashes($value),
2853
+											wp_kses_allowed_html('post')
2854
+										)
2855
+									);
2856
+								}
2857
+							} else {
2858
+								$set_column_values['MTP_content'] = wp_kses(
2859
+									$set_column_values['MTP_content'],
2860
+									wp_kses_allowed_html('post')
2861
+								);
2862
+							}
2863
+						}
2864
+						$message_template_fields = array(
2865
+							'GRP_ID'             => $set_column_values['GRP_ID'],
2866
+							'MTP_template_field' => $set_column_values['MTP_template_field'],
2867
+							'MTP_context'        => $set_column_values['MTP_context'],
2868
+							'MTP_content'        => $set_column_values['MTP_content'],
2869
+						);
2870
+						if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2871
+							if ($updated === false) {
2872
+								EE_Error::add_error(
2873
+									sprintf(
2874
+										esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2875
+										$template_field
2876
+									),
2877
+									__FILE__,
2878
+									__FUNCTION__,
2879
+									__LINE__
2880
+								);
2881
+							} else {
2882
+								$success = 1;
2883
+							}
2884
+						} else {
2885
+							// only do this logic if we don't have a MTP_ID for this field
2886
+							if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2887
+								// this has already been through the template field validator and sanitized, so it will be
2888
+								// safe to insert this field.  Why insert?  This typically happens when we introduce a new
2889
+								// message template field in a messenger/message type and existing users don't have the
2890
+								// default setup for it.
2891
+								// @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2892
+								$updated = $MTP->insert($message_template_fields);
2893
+								if (! $updated || is_wp_error($updated)) {
2894
+									EE_Error::add_error(
2895
+										sprintf(
2896
+											esc_html__('%s field could not be updated.', 'event_espresso'),
2897
+											$template_field
2898
+										),
2899
+										__FILE__,
2900
+										__FUNCTION__,
2901
+										__LINE__
2902
+									);
2903
+									$success = 0;
2904
+								} else {
2905
+									$success = 1;
2906
+								}
2907
+							}
2908
+						}
2909
+						$action_desc = 'updated';
2910
+					}
2911
+
2912
+					// we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2913
+					$mtpg_fields = array(
2914
+						'MTP_user_id'      => $set_column_values['MTP_user_id'],
2915
+						'MTP_messenger'    => $set_column_values['MTP_messenger'],
2916
+						'MTP_message_type' => $set_column_values['MTP_message_type'],
2917
+						'MTP_is_global'    => $set_column_values['MTP_is_global'],
2918
+						'MTP_is_override'  => $set_column_values['MTP_is_override'],
2919
+						'MTP_deleted'      => $set_column_values['MTP_deleted'],
2920
+						'MTP_is_active'    => $set_column_values['MTP_is_active'],
2921
+						'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2922
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2923
+							: '',
2924
+						'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2925
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2926
+							: '',
2927
+					);
2928
+
2929
+					$mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2930
+					$updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2931
+
2932
+					if ($updated === false) {
2933
+						EE_Error::add_error(
2934
+							sprintf(
2935
+								esc_html__(
2936
+									'The Message Template Group (%d) was NOT updated for some reason',
2937
+									'event_espresso'
2938
+								),
2939
+								$set_column_values['GRP_ID']
2940
+							),
2941
+							__FILE__,
2942
+							__FUNCTION__,
2943
+							__LINE__
2944
+						);
2945
+					} else {
2946
+						// k now we need to ensure the template_pack and template_variation fields are set.
2947
+						$template_pack = ! empty($this->_req_data['MTP_template_pack'])
2948
+							? $this->_req_data['MTP_template_pack']
2949
+							: 'default';
2950
+
2951
+						$template_variation = ! empty($this->_req_data['MTP_template_variation'])
2952
+							? $this->_req_data['MTP_template_variation']
2953
+							: 'default';
2954
+
2955
+						$mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2956
+						if ($mtpg_obj instanceof EE_Message_Template_Group) {
2957
+							$mtpg_obj->set_template_pack_name($template_pack);
2958
+							$mtpg_obj->set_template_pack_variation($template_variation);
2959
+						}
2960
+						$success = 1;
2961
+					}
2962
+				}
2963
+			}
2964
+		}
2965
+
2966
+		// we return things differently if doing ajax
2967
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2968
+			$this->_template_args['success'] = $success;
2969
+			$this->_template_args['error'] = ! $success ? true : false;
2970
+			$this->_template_args['content'] = '';
2971
+			$this->_template_args['data'] = array(
2972
+				'grpID'        => $edit_array['GRP_ID'],
2973
+				'templateName' => $edit_array['template_name'],
2974
+			);
2975
+			if ($success) {
2976
+				EE_Error::overwrite_success();
2977
+				EE_Error::add_success(
2978
+					esc_html__(
2979
+						'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.',
2980
+						'event_espresso'
2981
+					)
2982
+				);
2983
+			}
2984
+
2985
+			$this->_return_json();
2986
+		}
2987
+
2988
+
2989
+		// was a test send triggered?
2990
+		if (isset($this->_req_data['test_button'])) {
2991
+			EE_Error::overwrite_success();
2992
+			$this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2993
+			$override = true;
2994
+		}
2995
+
2996
+		if (empty($query_args)) {
2997
+			$query_args = array(
2998
+				'id'      => $this->_req_data['GRP_ID'],
2999
+				'context' => $context_slug,
3000
+				'action'  => 'edit_message_template',
3001
+			);
3002
+		}
3003
+
3004
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3005
+	}
3006
+
3007
+
3008
+	/**
3009
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
3010
+	 *
3011
+	 * @param  string $context      what context being tested
3012
+	 * @param  string $messenger    messenger being tested
3013
+	 * @param  string $message_type message type being tested
3014
+	 * @throws EE_Error
3015
+	 * @throws InvalidArgumentException
3016
+	 * @throws InvalidDataTypeException
3017
+	 * @throws InvalidInterfaceException
3018
+	 */
3019
+	protected function _do_test_send($context, $messenger, $message_type)
3020
+	{
3021
+		// set things up for preview
3022
+		$this->_req_data['messenger'] = $messenger;
3023
+		$this->_req_data['message_type'] = $message_type;
3024
+		$this->_req_data['context'] = $context;
3025
+		$this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3026
+		$active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3027
+
3028
+		// let's save any existing fields that might be required by the messenger
3029
+		if (isset($this->_req_data['test_settings_fld'])
3030
+			&& $active_messenger instanceof EE_messenger
3031
+			&& apply_filters(
3032
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3033
+				true,
3034
+				$this->_req_data['test_settings_fld'],
3035
+				$active_messenger
3036
+			)
3037
+		) {
3038
+			$active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3039
+		}
3040
+
3041
+		/**
3042
+		 * Use filter to add additional controls on whether message can send or not
3043
+		 */
3044
+		if (apply_filters(
3045
+			'FHEE__Messages_Admin_Page__do_test_send__can_send',
3046
+			true,
3047
+			$context,
3048
+			$this->_req_data,
3049
+			$messenger,
3050
+			$message_type
3051
+		)) {
3052
+			if (EEM_Event::instance()->count() > 0) {
3053
+				$success = $this->_preview_message(true);
3054
+				if ($success) {
3055
+					EE_Error::add_success(__('Test message sent', 'event_espresso'));
3056
+				} else {
3057
+					EE_Error::add_error(
3058
+						esc_html__('The test message was not sent', 'event_espresso'),
3059
+						__FILE__,
3060
+						__FUNCTION__,
3061
+						__LINE__
3062
+					);
3063
+				}
3064
+			} else {
3065
+				$this->noEventsErrorMessage(true);
3066
+			}
3067
+		}
3068
+	}
3069
+
3070
+
3071
+	/**
3072
+	 * _generate_new_templates
3073
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3074
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3075
+	 * for the event.
3076
+	 *
3077
+	 *
3078
+	 * @param  string $messenger     the messenger we are generating templates for
3079
+	 * @param array   $message_types array of message types that the templates are generated for.
3080
+	 * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3081
+	 *                               indicate the message_template_group being used as the base.
3082
+	 *
3083
+	 * @param bool    $global
3084
+	 *
3085
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
3086
+	 *                               encountering problems.
3087
+	 * @throws EE_Error
3088
+	 */
3089
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3090
+	{
3091
+
3092
+		// if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3093
+		// just don't generate any templates.
3094
+		if (empty($message_types)) {
3095
+			return true;
3096
+		}
3097
+
3098
+		return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3099
+	}
3100
+
3101
+
3102
+	/**
3103
+	 * [_trash_or_restore_message_template]
3104
+	 *
3105
+	 * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3106
+	 * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3107
+	 *                        an individual context (FALSE).
3108
+	 * @return void
3109
+	 * @throws EE_Error
3110
+	 * @throws InvalidArgumentException
3111
+	 * @throws InvalidDataTypeException
3112
+	 * @throws InvalidInterfaceException
3113
+	 */
3114
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
3115
+	{
3116
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3117
+		$MTP = EEM_Message_Template_Group::instance();
3118
+
3119
+		$success = 1;
3120
+
3121
+		// incoming GRP_IDs
3122
+		if ($all) {
3123
+			// Checkboxes
3124
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3125
+				// if array has more than one element then success message should be plural.
3126
+				// todo: what about nonce?
3127
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3128
+
3129
+				// cycle through checkboxes
3130
+				while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3131
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3132
+					if (! $trashed_or_restored) {
3133
+						$success = 0;
3134
+					}
3135
+				}
3136
+			} else {
3137
+				// grab single GRP_ID and handle
3138
+				$GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3139
+				if (! empty($GRP_ID)) {
3140
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3141
+					if (! $trashed_or_restored) {
3142
+						$success = 0;
3143
+					}
3144
+				} else {
3145
+					$success = 0;
3146
+				}
3147
+			}
3148
+		}
3149
+
3150
+		$action_desc = $trash
3151
+			? esc_html__('moved to the trash', 'event_espresso')
3152
+			: esc_html__('restored', 'event_espresso');
3153
+
3154
+		$action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3155
+
3156
+		$item_desc = $all ? _n(
3157
+			'Message Template Group',
3158
+			'Message Template Groups',
3159
+			$success,
3160
+			'event_espresso'
3161
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3162
+
3163
+		$item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3164
+			'template',
3165
+			'templates',
3166
+			$success,
3167
+			'event_espresso'
3168
+		) : $item_desc;
3169
+
3170
+		$this->_redirect_after_action($success, $item_desc, $action_desc, array());
3171
+	}
3172
+
3173
+
3174
+	/**
3175
+	 * [_delete_message_template]
3176
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3177
+	 *
3178
+	 * @return void
3179
+	 * @throws EE_Error
3180
+	 * @throws InvalidArgumentException
3181
+	 * @throws InvalidDataTypeException
3182
+	 * @throws InvalidInterfaceException
3183
+	 */
3184
+	protected function _delete_message_template()
3185
+	{
3186
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3187
+
3188
+		// checkboxes
3189
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3190
+			// if array has more than one element then success message should be plural
3191
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3192
+
3193
+			// cycle through bulk action checkboxes
3194
+			while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3195
+				$success = $this->_delete_mtp_permanently($GRP_ID);
3196
+			}
3197
+		} else {
3198
+			// grab single grp_id and delete
3199
+			$GRP_ID = absint($this->_req_data['id']);
3200
+			$success = $this->_delete_mtp_permanently($GRP_ID);
3201
+		}
3202
+
3203
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3204
+	}
3205
+
3206
+
3207
+	/**
3208
+	 * helper for permanently deleting a mtP group and all related message_templates
3209
+	 *
3210
+	 * @param  int  $GRP_ID        The group being deleted
3211
+	 * @param  bool $include_group whether to delete the Message Template Group as well.
3212
+	 * @return bool boolean to indicate the success of the deletes or not.
3213
+	 * @throws EE_Error
3214
+	 * @throws InvalidArgumentException
3215
+	 * @throws InvalidDataTypeException
3216
+	 * @throws InvalidInterfaceException
3217
+	 */
3218
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3219
+	{
3220
+		$success = 1;
3221
+		$MTPG = EEM_Message_Template_Group::instance();
3222
+		// first let's GET this group
3223
+		$MTG = $MTPG->get_one_by_ID($GRP_ID);
3224
+		// then delete permanently all the related Message Templates
3225
+		$deleted = $MTG->delete_related_permanently('Message_Template');
3226
+
3227
+		if ($deleted === 0) {
3228
+			$success = 0;
3229
+		}
3230
+
3231
+		// now delete permanently this particular group
3232
+
3233
+		if ($include_group && ! $MTG->delete_permanently()) {
3234
+			$success = 0;
3235
+		}
3236
+
3237
+		return $success;
3238
+	}
3239
+
3240
+
3241
+	/**
3242
+	 *    _learn_more_about_message_templates_link
3243
+	 *
3244
+	 * @access protected
3245
+	 * @return string
3246
+	 */
3247
+	protected function _learn_more_about_message_templates_link()
3248
+	{
3249
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3250
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
3251
+			   . '</a>';
3252
+	}
3253
+
3254
+
3255
+	/**
3256
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3257
+	 * ajax and other routes.
3258
+	 *
3259
+	 * @return void
3260
+	 * @throws DomainException
3261
+	 */
3262
+	protected function _settings()
3263
+	{
3264
+
3265
+
3266
+		$this->_set_m_mt_settings();
3267
+
3268
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3269
+			? $this->_req_data['selected_messenger']
3270
+			: 'email';
3271
+
3272
+		// let's setup the messenger tabs
3273
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3274
+			$this->_m_mt_settings['messenger_tabs'],
3275
+			'messenger_links',
3276
+			'|',
3277
+			$selected_messenger
3278
+		);
3279
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3280
+		$this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3281
+
3282
+		$this->display_admin_page_with_sidebar();
3283
+	}
3284
+
3285
+
3286
+	/**
3287
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3288
+	 *
3289
+	 * @access protected
3290
+	 * @return void
3291
+	 * @throws DomainException
3292
+	 */
3293
+	protected function _set_m_mt_settings()
3294
+	{
3295
+		// first if this is already set then lets get out no need to regenerate data.
3296
+		if (! empty($this->_m_mt_settings)) {
3297
+			return;
3298
+		}
3299
+
3300
+		// get all installed messengers and message_types
3301
+		/** @type EE_messenger[] $messengers */
3302
+		$messengers = $this->_message_resource_manager->installed_messengers();
3303
+		/** @type EE_message_type[] $message_types */
3304
+		$message_types = $this->_message_resource_manager->installed_message_types();
3305
+
3306
+
3307
+		// assemble the array for the _tab_text_links helper
3308
+
3309
+		foreach ($messengers as $messenger) {
3310
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3311
+				'label' => ucwords($messenger->label['singular']),
3312
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3313
+					? 'messenger-active'
3314
+					: '',
3315
+				'href'  => $messenger->name,
3316
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3317
+				'slug'  => $messenger->name,
3318
+				'obj'   => $messenger,
3319
+			);
3320
+
3321
+
3322
+			$message_types_for_messenger = $messenger->get_valid_message_types();
3323
+
3324
+			foreach ($message_types as $message_type) {
3325
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3326
+				// it shouldn't show in either the inactive OR active metabox.
3327
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3328
+					continue;
3329
+				}
3330
+
3331
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3332
+					$messenger->name,
3333
+					$message_type->name
3334
+				)
3335
+					? 'active'
3336
+					: 'inactive';
3337
+
3338
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3339
+					'label'    => ucwords($message_type->label['singular']),
3340
+					'class'    => 'message-type-' . $a_or_i,
3341
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3342
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3343
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3344
+					'title'    => $a_or_i === 'active'
3345
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3346
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3347
+					'content'  => $a_or_i === 'active'
3348
+						? $this->_message_type_settings_content($message_type, $messenger, true)
3349
+						: $this->_message_type_settings_content($message_type, $messenger),
3350
+					'slug'     => $message_type->name,
3351
+					'active'   => $a_or_i === 'active',
3352
+					'obj'      => $message_type,
3353
+				);
3354
+			}
3355
+		}
3356
+	}
3357
+
3358
+
3359
+	/**
3360
+	 * This just prepares the content for the message type settings
3361
+	 *
3362
+	 * @param  EE_message_type $message_type The message type object
3363
+	 * @param  EE_messenger    $messenger    The messenger object
3364
+	 * @param  boolean         $active       Whether the message type is active or not
3365
+	 * @return string html output for the content
3366
+	 * @throws DomainException
3367
+	 */
3368
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
3369
+	{
3370
+		// get message type fields
3371
+		$fields = $message_type->get_admin_settings_fields();
3372
+		$settings_template_args['template_form_fields'] = '';
3373
+
3374
+		if (! empty($fields) && $active) {
3375
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3376
+			foreach ($fields as $fldname => $fldprops) {
3377
+				$field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3378
+				$template_form_field[ $field_id ] = array(
3379
+					'name'       => 'message_type_settings[' . $fldname . ']',
3380
+					'label'      => $fldprops['label'],
3381
+					'input'      => $fldprops['field_type'],
3382
+					'type'       => $fldprops['value_type'],
3383
+					'required'   => $fldprops['required'],
3384
+					'validation' => $fldprops['validation'],
3385
+					'value'      => isset($existing_settings[ $fldname ])
3386
+						? $existing_settings[ $fldname ]
3387
+						: $fldprops['default'],
3388
+					'options'    => isset($fldprops['options'])
3389
+						? $fldprops['options']
3390
+						: array(),
3391
+					'default'    => isset($existing_settings[ $fldname ])
3392
+						? $existing_settings[ $fldname ]
3393
+						: $fldprops['default'],
3394
+					'css_class'  => 'no-drag',
3395
+					'format'     => $fldprops['format'],
3396
+				);
3397
+			}
3398
+
3399
+
3400
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3401
+				? $this->_generate_admin_form_fields(
3402
+					$template_form_field,
3403
+					'string',
3404
+					'ee_mt_activate_form'
3405
+				)
3406
+				: '';
3407
+		}
3408
+
3409
+		$settings_template_args['description'] = $message_type->description;
3410
+		// we also need some hidden fields
3411
+		$settings_template_args['hidden_fields'] = array(
3412
+			'message_type_settings[messenger]'    => array(
3413
+				'type'  => 'hidden',
3414
+				'value' => $messenger->name,
3415
+			),
3416
+			'message_type_settings[message_type]' => array(
3417
+				'type'  => 'hidden',
3418
+				'value' => $message_type->name,
3419
+			),
3420
+			'type'                                => array(
3421
+				'type'  => 'hidden',
3422
+				'value' => 'message_type',
3423
+			),
3424
+		);
3425
+
3426
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3427
+			$settings_template_args['hidden_fields'],
3428
+			'array'
3429
+		);
3430
+		$settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3431
+			? ' hidden'
3432
+			: '';
3433
+
3434
+
3435
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3436
+		$content = EEH_Template::display_template($template, $settings_template_args, true);
3437
+
3438
+		return $content;
3439
+	}
3440
+
3441
+
3442
+	/**
3443
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3444
+	 *
3445
+	 * @access protected
3446
+	 * @return void
3447
+	 * @throws DomainException
3448
+	 */
3449
+	protected function _messages_settings_metaboxes()
3450
+	{
3451
+		$this->_set_m_mt_settings();
3452
+		$m_boxes = $mt_boxes = array();
3453
+		$m_template_args = $mt_template_args = array();
3454
+
3455
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3456
+			? $this->_req_data['selected_messenger']
3457
+			: 'email';
3458
+
3459
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3460
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3461
+				$hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3462
+				$hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3463
+				// messenger meta boxes
3464
+				$active = $selected_messenger === $messenger;
3465
+				$active_mt_tabs = isset(
3466
+					$this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3467
+				)
3468
+					? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3469
+					: '';
3470
+				$m_boxes[ $messenger . '_a_box' ] = sprintf(
3471
+					esc_html__('%s Settings', 'event_espresso'),
3472
+					$tab_array['label']
3473
+				);
3474
+				$m_template_args[ $messenger . '_a_box' ] = array(
3475
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3476
+					'inactive_message_types' => isset(
3477
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3478
+					)
3479
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3480
+						: '',
3481
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3482
+					'hidden'                 => $active ? '' : ' hidden',
3483
+					'hide_on_message'        => $hide_on_message,
3484
+					'messenger'              => $messenger,
3485
+					'active'                 => $active,
3486
+				);
3487
+				// message type meta boxes
3488
+				// (which is really just the inactive container for each messenger
3489
+				// showing inactive message types for that messenger)
3490
+				$mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3491
+				$mt_template_args[ $messenger . '_i_box' ] = array(
3492
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3493
+					'inactive_message_types' => isset(
3494
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3495
+					)
3496
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3497
+						: '',
3498
+					'hidden'                 => $active ? '' : ' hidden',
3499
+					'hide_on_message'        => $hide_on_message,
3500
+					'hide_off_message'       => $hide_off_message,
3501
+					'messenger'              => $messenger,
3502
+					'active'                 => $active,
3503
+				);
3504
+			}
3505
+		}
3506
+
3507
+
3508
+		// register messenger metaboxes
3509
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3510
+		foreach ($m_boxes as $box => $label) {
3511
+			$callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3512
+			$msgr = str_replace('_a_box', '', $box);
3513
+			add_meta_box(
3514
+				'espresso_' . $msgr . '_settings',
3515
+				$label,
3516
+				function ($post, $metabox) {
3517
+					echo EEH_Template::display_template(
3518
+						$metabox["args"]["template_path"],
3519
+						$metabox["args"]["template_args"],
3520
+						true
3521
+					);
3522
+				},
3523
+				$this->_current_screen->id,
3524
+				'normal',
3525
+				'high',
3526
+				$callback_args
3527
+			);
3528
+		}
3529
+
3530
+		// register message type metaboxes
3531
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3532
+		foreach ($mt_boxes as $box => $label) {
3533
+			$callback_args = array(
3534
+				'template_path' => $mt_template_path,
3535
+				'template_args' => $mt_template_args[ $box ],
3536
+			);
3537
+			$mt = str_replace('_i_box', '', $box);
3538
+			add_meta_box(
3539
+				'espresso_' . $mt . '_inactive_mts',
3540
+				$label,
3541
+				function ($post, $metabox) {
3542
+					echo EEH_Template::display_template(
3543
+						$metabox["args"]["template_path"],
3544
+						$metabox["args"]["template_args"],
3545
+						true
3546
+					);
3547
+				},
3548
+				$this->_current_screen->id,
3549
+				'side',
3550
+				'high',
3551
+				$callback_args
3552
+			);
3553
+		}
3554
+
3555
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3556
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3557
+		if (is_main_site()) {
3558
+			add_meta_box(
3559
+				'espresso_global_message_settings',
3560
+				esc_html__('Global Message Settings', 'event_espresso'),
3561
+				array($this, 'global_messages_settings_metabox_content'),
3562
+				$this->_current_screen->id,
3563
+				'normal',
3564
+				'low',
3565
+				array()
3566
+			);
3567
+		}
3568
+	}
3569
+
3570
+
3571
+	/**
3572
+	 *  This generates the content for the global messages settings metabox.
3573
+	 *
3574
+	 * @return string
3575
+	 * @throws EE_Error
3576
+	 * @throws InvalidArgumentException
3577
+	 * @throws ReflectionException
3578
+	 * @throws InvalidDataTypeException
3579
+	 * @throws InvalidInterfaceException
3580
+	 */
3581
+	public function global_messages_settings_metabox_content()
3582
+	{
3583
+		$form = $this->_generate_global_settings_form();
3584
+		echo $form->form_open(
3585
+			$this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3586
+			'POST'
3587
+		)
3588
+			 . $form->get_html()
3589
+			 . $form->form_close();
3590
+	}
3591
+
3592
+
3593
+	/**
3594
+	 * This generates and returns the form object for the global messages settings.
3595
+	 *
3596
+	 * @return EE_Form_Section_Proper
3597
+	 * @throws EE_Error
3598
+	 * @throws InvalidArgumentException
3599
+	 * @throws ReflectionException
3600
+	 * @throws InvalidDataTypeException
3601
+	 * @throws InvalidInterfaceException
3602
+	 */
3603
+	protected function _generate_global_settings_form()
3604
+	{
3605
+		EE_Registry::instance()->load_helper('HTML');
3606
+		/** @var EE_Network_Core_Config $network_config */
3607
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3608
+
3609
+		return new EE_Form_Section_Proper(
3610
+			array(
3611
+				'name'            => 'global_messages_settings',
3612
+				'html_id'         => 'global_messages_settings',
3613
+				'html_class'      => 'form-table',
3614
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3615
+				'subsections'     => apply_filters(
3616
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3617
+					array(
3618
+						'do_messages_on_same_request' => new EE_Select_Input(
3619
+							array(
3620
+								true  => esc_html__("On the same request", "event_espresso"),
3621
+								false => esc_html__("On a separate request", "event_espresso"),
3622
+							),
3623
+							array(
3624
+								'default'         => $network_config->do_messages_on_same_request,
3625
+								'html_label_text' => esc_html__(
3626
+									'Generate and send all messages:',
3627
+									'event_espresso'
3628
+								),
3629
+								'html_help_text'  => esc_html__(
3630
+									'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.',
3631
+									'event_espresso'
3632
+								),
3633
+							)
3634
+						),
3635
+						'delete_threshold'            => new EE_Select_Input(
3636
+							array(
3637
+								0  => esc_html__('Forever', 'event_espresso'),
3638
+								3  => esc_html__('3 Months', 'event_espresso'),
3639
+								6  => esc_html__('6 Months', 'event_espresso'),
3640
+								9  => esc_html__('9 Months', 'event_espresso'),
3641
+								12 => esc_html__('12 Months', 'event_espresso'),
3642
+								24 => esc_html__('24 Months', 'event_espresso'),
3643
+								36 => esc_html__('36 Months', 'event_espresso'),
3644
+							),
3645
+							array(
3646
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3647
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3648
+								'html_help_text'  => esc_html__(
3649
+									'You can control how long a record of processed messages is kept via this option.',
3650
+									'event_espresso'
3651
+								),
3652
+							)
3653
+						),
3654
+						'update_settings'             => new EE_Submit_Input(
3655
+							array(
3656
+								'default'         => esc_html__('Update', 'event_espresso'),
3657
+								'html_label_text' => '&nbsp',
3658
+							)
3659
+						),
3660
+					)
3661
+				),
3662
+			)
3663
+		);
3664
+	}
3665
+
3666
+
3667
+	/**
3668
+	 * This handles updating the global settings set on the admin page.
3669
+	 *
3670
+	 * @throws EE_Error
3671
+	 * @throws InvalidDataTypeException
3672
+	 * @throws InvalidInterfaceException
3673
+	 * @throws InvalidArgumentException
3674
+	 * @throws ReflectionException
3675
+	 */
3676
+	protected function _update_global_settings()
3677
+	{
3678
+		/** @var EE_Network_Core_Config $network_config */
3679
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3680
+		$messages_config = EE_Registry::instance()->CFG->messages;
3681
+		$form = $this->_generate_global_settings_form();
3682
+		if ($form->was_submitted()) {
3683
+			$form->receive_form_submission();
3684
+			if ($form->is_valid()) {
3685
+				$valid_data = $form->valid_data();
3686
+				foreach ($valid_data as $property => $value) {
3687
+					$setter = 'set_' . $property;
3688
+					if (method_exists($network_config, $setter)) {
3689
+						$network_config->{$setter}($value);
3690
+					} elseif (property_exists($network_config, $property)
3691
+						&& $network_config->{$property} !== $value
3692
+					) {
3693
+						$network_config->{$property} = $value;
3694
+					} elseif (property_exists($messages_config, $property)
3695
+						&& $messages_config->{$property} !== $value
3696
+					) {
3697
+						$messages_config->{$property} = $value;
3698
+					}
3699
+				}
3700
+				// only update if the form submission was valid!
3701
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3702
+				EE_Registry::instance()->CFG->update_espresso_config();
3703
+				EE_Error::overwrite_success();
3704
+				EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3705
+			}
3706
+		}
3707
+		$this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3708
+	}
3709
+
3710
+
3711
+	/**
3712
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3713
+	 *
3714
+	 * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3715
+	 * @return string html formatted tabs
3716
+	 * @throws DomainException
3717
+	 */
3718
+	protected function _get_mt_tabs($tab_array)
3719
+	{
3720
+		$tab_array = (array) $tab_array;
3721
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3722
+		$tabs = '';
3723
+
3724
+		foreach ($tab_array as $tab) {
3725
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3726
+		}
3727
+
3728
+		return $tabs;
3729
+	}
3730
+
3731
+
3732
+	/**
3733
+	 * This prepares the content of the messenger meta box admin settings
3734
+	 *
3735
+	 * @param  EE_messenger $messenger The messenger we're setting up content for
3736
+	 * @return string html formatted content
3737
+	 * @throws DomainException
3738
+	 */
3739
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3740
+	{
3741
+
3742
+		$fields = $messenger->get_admin_settings_fields();
3743
+		$settings_template_args['template_form_fields'] = '';
3744
+
3745
+		// is $messenger active?
3746
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3747
+
3748
+
3749
+		if (! empty($fields)) {
3750
+			$existing_settings = $messenger->get_existing_admin_settings();
3751
+
3752
+			foreach ($fields as $fldname => $fldprops) {
3753
+				$field_id = $messenger->name . '-' . $fldname;
3754
+				$template_form_field[ $field_id ] = array(
3755
+					'name'       => 'messenger_settings[' . $field_id . ']',
3756
+					'label'      => $fldprops['label'],
3757
+					'input'      => $fldprops['field_type'],
3758
+					'type'       => $fldprops['value_type'],
3759
+					'required'   => $fldprops['required'],
3760
+					'validation' => $fldprops['validation'],
3761
+					'value'      => isset($existing_settings[ $field_id ])
3762
+						? $existing_settings[ $field_id ]
3763
+						: $fldprops['default'],
3764
+					'css_class'  => '',
3765
+					'format'     => $fldprops['format'],
3766
+				);
3767
+			}
3768
+
3769
+
3770
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3771
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3772
+				: '';
3773
+		}
3774
+
3775
+		// we also need some hidden fields
3776
+		$settings_template_args['hidden_fields'] = array(
3777
+			'messenger_settings[messenger]' => array(
3778
+				'type'  => 'hidden',
3779
+				'value' => $messenger->name,
3780
+			),
3781
+			'type'                          => array(
3782
+				'type'  => 'hidden',
3783
+				'value' => 'messenger',
3784
+			),
3785
+		);
3786
+
3787
+		// make sure any active message types that are existing are included in the hidden fields
3788
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3789
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3790
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3791
+					'type'  => 'hidden',
3792
+					'value' => $mt,
3793
+				);
3794
+			}
3795
+		}
3796
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3797
+			$settings_template_args['hidden_fields'],
3798
+			'array'
3799
+		);
3800
+		$active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3801
+
3802
+		$settings_template_args['messenger'] = $messenger->name;
3803
+		$settings_template_args['description'] = $messenger->description;
3804
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3805
+
3806
+
3807
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3808
+			$messenger->name
3809
+		)
3810
+			? $settings_template_args['show_hide_edit_form']
3811
+			: ' hidden';
3812
+
3813
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3814
+			? ' hidden'
3815
+			: $settings_template_args['show_hide_edit_form'];
3816
+
3817
+
3818
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3819
+		$settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3820
+		$settings_template_args['on_off_status'] = $active ? true : false;
3821
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3822
+		$content = EEH_Template::display_template(
3823
+			$template,
3824
+			$settings_template_args,
3825
+			true
3826
+		);
3827
+
3828
+		return $content;
3829
+	}
3830
+
3831
+
3832
+	/**
3833
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3834
+	 *
3835
+	 * @throws DomainException
3836
+	 * @throws EE_Error
3837
+	 * @throws InvalidDataTypeException
3838
+	 * @throws InvalidInterfaceException
3839
+	 * @throws InvalidArgumentException
3840
+	 * @throws ReflectionException
3841
+	 */
3842
+	public function activate_messenger_toggle()
3843
+	{
3844
+		$success = true;
3845
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3846
+		// let's check that we have required data
3847
+		if (! isset($this->_req_data['messenger'])) {
3848
+			EE_Error::add_error(
3849
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3850
+				__FILE__,
3851
+				__FUNCTION__,
3852
+				__LINE__
3853
+			);
3854
+			$success = false;
3855
+		}
3856
+
3857
+		// do a nonce check here since we're not arriving via a normal route
3858
+		$nonce = isset($this->_req_data['activate_nonce'])
3859
+			? sanitize_text_field($this->_req_data['activate_nonce'])
3860
+			: '';
3861
+		$nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3862
+
3863
+		$this->_verify_nonce($nonce, $nonce_ref);
3864
+
3865
+
3866
+		if (! isset($this->_req_data['status'])) {
3867
+			EE_Error::add_error(
3868
+				esc_html__(
3869
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3870
+					'event_espresso'
3871
+				),
3872
+				__FILE__,
3873
+				__FUNCTION__,
3874
+				__LINE__
3875
+			);
3876
+			$success = false;
3877
+		}
3878
+
3879
+		// do check to verify we have a valid status.
3880
+		$status = $this->_req_data['status'];
3881
+
3882
+		if ($status !== 'off' && $status !== 'on') {
3883
+			EE_Error::add_error(
3884
+				sprintf(
3885
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3886
+					$this->_req_data['status']
3887
+				),
3888
+				__FILE__,
3889
+				__FUNCTION__,
3890
+				__LINE__
3891
+			);
3892
+			$success = false;
3893
+		}
3894
+
3895
+		if ($success) {
3896
+			// made it here?  Stop dawdling then!!
3897
+			$success = $status === 'off'
3898
+				? $this->_deactivate_messenger($this->_req_data['messenger'])
3899
+				: $this->_activate_messenger($this->_req_data['messenger']);
3900
+		}
3901
+
3902
+		$this->_template_args['success'] = $success;
3903
+
3904
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
3905
+		$this->_return_json();
3906
+	}
3907
+
3908
+
3909
+	/**
3910
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3911
+	 *
3912
+	 * @throws DomainException
3913
+	 * @throws EE_Error
3914
+	 * @throws ReflectionException
3915
+	 * @throws InvalidDataTypeException
3916
+	 * @throws InvalidInterfaceException
3917
+	 * @throws InvalidArgumentException
3918
+	 */
3919
+	public function activate_mt_toggle()
3920
+	{
3921
+		$success = true;
3922
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3923
+
3924
+		// let's make sure we have the necessary data
3925
+		if (! isset($this->_req_data['message_type'])) {
3926
+			EE_Error::add_error(
3927
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3928
+				__FILE__,
3929
+				__FUNCTION__,
3930
+				__LINE__
3931
+			);
3932
+			$success = false;
3933
+		}
3934
+
3935
+		if (! isset($this->_req_data['messenger'])) {
3936
+			EE_Error::add_error(
3937
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3938
+				__FILE__,
3939
+				__FUNCTION__,
3940
+				__LINE__
3941
+			);
3942
+			$success = false;
3943
+		}
3944
+
3945
+		if (! isset($this->_req_data['status'])) {
3946
+			EE_Error::add_error(
3947
+				esc_html__(
3948
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3949
+					'event_espresso'
3950
+				),
3951
+				__FILE__,
3952
+				__FUNCTION__,
3953
+				__LINE__
3954
+			);
3955
+			$success = false;
3956
+		}
3957
+
3958
+
3959
+		// do check to verify we have a valid status.
3960
+		$status = $this->_req_data['status'];
3961
+
3962
+		if ($status !== 'activate' && $status !== 'deactivate') {
3963
+			EE_Error::add_error(
3964
+				sprintf(
3965
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3966
+					$this->_req_data['status']
3967
+				),
3968
+				__FILE__,
3969
+				__FUNCTION__,
3970
+				__LINE__
3971
+			);
3972
+			$success = false;
3973
+		}
3974
+
3975
+
3976
+		// do a nonce check here since we're not arriving via a normal route
3977
+		$nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3978
+		$nonce_ref = $this->_req_data['message_type'] . '_nonce';
3979
+
3980
+		$this->_verify_nonce($nonce, $nonce_ref);
3981
+
3982
+		if ($success) {
3983
+			// made it here? um, what are you waiting for then?
3984
+			$success = $status === 'deactivate'
3985
+				? $this->_deactivate_message_type_for_messenger(
3986
+					$this->_req_data['messenger'],
3987
+					$this->_req_data['message_type']
3988
+				)
3989
+				: $this->_activate_message_type_for_messenger(
3990
+					$this->_req_data['messenger'],
3991
+					$this->_req_data['message_type']
3992
+				);
3993
+		}
3994
+
3995
+		$this->_template_args['success'] = $success;
3996
+		$this->_return_json();
3997
+	}
3998
+
3999
+
4000
+	/**
4001
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
4002
+	 *
4003
+	 * @param string $messenger_name The name of the messenger being activated
4004
+	 * @return bool
4005
+	 * @throws DomainException
4006
+	 * @throws EE_Error
4007
+	 * @throws InvalidArgumentException
4008
+	 * @throws ReflectionException
4009
+	 * @throws InvalidDataTypeException
4010
+	 * @throws InvalidInterfaceException
4011
+	 */
4012
+	protected function _activate_messenger($messenger_name)
4013
+	{
4014
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4015
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4016
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
4017
+			? $active_messenger->get_default_message_types()
4018
+			: array();
4019
+
4020
+		// ensure is active
4021
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4022
+
4023
+		// set response_data for reload
4024
+		foreach ($message_types_to_activate as $message_type_name) {
4025
+			/** @var EE_message_type $message_type */
4026
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4027
+			if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4028
+				$messenger_name,
4029
+				$message_type_name
4030
+			)
4031
+				&& $message_type instanceof EE_message_type
4032
+			) {
4033
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
4034
+				if ($message_type->get_admin_settings_fields()) {
4035
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
4036
+				}
4037
+			}
4038
+		}
4039
+
4040
+		// add success message for activating messenger
4041
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4042
+	}
4043
+
4044
+
4045
+	/**
4046
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
4047
+	 *
4048
+	 * @param string $messenger_name The name of the messenger being activated
4049
+	 * @return bool
4050
+	 * @throws DomainException
4051
+	 * @throws EE_Error
4052
+	 * @throws InvalidArgumentException
4053
+	 * @throws ReflectionException
4054
+	 * @throws InvalidDataTypeException
4055
+	 * @throws InvalidInterfaceException
4056
+	 */
4057
+	protected function _deactivate_messenger($messenger_name)
4058
+	{
4059
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4060
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4061
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
4062
+
4063
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4064
+	}
4065
+
4066
+
4067
+	/**
4068
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4069
+	 *
4070
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
4071
+	 * @param string $message_type_name The name of the message type being activated for the messenger
4072
+	 * @return bool
4073
+	 * @throws DomainException
4074
+	 * @throws EE_Error
4075
+	 * @throws InvalidArgumentException
4076
+	 * @throws ReflectionException
4077
+	 * @throws InvalidDataTypeException
4078
+	 * @throws InvalidInterfaceException
4079
+	 */
4080
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4081
+	{
4082
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4083
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4084
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4085
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4086
+
4087
+		// ensure is active
4088
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4089
+
4090
+		// set response for load
4091
+		if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4092
+			$messenger_name,
4093
+			$message_type_name
4094
+		)
4095
+		) {
4096
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
4097
+			if ($message_type_to_activate->get_admin_settings_fields()) {
4098
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
4099
+			}
4100
+		}
4101
+
4102
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
4103
+			$active_messenger,
4104
+			$message_type_to_activate
4105
+		);
4106
+	}
4107
+
4108
+
4109
+	/**
4110
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4111
+	 *
4112
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4113
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
4114
+	 * @return bool
4115
+	 * @throws DomainException
4116
+	 * @throws EE_Error
4117
+	 * @throws InvalidArgumentException
4118
+	 * @throws ReflectionException
4119
+	 * @throws InvalidDataTypeException
4120
+	 * @throws InvalidInterfaceException
4121
+	 */
4122
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4123
+	{
4124
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4125
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4126
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4127
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4128
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4129
+
4130
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4131
+			$active_messenger,
4132
+			$message_type_to_deactivate
4133
+		);
4134
+	}
4135
+
4136
+
4137
+	/**
4138
+	 * This just initializes the defaults for activating messenger and message type responses.
4139
+	 */
4140
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
4141
+	{
4142
+		$this->_template_args['data']['active_mts'] = array();
4143
+		$this->_template_args['data']['mt_reload'] = array();
4144
+	}
4145
+
4146
+
4147
+	/**
4148
+	 * Setup appropriate response for activating a messenger and/or message types
4149
+	 *
4150
+	 * @param EE_messenger         $messenger
4151
+	 * @param EE_message_type|null $message_type
4152
+	 * @return bool
4153
+	 * @throws DomainException
4154
+	 * @throws EE_Error
4155
+	 * @throws InvalidArgumentException
4156
+	 * @throws ReflectionException
4157
+	 * @throws InvalidDataTypeException
4158
+	 * @throws InvalidInterfaceException
4159
+	 */
4160
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
4161
+		$messenger,
4162
+		EE_Message_Type $message_type = null
4163
+	) {
4164
+		// if $messenger isn't a valid messenger object then get out.
4165
+		if (! $messenger instanceof EE_Messenger) {
4166
+			EE_Error::add_error(
4167
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4168
+				__FILE__,
4169
+				__FUNCTION__,
4170
+				__LINE__
4171
+			);
4172
+
4173
+			return false;
4174
+		}
4175
+		// activated
4176
+		if ($this->_template_args['data']['active_mts']) {
4177
+			EE_Error::overwrite_success();
4178
+			// activated a message type with the messenger
4179
+			if ($message_type instanceof EE_message_type) {
4180
+				EE_Error::add_success(
4181
+					sprintf(
4182
+						esc_html__(
4183
+							'%s message type has been successfully activated with the %s messenger',
4184
+							'event_espresso'
4185
+						),
4186
+						ucwords($message_type->label['singular']),
4187
+						ucwords($messenger->label['singular'])
4188
+					)
4189
+				);
4190
+
4191
+				// if message type was invoice then let's make sure we activate the invoice payment method.
4192
+				if ($message_type->name === 'invoice') {
4193
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
4194
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4195
+					if ($pm instanceof EE_Payment_Method) {
4196
+						EE_Error::add_attention(
4197
+							esc_html__(
4198
+								'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.',
4199
+								'event_espresso'
4200
+							)
4201
+						);
4202
+					}
4203
+				}
4204
+				// just toggles the entire messenger
4205
+			} else {
4206
+				EE_Error::add_success(
4207
+					sprintf(
4208
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4209
+						ucwords($messenger->label['singular'])
4210
+					)
4211
+				);
4212
+			}
4213
+
4214
+			return true;
4215
+
4216
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4217
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4218
+			// in which case we just give a success message for the messenger being successfully activated.
4219
+		} else {
4220
+			if (! $messenger->get_default_message_types()) {
4221
+				// messenger doesn't have any default message types so still a success.
4222
+				EE_Error::add_success(
4223
+					sprintf(
4224
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4225
+						ucwords($messenger->label['singular'])
4226
+					)
4227
+				);
4228
+
4229
+				return true;
4230
+			} else {
4231
+				EE_Error::add_error(
4232
+					$message_type instanceof EE_message_type
4233
+						? sprintf(
4234
+							esc_html__(
4235
+								'%s message type was not successfully activated with the %s messenger',
4236
+								'event_espresso'
4237
+							),
4238
+							ucwords($message_type->label['singular']),
4239
+							ucwords($messenger->label['singular'])
4240
+						)
4241
+						: sprintf(
4242
+							esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4243
+							ucwords($messenger->label['singular'])
4244
+						),
4245
+					__FILE__,
4246
+					__FUNCTION__,
4247
+					__LINE__
4248
+				);
4249
+
4250
+				return false;
4251
+			}
4252
+		}
4253
+	}
4254
+
4255
+
4256
+	/**
4257
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
4258
+	 *
4259
+	 * @param EE_messenger         $messenger
4260
+	 * @param EE_message_type|null $message_type
4261
+	 * @return bool
4262
+	 * @throws DomainException
4263
+	 * @throws EE_Error
4264
+	 * @throws InvalidArgumentException
4265
+	 * @throws ReflectionException
4266
+	 * @throws InvalidDataTypeException
4267
+	 * @throws InvalidInterfaceException
4268
+	 */
4269
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4270
+		$messenger,
4271
+		EE_message_type $message_type = null
4272
+	) {
4273
+		EE_Error::overwrite_success();
4274
+
4275
+		// if $messenger isn't a valid messenger object then get out.
4276
+		if (! $messenger instanceof EE_Messenger) {
4277
+			EE_Error::add_error(
4278
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4279
+				__FILE__,
4280
+				__FUNCTION__,
4281
+				__LINE__
4282
+			);
4283
+
4284
+			return false;
4285
+		}
4286
+
4287
+		if ($message_type instanceof EE_message_type) {
4288
+			$message_type_name = $message_type->name;
4289
+			EE_Error::add_success(
4290
+				sprintf(
4291
+					esc_html__(
4292
+						'%s message type has been successfully deactivated for the %s messenger.',
4293
+						'event_espresso'
4294
+					),
4295
+					ucwords($message_type->label['singular']),
4296
+					ucwords($messenger->label['singular'])
4297
+				)
4298
+			);
4299
+		} else {
4300
+			$message_type_name = '';
4301
+			EE_Error::add_success(
4302
+				sprintf(
4303
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4304
+					ucwords($messenger->label['singular'])
4305
+				)
4306
+			);
4307
+		}
4308
+
4309
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4310
+		if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4311
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
4312
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4313
+			if ($count_updated > 0) {
4314
+				$msg = $message_type_name === 'invoice'
4315
+					? esc_html__(
4316
+						'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.',
4317
+						'event_espresso'
4318
+					)
4319
+					: esc_html__(
4320
+						'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.',
4321
+						'event_espresso'
4322
+					);
4323
+				EE_Error::add_attention($msg);
4324
+			}
4325
+		}
4326
+
4327
+		return true;
4328
+	}
4329
+
4330
+
4331
+	/**
4332
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4333
+	 *
4334
+	 * @throws DomainException
4335
+	 */
4336
+	public function update_mt_form()
4337
+	{
4338
+		if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4339
+			EE_Error::add_error(
4340
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4341
+				__FILE__,
4342
+				__FUNCTION__,
4343
+				__LINE__
4344
+			);
4345
+			$this->_return_json();
4346
+		}
4347
+
4348
+		$message_types = $this->get_installed_message_types();
4349
+
4350
+		$message_type = $message_types[ $this->_req_data['message_type'] ];
4351
+		$messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4352
+
4353
+		$content = $this->_message_type_settings_content(
4354
+			$message_type,
4355
+			$messenger,
4356
+			true
4357
+		);
4358
+		$this->_template_args['success'] = true;
4359
+		$this->_template_args['content'] = $content;
4360
+		$this->_return_json();
4361
+	}
4362
+
4363
+
4364
+	/**
4365
+	 * this handles saving the settings for a messenger or message type
4366
+	 *
4367
+	 */
4368
+	public function save_settings()
4369
+	{
4370
+		if (! isset($this->_req_data['type'])) {
4371
+			EE_Error::add_error(
4372
+				esc_html__(
4373
+					'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4374
+					'event_espresso'
4375
+				),
4376
+				__FILE__,
4377
+				__FUNCTION__,
4378
+				__LINE__
4379
+			);
4380
+			$this->_template_args['error'] = true;
4381
+			$this->_return_json();
4382
+		}
4383
+
4384
+
4385
+		if ($this->_req_data['type'] === 'messenger') {
4386
+			// this should be an array.
4387
+			$settings = $this->_req_data['messenger_settings'];
4388
+			$messenger = $settings['messenger'];
4389
+			// let's setup the settings data
4390
+			foreach ($settings as $key => $value) {
4391
+				switch ($key) {
4392
+					case 'messenger':
4393
+						unset($settings['messenger']);
4394
+						break;
4395
+					case 'message_types':
4396
+						unset($settings['message_types']);
4397
+						break;
4398
+					default:
4399
+						$settings[ $key ] = $value;
4400
+						break;
4401
+				}
4402
+			}
4403
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4404
+		} elseif ($this->_req_data['type'] === 'message_type') {
4405
+			$settings = $this->_req_data['message_type_settings'];
4406
+			$messenger = $settings['messenger'];
4407
+			$message_type = $settings['message_type'];
4408
+
4409
+			foreach ($settings as $key => $value) {
4410
+				switch ($key) {
4411
+					case 'messenger':
4412
+						unset($settings['messenger']);
4413
+						break;
4414
+					case 'message_type':
4415
+						unset($settings['message_type']);
4416
+						break;
4417
+					default:
4418
+						$settings[ $key ] = $value;
4419
+						break;
4420
+				}
4421
+			}
4422
+
4423
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4424
+		}
4425
+
4426
+		// okay we should have the data all setup.  Now we just update!
4427
+		$success = $this->_message_resource_manager->update_active_messengers_option();
4428
+
4429
+		if ($success) {
4430
+			EE_Error::add_success(__('Settings updated', 'event_espresso'));
4431
+		} else {
4432
+			EE_Error::add_error(
4433
+				esc_html__(
4434
+					'Settings did not get updated',
4435
+					'event_espresso'
4436
+				),
4437
+				__FILE__,
4438
+				__FUNCTION__,
4439
+				__LINE__
4440
+			);
4441
+		}
4442
+
4443
+		$this->_template_args['success'] = $success;
4444
+		$this->_return_json();
4445
+	}
4446
+
4447
+
4448
+
4449
+
4450
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4451
+
4452
+
4453
+	/**
4454
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4455
+	 * However, this does not send immediately, it just queues for sending.
4456
+	 *
4457
+	 * @since 4.9.0
4458
+	 * @throws EE_Error
4459
+	 * @throws InvalidDataTypeException
4460
+	 * @throws InvalidInterfaceException
4461
+	 * @throws InvalidArgumentException
4462
+	 * @throws ReflectionException
4463
+	 */
4464
+	protected function _generate_now()
4465
+	{
4466
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4467
+		$this->_redirect_after_action(false, '', '', array(), true);
4468
+	}
4469
+
4470
+
4471
+	/**
4472
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4473
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4474
+	 *
4475
+	 * @since 4.9.0
4476
+	 * @throws EE_Error
4477
+	 * @throws InvalidDataTypeException
4478
+	 * @throws InvalidInterfaceException
4479
+	 * @throws InvalidArgumentException
4480
+	 * @throws ReflectionException
4481
+	 */
4482
+	protected function _generate_and_send_now()
4483
+	{
4484
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4485
+		$this->_redirect_after_action(false, '', '', array(), true);
4486
+	}
4487
+
4488
+
4489
+	/**
4490
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4491
+	 *
4492
+	 * @since 4.9.0
4493
+	 * @throws EE_Error
4494
+	 * @throws InvalidDataTypeException
4495
+	 * @throws InvalidInterfaceException
4496
+	 * @throws InvalidArgumentException
4497
+	 * @throws ReflectionException
4498
+	 */
4499
+	protected function _queue_for_resending()
4500
+	{
4501
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4502
+		$this->_redirect_after_action(false, '', '', array(), true);
4503
+	}
4504
+
4505
+
4506
+	/**
4507
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4508
+	 *
4509
+	 * @since 4.9.0
4510
+	 * @throws EE_Error
4511
+	 * @throws InvalidDataTypeException
4512
+	 * @throws InvalidInterfaceException
4513
+	 * @throws InvalidArgumentException
4514
+	 * @throws ReflectionException
4515
+	 */
4516
+	protected function _send_now()
4517
+	{
4518
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4519
+		$this->_redirect_after_action(false, '', '', array(), true);
4520
+	}
4521
+
4522
+
4523
+	/**
4524
+	 * Deletes EE_messages for IDs in the request.
4525
+	 *
4526
+	 * @since 4.9.0
4527
+	 * @throws EE_Error
4528
+	 * @throws InvalidDataTypeException
4529
+	 * @throws InvalidInterfaceException
4530
+	 * @throws InvalidArgumentException
4531
+	 */
4532
+	protected function _delete_ee_messages()
4533
+	{
4534
+		$msg_ids = $this->_get_msg_ids_from_request();
4535
+		$deleted_count = 0;
4536
+		foreach ($msg_ids as $msg_id) {
4537
+			if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4538
+				$deleted_count++;
4539
+			}
4540
+		}
4541
+		if ($deleted_count) {
4542
+			EE_Error::add_success(
4543
+				esc_html(
4544
+					_n(
4545
+						'Message successfully deleted',
4546
+						'Messages successfully deleted',
4547
+						$deleted_count,
4548
+						'event_espresso'
4549
+					)
4550
+				)
4551
+			);
4552
+			$this->_redirect_after_action(
4553
+				false,
4554
+				'',
4555
+				'',
4556
+				array(),
4557
+				true
4558
+			);
4559
+		} else {
4560
+			EE_Error::add_error(
4561
+				_n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4562
+				__FILE__,
4563
+				__FUNCTION__,
4564
+				__LINE__
4565
+			);
4566
+			$this->_redirect_after_action(false, '', '', array(), true);
4567
+		}
4568
+	}
4569
+
4570
+
4571
+	/**
4572
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4573
+	 *
4574
+	 * @since 4.9.0
4575
+	 * @return array
4576
+	 */
4577
+	protected function _get_msg_ids_from_request()
4578
+	{
4579
+		if (! isset($this->_req_data['MSG_ID'])) {
4580
+			return array();
4581
+		}
4582
+
4583
+		return is_array($this->_req_data['MSG_ID'])
4584
+			? array_keys($this->_req_data['MSG_ID'])
4585
+			: array($this->_req_data['MSG_ID']);
4586
+	}
4587 4587
 }
Please login to merge, or discard this patch.
core/EE_System.core.php 1 patch
Indentation   +1309 added lines, -1309 removed lines patch added patch discarded remove patch
@@ -27,1313 +27,1313 @@
 block discarded – undo
27 27
 final class EE_System implements ResettableInterface
28 28
 {
29 29
 
30
-    /**
31
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
-     */
34
-    const req_type_normal = 0;
35
-
36
-    /**
37
-     * Indicates this is a brand new installation of EE so we should install
38
-     * tables and default data etc
39
-     */
40
-    const req_type_new_activation = 1;
41
-
42
-    /**
43
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
-     * and we just exited maintenance mode). We MUST check the database is setup properly
45
-     * and that default data is setup too
46
-     */
47
-    const req_type_reactivation = 2;
48
-
49
-    /**
50
-     * indicates that EE has been upgraded since its previous request.
51
-     * We may have data migration scripts to call and will want to trigger maintenance mode
52
-     */
53
-    const req_type_upgrade = 3;
54
-
55
-    /**
56
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
-     */
58
-    const req_type_downgrade = 4;
59
-
60
-    /**
61
-     * @deprecated since version 4.6.0.dev.006
62
-     * Now whenever a new_activation is detected the request type is still just
63
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
-     * (Specifically, when the migration manager indicates migrations are finished
67
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
-     */
69
-    const req_type_activation_but_not_installed = 5;
70
-
71
-    /**
72
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
-     */
74
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
-
76
-    /**
77
-     * @var EE_System $_instance
78
-     */
79
-    private static $_instance;
80
-
81
-    /**
82
-     * @var EE_Registry $registry
83
-     */
84
-    private $registry;
85
-
86
-    /**
87
-     * @var LoaderInterface $loader
88
-     */
89
-    private $loader;
90
-
91
-    /**
92
-     * @var EE_Capabilities $capabilities
93
-     */
94
-    private $capabilities;
95
-
96
-    /**
97
-     * @var RequestInterface $request
98
-     */
99
-    private $request;
100
-
101
-    /**
102
-     * @var EE_Maintenance_Mode $maintenance_mode
103
-     */
104
-    private $maintenance_mode;
105
-
106
-    /**
107
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
-     *
110
-     * @var int $_req_type
111
-     */
112
-    private $_req_type;
113
-
114
-    /**
115
-     * Whether or not there was a non-micro version change in EE core version during this request
116
-     *
117
-     * @var boolean $_major_version_change
118
-     */
119
-    private $_major_version_change = false;
120
-
121
-    /**
122
-     * A Context DTO dedicated solely to identifying the current request type.
123
-     *
124
-     * @var RequestTypeContextCheckerInterface $request_type
125
-     */
126
-    private $request_type;
127
-
128
-
129
-    /**
130
-     * @singleton method used to instantiate class object
131
-     * @param EE_Registry|null         $registry
132
-     * @param LoaderInterface|null     $loader
133
-     * @param RequestInterface|null    $request
134
-     * @param EE_Maintenance_Mode|null $maintenance_mode
135
-     * @return EE_System
136
-     */
137
-    public static function instance(
138
-        EE_Registry $registry = null,
139
-        LoaderInterface $loader = null,
140
-        RequestInterface $request = null,
141
-        EE_Maintenance_Mode $maintenance_mode = null
142
-    ) {
143
-        // check if class object is instantiated
144
-        if (! self::$_instance instanceof EE_System) {
145
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
-        }
147
-        return self::$_instance;
148
-    }
149
-
150
-
151
-    /**
152
-     * resets the instance and returns it
153
-     *
154
-     * @return EE_System
155
-     */
156
-    public static function reset()
157
-    {
158
-        self::$_instance->_req_type = null;
159
-        // make sure none of the old hooks are left hanging around
160
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
-        // we need to reset the migration manager in order for it to detect DMSs properly
162
-        EE_Data_Migration_Manager::reset();
163
-        self::instance()->detect_activations_or_upgrades();
164
-        self::instance()->perform_activations_upgrades_and_migrations();
165
-        return self::instance();
166
-    }
167
-
168
-
169
-    /**
170
-     * sets hooks for running rest of system
171
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
-     * starting EE Addons from any other point may lead to problems
173
-     *
174
-     * @param EE_Registry         $registry
175
-     * @param LoaderInterface     $loader
176
-     * @param RequestInterface    $request
177
-     * @param EE_Maintenance_Mode $maintenance_mode
178
-     */
179
-    private function __construct(
180
-        EE_Registry $registry,
181
-        LoaderInterface $loader,
182
-        RequestInterface $request,
183
-        EE_Maintenance_Mode $maintenance_mode
184
-    ) {
185
-        $this->registry = $registry;
186
-        $this->loader = $loader;
187
-        $this->request = $request;
188
-        $this->maintenance_mode = $maintenance_mode;
189
-        do_action('AHEE__EE_System__construct__begin', $this);
190
-        add_action(
191
-            'AHEE__EE_Bootstrap__load_espresso_addons',
192
-            array($this, 'loadCapabilities'),
193
-            5
194
-        );
195
-        add_action(
196
-            'AHEE__EE_Bootstrap__load_espresso_addons',
197
-            array($this, 'loadCommandBus'),
198
-            7
199
-        );
200
-        add_action(
201
-            'AHEE__EE_Bootstrap__load_espresso_addons',
202
-            array($this, 'loadPluginApi'),
203
-            9
204
-        );
205
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
-        add_action(
207
-            'AHEE__EE_Bootstrap__load_espresso_addons',
208
-            array($this, 'load_espresso_addons')
209
-        );
210
-        // when an ee addon is activated, we want to call the core hook(s) again
211
-        // because the newly-activated addon didn't get a chance to run at all
212
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
-        // detect whether install or upgrade
214
-        add_action(
215
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
-            array($this, 'detect_activations_or_upgrades'),
217
-            3
218
-        );
219
-        // load EE_Config, EE_Textdomain, etc
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_core_configuration',
222
-            array($this, 'load_core_configuration'),
223
-            5
224
-        );
225
-        // load specifications for matching routes to current request
226
-        add_action(
227
-            'AHEE__EE_Bootstrap__load_core_configuration',
228
-            array($this, 'loadRouteMatchSpecifications')
229
-        );
230
-        // load EE_Config, EE_Textdomain, etc
231
-        add_action(
232
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
-            array($this, 'register_shortcodes_modules_and_widgets'),
234
-            7
235
-        );
236
-        // you wanna get going? I wanna get going... let's get going!
237
-        add_action(
238
-            'AHEE__EE_Bootstrap__brew_espresso',
239
-            array($this, 'brew_espresso'),
240
-            9
241
-        );
242
-        // other housekeeping
243
-        // exclude EE critical pages from wp_list_pages
244
-        add_filter(
245
-            'wp_list_pages_excludes',
246
-            array($this, 'remove_pages_from_wp_list_pages'),
247
-            10
248
-        );
249
-        // ALL EE Addons should use the following hook point to attach their initial setup too
250
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
-        do_action('AHEE__EE_System__construct__complete', $this);
252
-    }
253
-
254
-
255
-    /**
256
-     * load and setup EE_Capabilities
257
-     *
258
-     * @return void
259
-     * @throws EE_Error
260
-     */
261
-    public function loadCapabilities()
262
-    {
263
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
264
-        add_action(
265
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
266
-            function () {
267
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
-            }
269
-        );
270
-    }
271
-
272
-
273
-    /**
274
-     * create and cache the CommandBus, and also add middleware
275
-     * The CapChecker middleware requires the use of EE_Capabilities
276
-     * which is why we need to load the CommandBus after Caps are set up
277
-     *
278
-     * @return void
279
-     * @throws EE_Error
280
-     */
281
-    public function loadCommandBus()
282
-    {
283
-        $this->loader->getShared(
284
-            'CommandBusInterface',
285
-            array(
286
-                null,
287
-                apply_filters(
288
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
-                    array(
290
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
-                    )
293
-                ),
294
-            )
295
-        );
296
-    }
297
-
298
-
299
-    /**
300
-     * @return void
301
-     * @throws EE_Error
302
-     */
303
-    public function loadPluginApi()
304
-    {
305
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
306
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
307
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
-        $this->loader->getShared('EE_Request_Handler');
309
-    }
310
-
311
-
312
-    /**
313
-     * @param string $addon_name
314
-     * @param string $version_constant
315
-     * @param string $min_version_required
316
-     * @param string $load_callback
317
-     * @param string $plugin_file_constant
318
-     * @return void
319
-     */
320
-    private function deactivateIncompatibleAddon(
321
-        $addon_name,
322
-        $version_constant,
323
-        $min_version_required,
324
-        $load_callback,
325
-        $plugin_file_constant
326
-    ) {
327
-        if (! defined($version_constant)) {
328
-            return;
329
-        }
330
-        $addon_version = constant($version_constant);
331
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
-            if (! function_exists('deactivate_plugins')) {
334
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
-            }
336
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
-            unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
-            EE_Error::add_error(
339
-                sprintf(
340
-                    esc_html__(
341
-                        'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
342
-                        'event_espresso'
343
-                    ),
344
-                    $addon_name,
345
-                    $min_version_required
346
-                ),
347
-                __FILE__,
348
-                __FUNCTION__ . "({$addon_name})",
349
-                __LINE__
350
-            );
351
-            EE_Error::get_notices(false, true);
352
-        }
353
-    }
354
-
355
-
356
-    /**
357
-     * load_espresso_addons
358
-     * allow addons to load first so that they can set hooks for running DMS's, etc
359
-     * this is hooked into both:
360
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
361
-     *        which runs during the WP 'plugins_loaded' action at priority 5
362
-     *    and the WP 'activate_plugin' hook point
363
-     *
364
-     * @access public
365
-     * @return void
366
-     */
367
-    public function load_espresso_addons()
368
-    {
369
-        $this->deactivateIncompatibleAddon(
370
-            'Wait Lists',
371
-            'EE_WAIT_LISTS_VERSION',
372
-            '1.0.0.beta.074',
373
-            'load_espresso_wait_lists',
374
-            'EE_WAIT_LISTS_PLUGIN_FILE'
375
-        );
376
-        $this->deactivateIncompatibleAddon(
377
-            'Automated Upcoming Event Notifications',
378
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
-            '1.0.0.beta.091',
380
-            'load_espresso_automated_upcoming_event_notification',
381
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
-        );
383
-        do_action('AHEE__EE_System__load_espresso_addons');
384
-        // if the WP API basic auth plugin isn't already loaded, load it now.
385
-        // We want it for mobile apps. Just include the entire plugin
386
-        // also, don't load the basic auth when a plugin is getting activated, because
387
-        // it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
-        // and causes a fatal error
389
-        if (($this->request->isWordPressApi() || $this->request->isApi())
390
-            && $this->request->getRequestParam('activate') !== 'true'
391
-            && ! function_exists('json_basic_auth_handler')
392
-            && ! function_exists('json_basic_auth_error')
393
-            && ! in_array(
394
-                $this->request->getRequestParam('action'),
395
-                array('activate', 'activate-selected'),
396
-                true
397
-            )
398
-        ) {
399
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
400
-        }
401
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
402
-    }
403
-
404
-
405
-    /**
406
-     * detect_activations_or_upgrades
407
-     * Checks for activation or upgrade of core first;
408
-     * then also checks if any registered addons have been activated or upgraded
409
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
410
-     * which runs during the WP 'plugins_loaded' action at priority 3
411
-     *
412
-     * @access public
413
-     * @return void
414
-     */
415
-    public function detect_activations_or_upgrades()
416
-    {
417
-        // first off: let's make sure to handle core
418
-        $this->detect_if_activation_or_upgrade();
419
-        foreach ($this->registry->addons as $addon) {
420
-            if ($addon instanceof EE_Addon) {
421
-                // detect teh request type for that addon
422
-                $addon->detect_req_type();
423
-            }
424
-        }
425
-    }
426
-
427
-
428
-    /**
429
-     * detect_if_activation_or_upgrade
430
-     * Takes care of detecting whether this is a brand new install or code upgrade,
431
-     * and either setting up the DB or setting up maintenance mode etc.
432
-     *
433
-     * @access public
434
-     * @return void
435
-     */
436
-    public function detect_if_activation_or_upgrade()
437
-    {
438
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
439
-        // check if db has been updated, or if its a brand-new installation
440
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
441
-        $request_type = $this->detect_req_type($espresso_db_update);
442
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
443
-        switch ($request_type) {
444
-            case EE_System::req_type_new_activation:
445
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
446
-                $this->_handle_core_version_change($espresso_db_update);
447
-                break;
448
-            case EE_System::req_type_reactivation:
449
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
450
-                $this->_handle_core_version_change($espresso_db_update);
451
-                break;
452
-            case EE_System::req_type_upgrade:
453
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
454
-                // migrations may be required now that we've upgraded
455
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
456
-                $this->_handle_core_version_change($espresso_db_update);
457
-                break;
458
-            case EE_System::req_type_downgrade:
459
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
460
-                // its possible migrations are no longer required
461
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
462
-                $this->_handle_core_version_change($espresso_db_update);
463
-                break;
464
-            case EE_System::req_type_normal:
465
-            default:
466
-                break;
467
-        }
468
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
469
-    }
470
-
471
-
472
-    /**
473
-     * Updates the list of installed versions and sets hooks for
474
-     * initializing the database later during the request
475
-     *
476
-     * @param array $espresso_db_update
477
-     */
478
-    private function _handle_core_version_change($espresso_db_update)
479
-    {
480
-        $this->update_list_of_installed_versions($espresso_db_update);
481
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
482
-        add_action(
483
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
484
-            array($this, 'initialize_db_if_no_migrations_required')
485
-        );
486
-    }
487
-
488
-
489
-    /**
490
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
491
-     * information about what versions of EE have been installed and activated,
492
-     * NOT necessarily the state of the database
493
-     *
494
-     * @param mixed $espresso_db_update           the value of the WordPress option.
495
-     *                                            If not supplied, fetches it from the options table
496
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
497
-     */
498
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
499
-    {
500
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
501
-        if (! $espresso_db_update) {
502
-            $espresso_db_update = get_option('espresso_db_update');
503
-        }
504
-        // check that option is an array
505
-        if (! is_array($espresso_db_update)) {
506
-            // if option is FALSE, then it never existed
507
-            if ($espresso_db_update === false) {
508
-                // make $espresso_db_update an array and save option with autoload OFF
509
-                $espresso_db_update = array();
510
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
511
-            } else {
512
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
513
-                $espresso_db_update = array($espresso_db_update => array());
514
-                update_option('espresso_db_update', $espresso_db_update);
515
-            }
516
-        } else {
517
-            $corrected_db_update = array();
518
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
519
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
520
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
521
-                    // the key is an int, and the value IS NOT an array
522
-                    // so it must be numerically-indexed, where values are versions installed...
523
-                    // fix it!
524
-                    $version_string = $should_be_array;
525
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
526
-                } else {
527
-                    // ok it checks out
528
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
529
-                }
530
-            }
531
-            $espresso_db_update = $corrected_db_update;
532
-            update_option('espresso_db_update', $espresso_db_update);
533
-        }
534
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
535
-        return $espresso_db_update;
536
-    }
537
-
538
-
539
-    /**
540
-     * Does the traditional work of setting up the plugin's database and adding default data.
541
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
542
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
543
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
544
-     * so that it will be done when migrations are finished
545
-     *
546
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
547
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
548
-     *                                       This is a resource-intensive job
549
-     *                                       so we prefer to only do it when necessary
550
-     * @return void
551
-     * @throws EE_Error
552
-     */
553
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
554
-    {
555
-        $request_type = $this->detect_req_type();
556
-        // only initialize system if we're not in maintenance mode.
557
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
558
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
559
-            $rewrite_rules = $this->loader->getShared(
560
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
561
-            );
562
-            $rewrite_rules->flush();
563
-            if ($verify_schema) {
564
-                EEH_Activation::initialize_db_and_folders();
565
-            }
566
-            EEH_Activation::initialize_db_content();
567
-            EEH_Activation::system_initialization();
568
-            if ($initialize_addons_too) {
569
-                $this->initialize_addons();
570
-            }
571
-        } else {
572
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
573
-        }
574
-        if ($request_type === EE_System::req_type_new_activation
575
-            || $request_type === EE_System::req_type_reactivation
576
-            || (
577
-                $request_type === EE_System::req_type_upgrade
578
-                && $this->is_major_version_change()
579
-            )
580
-        ) {
581
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
582
-        }
583
-    }
584
-
585
-
586
-    /**
587
-     * Initializes the db for all registered addons
588
-     *
589
-     * @throws EE_Error
590
-     */
591
-    public function initialize_addons()
592
-    {
593
-        // foreach registered addon, make sure its db is up-to-date too
594
-        foreach ($this->registry->addons as $addon) {
595
-            if ($addon instanceof EE_Addon) {
596
-                $addon->initialize_db_if_no_migrations_required();
597
-            }
598
-        }
599
-    }
600
-
601
-
602
-    /**
603
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
604
-     *
605
-     * @param    array  $version_history
606
-     * @param    string $current_version_to_add version to be added to the version history
607
-     * @return    boolean success as to whether or not this option was changed
608
-     */
609
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
610
-    {
611
-        if (! $version_history) {
612
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
613
-        }
614
-        if ($current_version_to_add === null) {
615
-            $current_version_to_add = espresso_version();
616
-        }
617
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
618
-        // re-save
619
-        return update_option('espresso_db_update', $version_history);
620
-    }
621
-
622
-
623
-    /**
624
-     * Detects if the current version indicated in the has existed in the list of
625
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
626
-     *
627
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
628
-     *                                  If not supplied, fetches it from the options table.
629
-     *                                  Also, caches its result so later parts of the code can also know whether
630
-     *                                  there's been an update or not. This way we can add the current version to
631
-     *                                  espresso_db_update, but still know if this is a new install or not
632
-     * @return int one of the constants on EE_System::req_type_
633
-     */
634
-    public function detect_req_type($espresso_db_update = null)
635
-    {
636
-        if ($this->_req_type === null) {
637
-            $espresso_db_update = ! empty($espresso_db_update)
638
-                ? $espresso_db_update
639
-                : $this->fix_espresso_db_upgrade_option();
640
-            $this->_req_type = EE_System::detect_req_type_given_activation_history(
641
-                $espresso_db_update,
642
-                'ee_espresso_activation',
643
-                espresso_version()
644
-            );
645
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
646
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
647
-        }
648
-        return $this->_req_type;
649
-    }
650
-
651
-
652
-    /**
653
-     * Returns whether or not there was a non-micro version change (ie, change in either
654
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
655
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
656
-     *
657
-     * @param $activation_history
658
-     * @return bool
659
-     */
660
-    private function _detect_major_version_change($activation_history)
661
-    {
662
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
663
-        $previous_version_parts = explode('.', $previous_version);
664
-        $current_version_parts = explode('.', espresso_version());
665
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
666
-               && ($previous_version_parts[0] !== $current_version_parts[0]
667
-                   || $previous_version_parts[1] !== $current_version_parts[1]
668
-               );
669
-    }
670
-
671
-
672
-    /**
673
-     * Returns true if either the major or minor version of EE changed during this request.
674
-     * 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
675
-     *
676
-     * @return bool
677
-     */
678
-    public function is_major_version_change()
679
-    {
680
-        return $this->_major_version_change;
681
-    }
682
-
683
-
684
-    /**
685
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
686
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
687
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
688
-     * just activated to (for core that will always be espresso_version())
689
-     *
690
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
691
-     *                                                 ee plugin. for core that's 'espresso_db_update'
692
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
693
-     *                                                 indicate that this plugin was just activated
694
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
695
-     *                                                 espresso_version())
696
-     * @return int one of the constants on EE_System::req_type_*
697
-     */
698
-    public static function detect_req_type_given_activation_history(
699
-        $activation_history_for_addon,
700
-        $activation_indicator_option_name,
701
-        $version_to_upgrade_to
702
-    ) {
703
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
704
-        if ($activation_history_for_addon) {
705
-            // it exists, so this isn't a completely new install
706
-            // check if this version already in that list of previously installed versions
707
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
708
-                // it a version we haven't seen before
709
-                if ($version_is_higher === 1) {
710
-                    $req_type = EE_System::req_type_upgrade;
711
-                } else {
712
-                    $req_type = EE_System::req_type_downgrade;
713
-                }
714
-                delete_option($activation_indicator_option_name);
715
-            } else {
716
-                // its not an update. maybe a reactivation?
717
-                if (get_option($activation_indicator_option_name, false)) {
718
-                    if ($version_is_higher === -1) {
719
-                        $req_type = EE_System::req_type_downgrade;
720
-                    } elseif ($version_is_higher === 0) {
721
-                        // we've seen this version before, but it's an activation. must be a reactivation
722
-                        $req_type = EE_System::req_type_reactivation;
723
-                    } else {// $version_is_higher === 1
724
-                        $req_type = EE_System::req_type_upgrade;
725
-                    }
726
-                    delete_option($activation_indicator_option_name);
727
-                } else {
728
-                    // we've seen this version before and the activation indicate doesn't show it was just activated
729
-                    if ($version_is_higher === -1) {
730
-                        $req_type = EE_System::req_type_downgrade;
731
-                    } elseif ($version_is_higher === 0) {
732
-                        // we've seen this version before and it's not an activation. its normal request
733
-                        $req_type = EE_System::req_type_normal;
734
-                    } else {// $version_is_higher === 1
735
-                        $req_type = EE_System::req_type_upgrade;
736
-                    }
737
-                }
738
-            }
739
-        } else {
740
-            // brand new install
741
-            $req_type = EE_System::req_type_new_activation;
742
-            delete_option($activation_indicator_option_name);
743
-        }
744
-        return $req_type;
745
-    }
746
-
747
-
748
-    /**
749
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
750
-     * the $activation_history_for_addon
751
-     *
752
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
753
-     *                                             sometimes containing 'unknown-date'
754
-     * @param string $version_to_upgrade_to        (current version)
755
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
756
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
757
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
758
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
759
-     */
760
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
761
-    {
762
-        // find the most recently-activated version
763
-        $most_recently_active_version =
764
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
765
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
766
-    }
767
-
768
-
769
-    /**
770
-     * Gets the most recently active version listed in the activation history,
771
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
772
-     *
773
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
774
-     *                                   sometimes containing 'unknown-date'
775
-     * @return string
776
-     */
777
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
778
-    {
779
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
780
-        $most_recently_active_version = '0.0.0.dev.000';
781
-        if (is_array($activation_history)) {
782
-            foreach ($activation_history as $version => $times_activated) {
783
-                // check there is a record of when this version was activated. Otherwise,
784
-                // mark it as unknown
785
-                if (! $times_activated) {
786
-                    $times_activated = array('unknown-date');
787
-                }
788
-                if (is_string($times_activated)) {
789
-                    $times_activated = array($times_activated);
790
-                }
791
-                foreach ($times_activated as $an_activation) {
792
-                    if ($an_activation !== 'unknown-date'
793
-                        && $an_activation
794
-                           > $most_recently_active_version_activation) {
795
-                        $most_recently_active_version = $version;
796
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
797
-                            ? '1970-01-01 00:00:00'
798
-                            : $an_activation;
799
-                    }
800
-                }
801
-            }
802
-        }
803
-        return $most_recently_active_version;
804
-    }
805
-
806
-
807
-    /**
808
-     * This redirects to the about EE page after activation
809
-     *
810
-     * @return void
811
-     */
812
-    public function redirect_to_about_ee()
813
-    {
814
-        $notices = EE_Error::get_notices(false);
815
-        // if current user is an admin and it's not an ajax or rest request
816
-        if (! isset($notices['errors'])
817
-            && $this->request->isAdmin()
818
-            && apply_filters(
819
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
820
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
821
-            )
822
-        ) {
823
-            $query_params = array('page' => 'espresso_about');
824
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
825
-                $query_params['new_activation'] = true;
826
-            }
827
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
828
-                $query_params['reactivation'] = true;
829
-            }
830
-            $url = add_query_arg($query_params, admin_url('admin.php'));
831
-            wp_safe_redirect($url);
832
-            exit();
833
-        }
834
-    }
835
-
836
-
837
-    /**
838
-     * load_core_configuration
839
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
840
-     * which runs during the WP 'plugins_loaded' action at priority 5
841
-     *
842
-     * @return void
843
-     * @throws ReflectionException
844
-     * @throws Exception
845
-     */
846
-    public function load_core_configuration()
847
-    {
848
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
849
-        $this->loader->getShared('EE_Load_Textdomain');
850
-        // load textdomain
851
-        EE_Load_Textdomain::load_textdomain();
852
-        // load caf stuff a chance to play during the activation process too.
853
-        $this->_maybe_brew_regular();
854
-        // load and setup EE_Config and EE_Network_Config
855
-        $config = $this->loader->getShared('EE_Config');
856
-        $this->loader->getShared('EE_Network_Config');
857
-        // setup autoloaders
858
-        // enable logging?
859
-        if ($config->admin->use_remote_logging) {
860
-            $this->loader->getShared('EE_Log');
861
-        }
862
-        // check for activation errors
863
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
864
-        if ($activation_errors) {
865
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
866
-            update_option('ee_plugin_activation_errors', false);
867
-        }
868
-        // get model names
869
-        $this->_parse_model_names();
870
-        // configure custom post type definitions
871
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
872
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
873
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
874
-    }
875
-
876
-
877
-    /**
878
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
879
-     *
880
-     * @return void
881
-     * @throws ReflectionException
882
-     */
883
-    private function _parse_model_names()
884
-    {
885
-        // get all the files in the EE_MODELS folder that end in .model.php
886
-        $models = glob(EE_MODELS . '*.model.php');
887
-        $model_names = array();
888
-        $non_abstract_db_models = array();
889
-        foreach ($models as $model) {
890
-            // get model classname
891
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
892
-            $short_name = str_replace('EEM_', '', $classname);
893
-            $reflectionClass = new ReflectionClass($classname);
894
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
895
-                $non_abstract_db_models[ $short_name ] = $classname;
896
-            }
897
-            $model_names[ $short_name ] = $classname;
898
-        }
899
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
900
-        $this->registry->non_abstract_db_models = apply_filters(
901
-            'FHEE__EE_System__parse_implemented_model_names',
902
-            $non_abstract_db_models
903
-        );
904
-    }
905
-
906
-
907
-    /**
908
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
909
-     * that need to be setup before our EE_System launches.
910
-     *
911
-     * @return void
912
-     * @throws DomainException
913
-     * @throws InvalidArgumentException
914
-     * @throws InvalidDataTypeException
915
-     * @throws InvalidInterfaceException
916
-     * @throws InvalidClassException
917
-     * @throws InvalidFilePathException
918
-     */
919
-    private function _maybe_brew_regular()
920
-    {
921
-        /** @var Domain $domain */
922
-        $domain = DomainFactory::getShared(
923
-            new FullyQualifiedName(
924
-                'EventEspresso\core\domain\Domain'
925
-            ),
926
-            array(
927
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
928
-                Version::fromString(espresso_version()),
929
-            )
930
-        );
931
-        if ($domain->isCaffeinated()) {
932
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
933
-        }
934
-    }
935
-
936
-
937
-    /**
938
-     * @since 4.9.71.p
939
-     * @throws Exception
940
-     */
941
-    public function loadRouteMatchSpecifications()
942
-    {
943
-        try {
944
-            $this->loader->getShared(
945
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
946
-            );
947
-        } catch (Exception $exception) {
948
-            new ExceptionStackTraceDisplay($exception);
949
-        }
950
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
951
-    }
952
-
953
-
954
-    /**
955
-     * register_shortcodes_modules_and_widgets
956
-     * generate lists of shortcodes and modules, then verify paths and classes
957
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
958
-     * which runs during the WP 'plugins_loaded' action at priority 7
959
-     *
960
-     * @access public
961
-     * @return void
962
-     * @throws Exception
963
-     */
964
-    public function register_shortcodes_modules_and_widgets()
965
-    {
966
-        if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
967
-            try {
968
-                // load, register, and add shortcodes the new way
969
-                $this->loader->getShared(
970
-                    'EventEspresso\core\services\shortcodes\ShortcodesManager',
971
-                    array(
972
-                        // and the old way, but we'll put it under control of the new system
973
-                        EE_Config::getLegacyShortcodesManager(),
974
-                    )
975
-                );
976
-            } catch (Exception $exception) {
977
-                new ExceptionStackTraceDisplay($exception);
978
-            }
979
-        }
980
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
981
-        // check for addons using old hook point
982
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
983
-            $this->_incompatible_addon_error();
984
-        }
985
-    }
986
-
987
-
988
-    /**
989
-     * _incompatible_addon_error
990
-     *
991
-     * @access public
992
-     * @return void
993
-     */
994
-    private function _incompatible_addon_error()
995
-    {
996
-        // get array of classes hooking into here
997
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
998
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
999
-        );
1000
-        if (! empty($class_names)) {
1001
-            $msg = __(
1002
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1003
-                'event_espresso'
1004
-            );
1005
-            $msg .= '<ul>';
1006
-            foreach ($class_names as $class_name) {
1007
-                $msg .= '<li><b>Event Espresso - '
1008
-                        . str_replace(
1009
-                            array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1010
-                            '',
1011
-                            $class_name
1012
-                        ) . '</b></li>';
1013
-            }
1014
-            $msg .= '</ul>';
1015
-            $msg .= __(
1016
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1017
-                'event_espresso'
1018
-            );
1019
-            // save list of incompatible addons to wp-options for later use
1020
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1021
-            if (is_admin()) {
1022
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1023
-            }
1024
-        }
1025
-    }
1026
-
1027
-
1028
-    /**
1029
-     * brew_espresso
1030
-     * begins the process of setting hooks for initializing EE in the correct order
1031
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1032
-     * which runs during the WP 'plugins_loaded' action at priority 9
1033
-     *
1034
-     * @return void
1035
-     */
1036
-    public function brew_espresso()
1037
-    {
1038
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1039
-        // load some final core systems
1040
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1041
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1042
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1043
-        add_action('init', array($this, 'load_controllers'), 7);
1044
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1045
-        add_action('init', array($this, 'initialize'), 10);
1046
-        add_action('init', array($this, 'initialize_last'), 100);
1047
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1048
-            // pew pew pew
1049
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1050
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1051
-        }
1052
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1053
-    }
1054
-
1055
-
1056
-    /**
1057
-     *    set_hooks_for_core
1058
-     *
1059
-     * @access public
1060
-     * @return    void
1061
-     * @throws EE_Error
1062
-     */
1063
-    public function set_hooks_for_core()
1064
-    {
1065
-        $this->_deactivate_incompatible_addons();
1066
-        do_action('AHEE__EE_System__set_hooks_for_core');
1067
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1068
-        // caps need to be initialized on every request so that capability maps are set.
1069
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1070
-        $this->registry->CAP->init_caps();
1071
-    }
1072
-
1073
-
1074
-    /**
1075
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1076
-     * deactivates any addons considered incompatible with the current version of EE
1077
-     */
1078
-    private function _deactivate_incompatible_addons()
1079
-    {
1080
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1081
-        if (! empty($incompatible_addons)) {
1082
-            $active_plugins = get_option('active_plugins', array());
1083
-            foreach ($active_plugins as $active_plugin) {
1084
-                foreach ($incompatible_addons as $incompatible_addon) {
1085
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1086
-                        unset($_GET['activate']);
1087
-                        espresso_deactivate_plugin($active_plugin);
1088
-                    }
1089
-                }
1090
-            }
1091
-        }
1092
-    }
1093
-
1094
-
1095
-    /**
1096
-     *    perform_activations_upgrades_and_migrations
1097
-     *
1098
-     * @access public
1099
-     * @return    void
1100
-     */
1101
-    public function perform_activations_upgrades_and_migrations()
1102
-    {
1103
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1104
-    }
1105
-
1106
-
1107
-    /**
1108
-     * @return void
1109
-     * @throws DomainException
1110
-     */
1111
-    public function load_CPTs_and_session()
1112
-    {
1113
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1114
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1115
-        $register_custom_taxonomies = $this->loader->getShared(
1116
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1117
-        );
1118
-        $register_custom_taxonomies->registerCustomTaxonomies();
1119
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1120
-        $register_custom_post_types = $this->loader->getShared(
1121
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1122
-        );
1123
-        $register_custom_post_types->registerCustomPostTypes();
1124
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1125
-        $register_custom_taxonomy_terms = $this->loader->getShared(
1126
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1127
-        );
1128
-        $register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1129
-        // load legacy Custom Post Types and Taxonomies
1130
-        $this->loader->getShared('EE_Register_CPTs');
1131
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1132
-    }
1133
-
1134
-
1135
-    /**
1136
-     * load_controllers
1137
-     * this is the best place to load any additional controllers that needs access to EE core.
1138
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1139
-     * time
1140
-     *
1141
-     * @access public
1142
-     * @return void
1143
-     */
1144
-    public function load_controllers()
1145
-    {
1146
-        do_action('AHEE__EE_System__load_controllers__start');
1147
-        // let's get it started
1148
-        if (! $this->maintenance_mode->level()
1149
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1150
-        ) {
1151
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1152
-            $this->loader->getShared('EE_Front_Controller');
1153
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1154
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1155
-            $this->loader->getShared('EE_Admin');
1156
-        } elseif ($this->request->isWordPressHeartbeat()) {
1157
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1158
-        }
1159
-        do_action('AHEE__EE_System__load_controllers__complete');
1160
-    }
1161
-
1162
-
1163
-    /**
1164
-     * core_loaded_and_ready
1165
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1166
-     *
1167
-     * @access public
1168
-     * @return void
1169
-     * @throws Exception
1170
-     */
1171
-    public function core_loaded_and_ready()
1172
-    {
1173
-        if ($this->request->isAdmin()
1174
-            || $this->request->isFrontend()
1175
-            || $this->request->isIframe()
1176
-            || $this->request->isWordPressApi()
1177
-        ) {
1178
-            try {
1179
-                $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1180
-                $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1181
-                if ($this->canLoadBlocks()) {
1182
-                    $this->loader->getShared(
1183
-                        'EventEspresso\core\services\editor\BlockRegistrationManager'
1184
-                    );
1185
-                }
1186
-            } catch (Exception $exception) {
1187
-                new ExceptionStackTraceDisplay($exception);
1188
-            }
1189
-        }
1190
-        if ($this->request->isAdmin()
1191
-            || $this->request->isEeAjax()
1192
-            || $this->request->isFrontend()
1193
-        ) {
1194
-            $this->loader->getShared('EE_Session');
1195
-        }
1196
-        // integrate WP_Query with the EE models
1197
-        $this->loader->getShared('EE_CPT_Strategy');
1198
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1199
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1200
-        // builders require these even on the front-end
1201
-        require_once EE_PUBLIC . 'template_tags.php';
1202
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * initialize
1208
-     * this is the best place to begin initializing client code
1209
-     *
1210
-     * @access public
1211
-     * @return void
1212
-     */
1213
-    public function initialize()
1214
-    {
1215
-        do_action('AHEE__EE_System__initialize');
1216
-    }
1217
-
1218
-
1219
-    /**
1220
-     * initialize_last
1221
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1222
-     * initialize has done so
1223
-     *
1224
-     * @access public
1225
-     * @return void
1226
-     */
1227
-    public function initialize_last()
1228
-    {
1229
-        do_action('AHEE__EE_System__initialize_last');
1230
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1231
-        $rewrite_rules = $this->loader->getShared(
1232
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1233
-        );
1234
-        $rewrite_rules->flushRewriteRules();
1235
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1236
-        if (($this->request->isAjax() || $this->request->isAdmin())
1237
-            && $this->maintenance_mode->models_can_query()) {
1238
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1239
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1240
-        }
1241
-    }
1242
-
1243
-
1244
-    /**
1245
-     * @return void
1246
-     * @throws EE_Error
1247
-     */
1248
-    public function addEspressoToolbar()
1249
-    {
1250
-        $this->loader->getShared(
1251
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1252
-            array($this->registry->CAP)
1253
-        );
1254
-    }
1255
-
1256
-
1257
-    /**
1258
-     * do_not_cache
1259
-     * sets no cache headers and defines no cache constants for WP plugins
1260
-     *
1261
-     * @access public
1262
-     * @return void
1263
-     */
1264
-    public static function do_not_cache()
1265
-    {
1266
-        // set no cache constants
1267
-        if (! defined('DONOTCACHEPAGE')) {
1268
-            define('DONOTCACHEPAGE', true);
1269
-        }
1270
-        if (! defined('DONOTCACHCEOBJECT')) {
1271
-            define('DONOTCACHCEOBJECT', true);
1272
-        }
1273
-        if (! defined('DONOTCACHEDB')) {
1274
-            define('DONOTCACHEDB', true);
1275
-        }
1276
-        // add no cache headers
1277
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1278
-        // plus a little extra for nginx and Google Chrome
1279
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1280
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1281
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1282
-    }
1283
-
1284
-
1285
-    /**
1286
-     *    extra_nocache_headers
1287
-     *
1288
-     * @access    public
1289
-     * @param $headers
1290
-     * @return    array
1291
-     */
1292
-    public static function extra_nocache_headers($headers)
1293
-    {
1294
-        // for NGINX
1295
-        $headers['X-Accel-Expires'] = 0;
1296
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1297
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1298
-        return $headers;
1299
-    }
1300
-
1301
-
1302
-    /**
1303
-     *    nocache_headers
1304
-     *
1305
-     * @access    public
1306
-     * @return    void
1307
-     */
1308
-    public static function nocache_headers()
1309
-    {
1310
-        nocache_headers();
1311
-    }
1312
-
1313
-
1314
-    /**
1315
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1316
-     * never returned with the function.
1317
-     *
1318
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1319
-     * @return array
1320
-     */
1321
-    public function remove_pages_from_wp_list_pages($exclude_array)
1322
-    {
1323
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1324
-    }
1325
-
1326
-
1327
-    /**
1328
-     * Return whether blocks can be registered/loaded or not.
1329
-     * @return bool
1330
-     */
1331
-    private function canLoadBlocks()
1332
-    {
1333
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1334
-               && function_exists('register_block_type')
1335
-               // don't load blocks if in the Divi page builder editor context
1336
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
1337
-               && ! $this->request->getRequestParam('et_fb', false);
1338
-    }
30
+	/**
31
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
+	 */
34
+	const req_type_normal = 0;
35
+
36
+	/**
37
+	 * Indicates this is a brand new installation of EE so we should install
38
+	 * tables and default data etc
39
+	 */
40
+	const req_type_new_activation = 1;
41
+
42
+	/**
43
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
45
+	 * and that default data is setup too
46
+	 */
47
+	const req_type_reactivation = 2;
48
+
49
+	/**
50
+	 * indicates that EE has been upgraded since its previous request.
51
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
52
+	 */
53
+	const req_type_upgrade = 3;
54
+
55
+	/**
56
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
+	 */
58
+	const req_type_downgrade = 4;
59
+
60
+	/**
61
+	 * @deprecated since version 4.6.0.dev.006
62
+	 * Now whenever a new_activation is detected the request type is still just
63
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
+	 * (Specifically, when the migration manager indicates migrations are finished
67
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
+	 */
69
+	const req_type_activation_but_not_installed = 5;
70
+
71
+	/**
72
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
+	 */
74
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
+
76
+	/**
77
+	 * @var EE_System $_instance
78
+	 */
79
+	private static $_instance;
80
+
81
+	/**
82
+	 * @var EE_Registry $registry
83
+	 */
84
+	private $registry;
85
+
86
+	/**
87
+	 * @var LoaderInterface $loader
88
+	 */
89
+	private $loader;
90
+
91
+	/**
92
+	 * @var EE_Capabilities $capabilities
93
+	 */
94
+	private $capabilities;
95
+
96
+	/**
97
+	 * @var RequestInterface $request
98
+	 */
99
+	private $request;
100
+
101
+	/**
102
+	 * @var EE_Maintenance_Mode $maintenance_mode
103
+	 */
104
+	private $maintenance_mode;
105
+
106
+	/**
107
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
+	 *
110
+	 * @var int $_req_type
111
+	 */
112
+	private $_req_type;
113
+
114
+	/**
115
+	 * Whether or not there was a non-micro version change in EE core version during this request
116
+	 *
117
+	 * @var boolean $_major_version_change
118
+	 */
119
+	private $_major_version_change = false;
120
+
121
+	/**
122
+	 * A Context DTO dedicated solely to identifying the current request type.
123
+	 *
124
+	 * @var RequestTypeContextCheckerInterface $request_type
125
+	 */
126
+	private $request_type;
127
+
128
+
129
+	/**
130
+	 * @singleton method used to instantiate class object
131
+	 * @param EE_Registry|null         $registry
132
+	 * @param LoaderInterface|null     $loader
133
+	 * @param RequestInterface|null    $request
134
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
135
+	 * @return EE_System
136
+	 */
137
+	public static function instance(
138
+		EE_Registry $registry = null,
139
+		LoaderInterface $loader = null,
140
+		RequestInterface $request = null,
141
+		EE_Maintenance_Mode $maintenance_mode = null
142
+	) {
143
+		// check if class object is instantiated
144
+		if (! self::$_instance instanceof EE_System) {
145
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
+		}
147
+		return self::$_instance;
148
+	}
149
+
150
+
151
+	/**
152
+	 * resets the instance and returns it
153
+	 *
154
+	 * @return EE_System
155
+	 */
156
+	public static function reset()
157
+	{
158
+		self::$_instance->_req_type = null;
159
+		// make sure none of the old hooks are left hanging around
160
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
+		// we need to reset the migration manager in order for it to detect DMSs properly
162
+		EE_Data_Migration_Manager::reset();
163
+		self::instance()->detect_activations_or_upgrades();
164
+		self::instance()->perform_activations_upgrades_and_migrations();
165
+		return self::instance();
166
+	}
167
+
168
+
169
+	/**
170
+	 * sets hooks for running rest of system
171
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
+	 * starting EE Addons from any other point may lead to problems
173
+	 *
174
+	 * @param EE_Registry         $registry
175
+	 * @param LoaderInterface     $loader
176
+	 * @param RequestInterface    $request
177
+	 * @param EE_Maintenance_Mode $maintenance_mode
178
+	 */
179
+	private function __construct(
180
+		EE_Registry $registry,
181
+		LoaderInterface $loader,
182
+		RequestInterface $request,
183
+		EE_Maintenance_Mode $maintenance_mode
184
+	) {
185
+		$this->registry = $registry;
186
+		$this->loader = $loader;
187
+		$this->request = $request;
188
+		$this->maintenance_mode = $maintenance_mode;
189
+		do_action('AHEE__EE_System__construct__begin', $this);
190
+		add_action(
191
+			'AHEE__EE_Bootstrap__load_espresso_addons',
192
+			array($this, 'loadCapabilities'),
193
+			5
194
+		);
195
+		add_action(
196
+			'AHEE__EE_Bootstrap__load_espresso_addons',
197
+			array($this, 'loadCommandBus'),
198
+			7
199
+		);
200
+		add_action(
201
+			'AHEE__EE_Bootstrap__load_espresso_addons',
202
+			array($this, 'loadPluginApi'),
203
+			9
204
+		);
205
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
+		add_action(
207
+			'AHEE__EE_Bootstrap__load_espresso_addons',
208
+			array($this, 'load_espresso_addons')
209
+		);
210
+		// when an ee addon is activated, we want to call the core hook(s) again
211
+		// because the newly-activated addon didn't get a chance to run at all
212
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
+		// detect whether install or upgrade
214
+		add_action(
215
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
+			array($this, 'detect_activations_or_upgrades'),
217
+			3
218
+		);
219
+		// load EE_Config, EE_Textdomain, etc
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_core_configuration',
222
+			array($this, 'load_core_configuration'),
223
+			5
224
+		);
225
+		// load specifications for matching routes to current request
226
+		add_action(
227
+			'AHEE__EE_Bootstrap__load_core_configuration',
228
+			array($this, 'loadRouteMatchSpecifications')
229
+		);
230
+		// load EE_Config, EE_Textdomain, etc
231
+		add_action(
232
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
+			array($this, 'register_shortcodes_modules_and_widgets'),
234
+			7
235
+		);
236
+		// you wanna get going? I wanna get going... let's get going!
237
+		add_action(
238
+			'AHEE__EE_Bootstrap__brew_espresso',
239
+			array($this, 'brew_espresso'),
240
+			9
241
+		);
242
+		// other housekeeping
243
+		// exclude EE critical pages from wp_list_pages
244
+		add_filter(
245
+			'wp_list_pages_excludes',
246
+			array($this, 'remove_pages_from_wp_list_pages'),
247
+			10
248
+		);
249
+		// ALL EE Addons should use the following hook point to attach their initial setup too
250
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
+		do_action('AHEE__EE_System__construct__complete', $this);
252
+	}
253
+
254
+
255
+	/**
256
+	 * load and setup EE_Capabilities
257
+	 *
258
+	 * @return void
259
+	 * @throws EE_Error
260
+	 */
261
+	public function loadCapabilities()
262
+	{
263
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
264
+		add_action(
265
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
266
+			function () {
267
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
+			}
269
+		);
270
+	}
271
+
272
+
273
+	/**
274
+	 * create and cache the CommandBus, and also add middleware
275
+	 * The CapChecker middleware requires the use of EE_Capabilities
276
+	 * which is why we need to load the CommandBus after Caps are set up
277
+	 *
278
+	 * @return void
279
+	 * @throws EE_Error
280
+	 */
281
+	public function loadCommandBus()
282
+	{
283
+		$this->loader->getShared(
284
+			'CommandBusInterface',
285
+			array(
286
+				null,
287
+				apply_filters(
288
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
+					array(
290
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
+					)
293
+				),
294
+			)
295
+		);
296
+	}
297
+
298
+
299
+	/**
300
+	 * @return void
301
+	 * @throws EE_Error
302
+	 */
303
+	public function loadPluginApi()
304
+	{
305
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
306
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
307
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
+		$this->loader->getShared('EE_Request_Handler');
309
+	}
310
+
311
+
312
+	/**
313
+	 * @param string $addon_name
314
+	 * @param string $version_constant
315
+	 * @param string $min_version_required
316
+	 * @param string $load_callback
317
+	 * @param string $plugin_file_constant
318
+	 * @return void
319
+	 */
320
+	private function deactivateIncompatibleAddon(
321
+		$addon_name,
322
+		$version_constant,
323
+		$min_version_required,
324
+		$load_callback,
325
+		$plugin_file_constant
326
+	) {
327
+		if (! defined($version_constant)) {
328
+			return;
329
+		}
330
+		$addon_version = constant($version_constant);
331
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
+			if (! function_exists('deactivate_plugins')) {
334
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
+			}
336
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
+			unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
+			EE_Error::add_error(
339
+				sprintf(
340
+					esc_html__(
341
+						'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
342
+						'event_espresso'
343
+					),
344
+					$addon_name,
345
+					$min_version_required
346
+				),
347
+				__FILE__,
348
+				__FUNCTION__ . "({$addon_name})",
349
+				__LINE__
350
+			);
351
+			EE_Error::get_notices(false, true);
352
+		}
353
+	}
354
+
355
+
356
+	/**
357
+	 * load_espresso_addons
358
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
359
+	 * this is hooked into both:
360
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
361
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
362
+	 *    and the WP 'activate_plugin' hook point
363
+	 *
364
+	 * @access public
365
+	 * @return void
366
+	 */
367
+	public function load_espresso_addons()
368
+	{
369
+		$this->deactivateIncompatibleAddon(
370
+			'Wait Lists',
371
+			'EE_WAIT_LISTS_VERSION',
372
+			'1.0.0.beta.074',
373
+			'load_espresso_wait_lists',
374
+			'EE_WAIT_LISTS_PLUGIN_FILE'
375
+		);
376
+		$this->deactivateIncompatibleAddon(
377
+			'Automated Upcoming Event Notifications',
378
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
+			'1.0.0.beta.091',
380
+			'load_espresso_automated_upcoming_event_notification',
381
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
+		);
383
+		do_action('AHEE__EE_System__load_espresso_addons');
384
+		// if the WP API basic auth plugin isn't already loaded, load it now.
385
+		// We want it for mobile apps. Just include the entire plugin
386
+		// also, don't load the basic auth when a plugin is getting activated, because
387
+		// it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
+		// and causes a fatal error
389
+		if (($this->request->isWordPressApi() || $this->request->isApi())
390
+			&& $this->request->getRequestParam('activate') !== 'true'
391
+			&& ! function_exists('json_basic_auth_handler')
392
+			&& ! function_exists('json_basic_auth_error')
393
+			&& ! in_array(
394
+				$this->request->getRequestParam('action'),
395
+				array('activate', 'activate-selected'),
396
+				true
397
+			)
398
+		) {
399
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
400
+		}
401
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
402
+	}
403
+
404
+
405
+	/**
406
+	 * detect_activations_or_upgrades
407
+	 * Checks for activation or upgrade of core first;
408
+	 * then also checks if any registered addons have been activated or upgraded
409
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
410
+	 * which runs during the WP 'plugins_loaded' action at priority 3
411
+	 *
412
+	 * @access public
413
+	 * @return void
414
+	 */
415
+	public function detect_activations_or_upgrades()
416
+	{
417
+		// first off: let's make sure to handle core
418
+		$this->detect_if_activation_or_upgrade();
419
+		foreach ($this->registry->addons as $addon) {
420
+			if ($addon instanceof EE_Addon) {
421
+				// detect teh request type for that addon
422
+				$addon->detect_req_type();
423
+			}
424
+		}
425
+	}
426
+
427
+
428
+	/**
429
+	 * detect_if_activation_or_upgrade
430
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
431
+	 * and either setting up the DB or setting up maintenance mode etc.
432
+	 *
433
+	 * @access public
434
+	 * @return void
435
+	 */
436
+	public function detect_if_activation_or_upgrade()
437
+	{
438
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
439
+		// check if db has been updated, or if its a brand-new installation
440
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
441
+		$request_type = $this->detect_req_type($espresso_db_update);
442
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
443
+		switch ($request_type) {
444
+			case EE_System::req_type_new_activation:
445
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
446
+				$this->_handle_core_version_change($espresso_db_update);
447
+				break;
448
+			case EE_System::req_type_reactivation:
449
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
450
+				$this->_handle_core_version_change($espresso_db_update);
451
+				break;
452
+			case EE_System::req_type_upgrade:
453
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
454
+				// migrations may be required now that we've upgraded
455
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
456
+				$this->_handle_core_version_change($espresso_db_update);
457
+				break;
458
+			case EE_System::req_type_downgrade:
459
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
460
+				// its possible migrations are no longer required
461
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
462
+				$this->_handle_core_version_change($espresso_db_update);
463
+				break;
464
+			case EE_System::req_type_normal:
465
+			default:
466
+				break;
467
+		}
468
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
469
+	}
470
+
471
+
472
+	/**
473
+	 * Updates the list of installed versions and sets hooks for
474
+	 * initializing the database later during the request
475
+	 *
476
+	 * @param array $espresso_db_update
477
+	 */
478
+	private function _handle_core_version_change($espresso_db_update)
479
+	{
480
+		$this->update_list_of_installed_versions($espresso_db_update);
481
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
482
+		add_action(
483
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
484
+			array($this, 'initialize_db_if_no_migrations_required')
485
+		);
486
+	}
487
+
488
+
489
+	/**
490
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
491
+	 * information about what versions of EE have been installed and activated,
492
+	 * NOT necessarily the state of the database
493
+	 *
494
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
495
+	 *                                            If not supplied, fetches it from the options table
496
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
497
+	 */
498
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
499
+	{
500
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
501
+		if (! $espresso_db_update) {
502
+			$espresso_db_update = get_option('espresso_db_update');
503
+		}
504
+		// check that option is an array
505
+		if (! is_array($espresso_db_update)) {
506
+			// if option is FALSE, then it never existed
507
+			if ($espresso_db_update === false) {
508
+				// make $espresso_db_update an array and save option with autoload OFF
509
+				$espresso_db_update = array();
510
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
511
+			} else {
512
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
513
+				$espresso_db_update = array($espresso_db_update => array());
514
+				update_option('espresso_db_update', $espresso_db_update);
515
+			}
516
+		} else {
517
+			$corrected_db_update = array();
518
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
519
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
520
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
521
+					// the key is an int, and the value IS NOT an array
522
+					// so it must be numerically-indexed, where values are versions installed...
523
+					// fix it!
524
+					$version_string = $should_be_array;
525
+					$corrected_db_update[ $version_string ] = array('unknown-date');
526
+				} else {
527
+					// ok it checks out
528
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
529
+				}
530
+			}
531
+			$espresso_db_update = $corrected_db_update;
532
+			update_option('espresso_db_update', $espresso_db_update);
533
+		}
534
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
535
+		return $espresso_db_update;
536
+	}
537
+
538
+
539
+	/**
540
+	 * Does the traditional work of setting up the plugin's database and adding default data.
541
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
542
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
543
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
544
+	 * so that it will be done when migrations are finished
545
+	 *
546
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
547
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
548
+	 *                                       This is a resource-intensive job
549
+	 *                                       so we prefer to only do it when necessary
550
+	 * @return void
551
+	 * @throws EE_Error
552
+	 */
553
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
554
+	{
555
+		$request_type = $this->detect_req_type();
556
+		// only initialize system if we're not in maintenance mode.
557
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
558
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
559
+			$rewrite_rules = $this->loader->getShared(
560
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
561
+			);
562
+			$rewrite_rules->flush();
563
+			if ($verify_schema) {
564
+				EEH_Activation::initialize_db_and_folders();
565
+			}
566
+			EEH_Activation::initialize_db_content();
567
+			EEH_Activation::system_initialization();
568
+			if ($initialize_addons_too) {
569
+				$this->initialize_addons();
570
+			}
571
+		} else {
572
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
573
+		}
574
+		if ($request_type === EE_System::req_type_new_activation
575
+			|| $request_type === EE_System::req_type_reactivation
576
+			|| (
577
+				$request_type === EE_System::req_type_upgrade
578
+				&& $this->is_major_version_change()
579
+			)
580
+		) {
581
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
582
+		}
583
+	}
584
+
585
+
586
+	/**
587
+	 * Initializes the db for all registered addons
588
+	 *
589
+	 * @throws EE_Error
590
+	 */
591
+	public function initialize_addons()
592
+	{
593
+		// foreach registered addon, make sure its db is up-to-date too
594
+		foreach ($this->registry->addons as $addon) {
595
+			if ($addon instanceof EE_Addon) {
596
+				$addon->initialize_db_if_no_migrations_required();
597
+			}
598
+		}
599
+	}
600
+
601
+
602
+	/**
603
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
604
+	 *
605
+	 * @param    array  $version_history
606
+	 * @param    string $current_version_to_add version to be added to the version history
607
+	 * @return    boolean success as to whether or not this option was changed
608
+	 */
609
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
610
+	{
611
+		if (! $version_history) {
612
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
613
+		}
614
+		if ($current_version_to_add === null) {
615
+			$current_version_to_add = espresso_version();
616
+		}
617
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
618
+		// re-save
619
+		return update_option('espresso_db_update', $version_history);
620
+	}
621
+
622
+
623
+	/**
624
+	 * Detects if the current version indicated in the has existed in the list of
625
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
626
+	 *
627
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
628
+	 *                                  If not supplied, fetches it from the options table.
629
+	 *                                  Also, caches its result so later parts of the code can also know whether
630
+	 *                                  there's been an update or not. This way we can add the current version to
631
+	 *                                  espresso_db_update, but still know if this is a new install or not
632
+	 * @return int one of the constants on EE_System::req_type_
633
+	 */
634
+	public function detect_req_type($espresso_db_update = null)
635
+	{
636
+		if ($this->_req_type === null) {
637
+			$espresso_db_update = ! empty($espresso_db_update)
638
+				? $espresso_db_update
639
+				: $this->fix_espresso_db_upgrade_option();
640
+			$this->_req_type = EE_System::detect_req_type_given_activation_history(
641
+				$espresso_db_update,
642
+				'ee_espresso_activation',
643
+				espresso_version()
644
+			);
645
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
646
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
647
+		}
648
+		return $this->_req_type;
649
+	}
650
+
651
+
652
+	/**
653
+	 * Returns whether or not there was a non-micro version change (ie, change in either
654
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
655
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
656
+	 *
657
+	 * @param $activation_history
658
+	 * @return bool
659
+	 */
660
+	private function _detect_major_version_change($activation_history)
661
+	{
662
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
663
+		$previous_version_parts = explode('.', $previous_version);
664
+		$current_version_parts = explode('.', espresso_version());
665
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
666
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
667
+				   || $previous_version_parts[1] !== $current_version_parts[1]
668
+			   );
669
+	}
670
+
671
+
672
+	/**
673
+	 * Returns true if either the major or minor version of EE changed during this request.
674
+	 * 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
675
+	 *
676
+	 * @return bool
677
+	 */
678
+	public function is_major_version_change()
679
+	{
680
+		return $this->_major_version_change;
681
+	}
682
+
683
+
684
+	/**
685
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
686
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
687
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
688
+	 * just activated to (for core that will always be espresso_version())
689
+	 *
690
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
691
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
692
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
693
+	 *                                                 indicate that this plugin was just activated
694
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
695
+	 *                                                 espresso_version())
696
+	 * @return int one of the constants on EE_System::req_type_*
697
+	 */
698
+	public static function detect_req_type_given_activation_history(
699
+		$activation_history_for_addon,
700
+		$activation_indicator_option_name,
701
+		$version_to_upgrade_to
702
+	) {
703
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
704
+		if ($activation_history_for_addon) {
705
+			// it exists, so this isn't a completely new install
706
+			// check if this version already in that list of previously installed versions
707
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
708
+				// it a version we haven't seen before
709
+				if ($version_is_higher === 1) {
710
+					$req_type = EE_System::req_type_upgrade;
711
+				} else {
712
+					$req_type = EE_System::req_type_downgrade;
713
+				}
714
+				delete_option($activation_indicator_option_name);
715
+			} else {
716
+				// its not an update. maybe a reactivation?
717
+				if (get_option($activation_indicator_option_name, false)) {
718
+					if ($version_is_higher === -1) {
719
+						$req_type = EE_System::req_type_downgrade;
720
+					} elseif ($version_is_higher === 0) {
721
+						// we've seen this version before, but it's an activation. must be a reactivation
722
+						$req_type = EE_System::req_type_reactivation;
723
+					} else {// $version_is_higher === 1
724
+						$req_type = EE_System::req_type_upgrade;
725
+					}
726
+					delete_option($activation_indicator_option_name);
727
+				} else {
728
+					// we've seen this version before and the activation indicate doesn't show it was just activated
729
+					if ($version_is_higher === -1) {
730
+						$req_type = EE_System::req_type_downgrade;
731
+					} elseif ($version_is_higher === 0) {
732
+						// we've seen this version before and it's not an activation. its normal request
733
+						$req_type = EE_System::req_type_normal;
734
+					} else {// $version_is_higher === 1
735
+						$req_type = EE_System::req_type_upgrade;
736
+					}
737
+				}
738
+			}
739
+		} else {
740
+			// brand new install
741
+			$req_type = EE_System::req_type_new_activation;
742
+			delete_option($activation_indicator_option_name);
743
+		}
744
+		return $req_type;
745
+	}
746
+
747
+
748
+	/**
749
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
750
+	 * the $activation_history_for_addon
751
+	 *
752
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
753
+	 *                                             sometimes containing 'unknown-date'
754
+	 * @param string $version_to_upgrade_to        (current version)
755
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
756
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
757
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
758
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
759
+	 */
760
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
761
+	{
762
+		// find the most recently-activated version
763
+		$most_recently_active_version =
764
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
765
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
766
+	}
767
+
768
+
769
+	/**
770
+	 * Gets the most recently active version listed in the activation history,
771
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
772
+	 *
773
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
774
+	 *                                   sometimes containing 'unknown-date'
775
+	 * @return string
776
+	 */
777
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
778
+	{
779
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
780
+		$most_recently_active_version = '0.0.0.dev.000';
781
+		if (is_array($activation_history)) {
782
+			foreach ($activation_history as $version => $times_activated) {
783
+				// check there is a record of when this version was activated. Otherwise,
784
+				// mark it as unknown
785
+				if (! $times_activated) {
786
+					$times_activated = array('unknown-date');
787
+				}
788
+				if (is_string($times_activated)) {
789
+					$times_activated = array($times_activated);
790
+				}
791
+				foreach ($times_activated as $an_activation) {
792
+					if ($an_activation !== 'unknown-date'
793
+						&& $an_activation
794
+						   > $most_recently_active_version_activation) {
795
+						$most_recently_active_version = $version;
796
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
797
+							? '1970-01-01 00:00:00'
798
+							: $an_activation;
799
+					}
800
+				}
801
+			}
802
+		}
803
+		return $most_recently_active_version;
804
+	}
805
+
806
+
807
+	/**
808
+	 * This redirects to the about EE page after activation
809
+	 *
810
+	 * @return void
811
+	 */
812
+	public function redirect_to_about_ee()
813
+	{
814
+		$notices = EE_Error::get_notices(false);
815
+		// if current user is an admin and it's not an ajax or rest request
816
+		if (! isset($notices['errors'])
817
+			&& $this->request->isAdmin()
818
+			&& apply_filters(
819
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
820
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
821
+			)
822
+		) {
823
+			$query_params = array('page' => 'espresso_about');
824
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
825
+				$query_params['new_activation'] = true;
826
+			}
827
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
828
+				$query_params['reactivation'] = true;
829
+			}
830
+			$url = add_query_arg($query_params, admin_url('admin.php'));
831
+			wp_safe_redirect($url);
832
+			exit();
833
+		}
834
+	}
835
+
836
+
837
+	/**
838
+	 * load_core_configuration
839
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
840
+	 * which runs during the WP 'plugins_loaded' action at priority 5
841
+	 *
842
+	 * @return void
843
+	 * @throws ReflectionException
844
+	 * @throws Exception
845
+	 */
846
+	public function load_core_configuration()
847
+	{
848
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
849
+		$this->loader->getShared('EE_Load_Textdomain');
850
+		// load textdomain
851
+		EE_Load_Textdomain::load_textdomain();
852
+		// load caf stuff a chance to play during the activation process too.
853
+		$this->_maybe_brew_regular();
854
+		// load and setup EE_Config and EE_Network_Config
855
+		$config = $this->loader->getShared('EE_Config');
856
+		$this->loader->getShared('EE_Network_Config');
857
+		// setup autoloaders
858
+		// enable logging?
859
+		if ($config->admin->use_remote_logging) {
860
+			$this->loader->getShared('EE_Log');
861
+		}
862
+		// check for activation errors
863
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
864
+		if ($activation_errors) {
865
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
866
+			update_option('ee_plugin_activation_errors', false);
867
+		}
868
+		// get model names
869
+		$this->_parse_model_names();
870
+		// configure custom post type definitions
871
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
872
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
873
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
874
+	}
875
+
876
+
877
+	/**
878
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
879
+	 *
880
+	 * @return void
881
+	 * @throws ReflectionException
882
+	 */
883
+	private function _parse_model_names()
884
+	{
885
+		// get all the files in the EE_MODELS folder that end in .model.php
886
+		$models = glob(EE_MODELS . '*.model.php');
887
+		$model_names = array();
888
+		$non_abstract_db_models = array();
889
+		foreach ($models as $model) {
890
+			// get model classname
891
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
892
+			$short_name = str_replace('EEM_', '', $classname);
893
+			$reflectionClass = new ReflectionClass($classname);
894
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
895
+				$non_abstract_db_models[ $short_name ] = $classname;
896
+			}
897
+			$model_names[ $short_name ] = $classname;
898
+		}
899
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
900
+		$this->registry->non_abstract_db_models = apply_filters(
901
+			'FHEE__EE_System__parse_implemented_model_names',
902
+			$non_abstract_db_models
903
+		);
904
+	}
905
+
906
+
907
+	/**
908
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
909
+	 * that need to be setup before our EE_System launches.
910
+	 *
911
+	 * @return void
912
+	 * @throws DomainException
913
+	 * @throws InvalidArgumentException
914
+	 * @throws InvalidDataTypeException
915
+	 * @throws InvalidInterfaceException
916
+	 * @throws InvalidClassException
917
+	 * @throws InvalidFilePathException
918
+	 */
919
+	private function _maybe_brew_regular()
920
+	{
921
+		/** @var Domain $domain */
922
+		$domain = DomainFactory::getShared(
923
+			new FullyQualifiedName(
924
+				'EventEspresso\core\domain\Domain'
925
+			),
926
+			array(
927
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
928
+				Version::fromString(espresso_version()),
929
+			)
930
+		);
931
+		if ($domain->isCaffeinated()) {
932
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
933
+		}
934
+	}
935
+
936
+
937
+	/**
938
+	 * @since 4.9.71.p
939
+	 * @throws Exception
940
+	 */
941
+	public function loadRouteMatchSpecifications()
942
+	{
943
+		try {
944
+			$this->loader->getShared(
945
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
946
+			);
947
+		} catch (Exception $exception) {
948
+			new ExceptionStackTraceDisplay($exception);
949
+		}
950
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
951
+	}
952
+
953
+
954
+	/**
955
+	 * register_shortcodes_modules_and_widgets
956
+	 * generate lists of shortcodes and modules, then verify paths and classes
957
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
958
+	 * which runs during the WP 'plugins_loaded' action at priority 7
959
+	 *
960
+	 * @access public
961
+	 * @return void
962
+	 * @throws Exception
963
+	 */
964
+	public function register_shortcodes_modules_and_widgets()
965
+	{
966
+		if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
967
+			try {
968
+				// load, register, and add shortcodes the new way
969
+				$this->loader->getShared(
970
+					'EventEspresso\core\services\shortcodes\ShortcodesManager',
971
+					array(
972
+						// and the old way, but we'll put it under control of the new system
973
+						EE_Config::getLegacyShortcodesManager(),
974
+					)
975
+				);
976
+			} catch (Exception $exception) {
977
+				new ExceptionStackTraceDisplay($exception);
978
+			}
979
+		}
980
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
981
+		// check for addons using old hook point
982
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
983
+			$this->_incompatible_addon_error();
984
+		}
985
+	}
986
+
987
+
988
+	/**
989
+	 * _incompatible_addon_error
990
+	 *
991
+	 * @access public
992
+	 * @return void
993
+	 */
994
+	private function _incompatible_addon_error()
995
+	{
996
+		// get array of classes hooking into here
997
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
998
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
999
+		);
1000
+		if (! empty($class_names)) {
1001
+			$msg = __(
1002
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1003
+				'event_espresso'
1004
+			);
1005
+			$msg .= '<ul>';
1006
+			foreach ($class_names as $class_name) {
1007
+				$msg .= '<li><b>Event Espresso - '
1008
+						. str_replace(
1009
+							array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1010
+							'',
1011
+							$class_name
1012
+						) . '</b></li>';
1013
+			}
1014
+			$msg .= '</ul>';
1015
+			$msg .= __(
1016
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1017
+				'event_espresso'
1018
+			);
1019
+			// save list of incompatible addons to wp-options for later use
1020
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1021
+			if (is_admin()) {
1022
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1023
+			}
1024
+		}
1025
+	}
1026
+
1027
+
1028
+	/**
1029
+	 * brew_espresso
1030
+	 * begins the process of setting hooks for initializing EE in the correct order
1031
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1032
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1033
+	 *
1034
+	 * @return void
1035
+	 */
1036
+	public function brew_espresso()
1037
+	{
1038
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1039
+		// load some final core systems
1040
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1041
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1042
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1043
+		add_action('init', array($this, 'load_controllers'), 7);
1044
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1045
+		add_action('init', array($this, 'initialize'), 10);
1046
+		add_action('init', array($this, 'initialize_last'), 100);
1047
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1048
+			// pew pew pew
1049
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1050
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1051
+		}
1052
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1053
+	}
1054
+
1055
+
1056
+	/**
1057
+	 *    set_hooks_for_core
1058
+	 *
1059
+	 * @access public
1060
+	 * @return    void
1061
+	 * @throws EE_Error
1062
+	 */
1063
+	public function set_hooks_for_core()
1064
+	{
1065
+		$this->_deactivate_incompatible_addons();
1066
+		do_action('AHEE__EE_System__set_hooks_for_core');
1067
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1068
+		// caps need to be initialized on every request so that capability maps are set.
1069
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1070
+		$this->registry->CAP->init_caps();
1071
+	}
1072
+
1073
+
1074
+	/**
1075
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1076
+	 * deactivates any addons considered incompatible with the current version of EE
1077
+	 */
1078
+	private function _deactivate_incompatible_addons()
1079
+	{
1080
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1081
+		if (! empty($incompatible_addons)) {
1082
+			$active_plugins = get_option('active_plugins', array());
1083
+			foreach ($active_plugins as $active_plugin) {
1084
+				foreach ($incompatible_addons as $incompatible_addon) {
1085
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1086
+						unset($_GET['activate']);
1087
+						espresso_deactivate_plugin($active_plugin);
1088
+					}
1089
+				}
1090
+			}
1091
+		}
1092
+	}
1093
+
1094
+
1095
+	/**
1096
+	 *    perform_activations_upgrades_and_migrations
1097
+	 *
1098
+	 * @access public
1099
+	 * @return    void
1100
+	 */
1101
+	public function perform_activations_upgrades_and_migrations()
1102
+	{
1103
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1104
+	}
1105
+
1106
+
1107
+	/**
1108
+	 * @return void
1109
+	 * @throws DomainException
1110
+	 */
1111
+	public function load_CPTs_and_session()
1112
+	{
1113
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1114
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1115
+		$register_custom_taxonomies = $this->loader->getShared(
1116
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1117
+		);
1118
+		$register_custom_taxonomies->registerCustomTaxonomies();
1119
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1120
+		$register_custom_post_types = $this->loader->getShared(
1121
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1122
+		);
1123
+		$register_custom_post_types->registerCustomPostTypes();
1124
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1125
+		$register_custom_taxonomy_terms = $this->loader->getShared(
1126
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1127
+		);
1128
+		$register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1129
+		// load legacy Custom Post Types and Taxonomies
1130
+		$this->loader->getShared('EE_Register_CPTs');
1131
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1132
+	}
1133
+
1134
+
1135
+	/**
1136
+	 * load_controllers
1137
+	 * this is the best place to load any additional controllers that needs access to EE core.
1138
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1139
+	 * time
1140
+	 *
1141
+	 * @access public
1142
+	 * @return void
1143
+	 */
1144
+	public function load_controllers()
1145
+	{
1146
+		do_action('AHEE__EE_System__load_controllers__start');
1147
+		// let's get it started
1148
+		if (! $this->maintenance_mode->level()
1149
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1150
+		) {
1151
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1152
+			$this->loader->getShared('EE_Front_Controller');
1153
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1154
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1155
+			$this->loader->getShared('EE_Admin');
1156
+		} elseif ($this->request->isWordPressHeartbeat()) {
1157
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1158
+		}
1159
+		do_action('AHEE__EE_System__load_controllers__complete');
1160
+	}
1161
+
1162
+
1163
+	/**
1164
+	 * core_loaded_and_ready
1165
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1166
+	 *
1167
+	 * @access public
1168
+	 * @return void
1169
+	 * @throws Exception
1170
+	 */
1171
+	public function core_loaded_and_ready()
1172
+	{
1173
+		if ($this->request->isAdmin()
1174
+			|| $this->request->isFrontend()
1175
+			|| $this->request->isIframe()
1176
+			|| $this->request->isWordPressApi()
1177
+		) {
1178
+			try {
1179
+				$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1180
+				$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1181
+				if ($this->canLoadBlocks()) {
1182
+					$this->loader->getShared(
1183
+						'EventEspresso\core\services\editor\BlockRegistrationManager'
1184
+					);
1185
+				}
1186
+			} catch (Exception $exception) {
1187
+				new ExceptionStackTraceDisplay($exception);
1188
+			}
1189
+		}
1190
+		if ($this->request->isAdmin()
1191
+			|| $this->request->isEeAjax()
1192
+			|| $this->request->isFrontend()
1193
+		) {
1194
+			$this->loader->getShared('EE_Session');
1195
+		}
1196
+		// integrate WP_Query with the EE models
1197
+		$this->loader->getShared('EE_CPT_Strategy');
1198
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1199
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1200
+		// builders require these even on the front-end
1201
+		require_once EE_PUBLIC . 'template_tags.php';
1202
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * initialize
1208
+	 * this is the best place to begin initializing client code
1209
+	 *
1210
+	 * @access public
1211
+	 * @return void
1212
+	 */
1213
+	public function initialize()
1214
+	{
1215
+		do_action('AHEE__EE_System__initialize');
1216
+	}
1217
+
1218
+
1219
+	/**
1220
+	 * initialize_last
1221
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1222
+	 * initialize has done so
1223
+	 *
1224
+	 * @access public
1225
+	 * @return void
1226
+	 */
1227
+	public function initialize_last()
1228
+	{
1229
+		do_action('AHEE__EE_System__initialize_last');
1230
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1231
+		$rewrite_rules = $this->loader->getShared(
1232
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1233
+		);
1234
+		$rewrite_rules->flushRewriteRules();
1235
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1236
+		if (($this->request->isAjax() || $this->request->isAdmin())
1237
+			&& $this->maintenance_mode->models_can_query()) {
1238
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1239
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1240
+		}
1241
+	}
1242
+
1243
+
1244
+	/**
1245
+	 * @return void
1246
+	 * @throws EE_Error
1247
+	 */
1248
+	public function addEspressoToolbar()
1249
+	{
1250
+		$this->loader->getShared(
1251
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1252
+			array($this->registry->CAP)
1253
+		);
1254
+	}
1255
+
1256
+
1257
+	/**
1258
+	 * do_not_cache
1259
+	 * sets no cache headers and defines no cache constants for WP plugins
1260
+	 *
1261
+	 * @access public
1262
+	 * @return void
1263
+	 */
1264
+	public static function do_not_cache()
1265
+	{
1266
+		// set no cache constants
1267
+		if (! defined('DONOTCACHEPAGE')) {
1268
+			define('DONOTCACHEPAGE', true);
1269
+		}
1270
+		if (! defined('DONOTCACHCEOBJECT')) {
1271
+			define('DONOTCACHCEOBJECT', true);
1272
+		}
1273
+		if (! defined('DONOTCACHEDB')) {
1274
+			define('DONOTCACHEDB', true);
1275
+		}
1276
+		// add no cache headers
1277
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1278
+		// plus a little extra for nginx and Google Chrome
1279
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1280
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1281
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1282
+	}
1283
+
1284
+
1285
+	/**
1286
+	 *    extra_nocache_headers
1287
+	 *
1288
+	 * @access    public
1289
+	 * @param $headers
1290
+	 * @return    array
1291
+	 */
1292
+	public static function extra_nocache_headers($headers)
1293
+	{
1294
+		// for NGINX
1295
+		$headers['X-Accel-Expires'] = 0;
1296
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1297
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1298
+		return $headers;
1299
+	}
1300
+
1301
+
1302
+	/**
1303
+	 *    nocache_headers
1304
+	 *
1305
+	 * @access    public
1306
+	 * @return    void
1307
+	 */
1308
+	public static function nocache_headers()
1309
+	{
1310
+		nocache_headers();
1311
+	}
1312
+
1313
+
1314
+	/**
1315
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1316
+	 * never returned with the function.
1317
+	 *
1318
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1319
+	 * @return array
1320
+	 */
1321
+	public function remove_pages_from_wp_list_pages($exclude_array)
1322
+	{
1323
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1324
+	}
1325
+
1326
+
1327
+	/**
1328
+	 * Return whether blocks can be registered/loaded or not.
1329
+	 * @return bool
1330
+	 */
1331
+	private function canLoadBlocks()
1332
+	{
1333
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1334
+			   && function_exists('register_block_type')
1335
+			   // don't load blocks if in the Divi page builder editor context
1336
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
1337
+			   && ! $this->request->getRequestParam('et_fb', false);
1338
+	}
1339 1339
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Message_Resource_Manager.lib.php 2 patches
Indentation   +1115 added lines, -1115 removed lines patch added patch discarded remove patch
@@ -12,1119 +12,1119 @@
 block discarded – undo
12 12
 class EE_Message_Resource_Manager
13 13
 {
14 14
 
15
-    /**
16
-     * This option in the database is used to keep a record of message types that have been activated for a messenger
17
-     * at some point in the history of the site.  It is utilized by the implementation of the 'force' flag in
18
-     * EE_Register_Message_Type.  The force flag is an indication of whether a message type should be activated by
19
-     * default when the message type is registered.  However, if a user has explicitly deactivated a message type, then
20
-     * the force flag is ignored.  The method by which the code knows whether to ignore this flag is via this option.
21
-     * Note, that this is NOT a historical record.  Its entirely possible for a message type to have been activated for
22
-     * a messenger and yet not have a record in this option.  This occurs when a message type is inactivated through an
23
-     * automated process (when an add-on registering the message type deactivates, or when some other code calls the
24
-     * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to ensure
25
-     * the "force" flag is respected if that message type is later re-registered.
26
-     *
27
-     * This option should NOT be used to determine the current "active" state of a message type for a given messenger.
28
-     *
29
-     * The name of this option (and related methods/properties) is due to matching the original intended purpose for the
30
-     * option that got superseded by later behaviour requirements.
31
-     */
32
-    const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger';
33
-
34
-    /**
35
-     * @type boolean $_initialized
36
-     */
37
-    protected $_initialized = false;
38
-
39
-    /**
40
-     * @type EE_Messenger_Collection $_messenger_collection_loader
41
-     */
42
-    protected $_messenger_collection_loader;
43
-
44
-    /**
45
-     * @type EE_Message_Type_Collection $_message_type_collection_loader
46
-     */
47
-    protected $_message_type_collection_loader;
48
-
49
-    /**
50
-     * @type EEM_Message_Template_Group $_message_template_group_model
51
-     */
52
-    protected $_message_template_group_model;
53
-
54
-    /**
55
-     * @type EE_messenger[]
56
-     */
57
-    protected $_installed_messengers = array();
58
-
59
-    /**
60
-     * @type EE_message_type[]
61
-     */
62
-    protected $_installed_message_types = array();
63
-
64
-    /**
65
-     * Array of active messengers.
66
-     * Format is this:
67
-     * array(
68
-     *      'messenger_name' => EE_messenger
69
-     * )
70
-     *
71
-     * @type EE_messenger[]
72
-     */
73
-    protected $_active_messengers = array();
74
-
75
-    /**
76
-     * Formatted array of active message types grouped per messenger.
77
-     * Format is this:
78
-     * array(
79
-     *      'messenger_name' => array(
80
-     *          'settings' => array(
81
-     *              '{messenger_name}-message_types' => array(
82
-     *                  'message_type_name' => array() //variable array of settings corresponding to message type.
83
-     *              )
84
-     *          )
85
-     *      )
86
-     * )
87
-     *
88
-     * @type array
89
-     */
90
-    protected $_active_message_types = array();
91
-
92
-
93
-    /**
94
-     * This holds the array of messengers and their corresponding message types that have
95
-     * been activated on a site at some point.  This is an important record that helps the messages system
96
-     * not accidentally reactivate something that was intentionally deactivated by a user.
97
-     *
98
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
99
-     *
100
-     * @type array
101
-     */
102
-    protected $_has_activated_messengers_and_message_types = array();
103
-
104
-    /**
105
-     * An array of unique message type contexts across all active message types.
106
-     * The array will be indexed by either 'slugs' or 'all'.
107
-     * The slugs index contains an array indexed by unique context slugs with the latest label representation for that
108
-     * slug. array(
109
-     *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
110
-     * );
111
-     * The all index returns an array in this format:
112
-     * array(
113
-     *      'message_type_name' => array(
114
-     *          'context_slug' => array(
115
-     *              'label' => 'localized label for context',
116
-     *              'description' => 'localized description for context'
117
-     *          )
118
-     *      )
119
-     * );
120
-     *
121
-     * @type array
122
-     */
123
-    protected $_contexts = array();
124
-
125
-
126
-    /**
127
-     * EE_Message_Resource_Manager constructor.
128
-     *
129
-     * @param \EE_Messenger_Collection_Loader    $Messenger_Collection_Loader
130
-     * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader
131
-     * @param \EEM_Message_Template_Group        $Message_Template_Group_Model
132
-     */
133
-    public function __construct(
134
-        EE_Messenger_Collection_Loader $Messenger_Collection_Loader,
135
-        EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader,
136
-        EEM_Message_Template_Group $Message_Template_Group_Model
137
-    ) {
138
-        $this->_messenger_collection_loader    = $Messenger_Collection_Loader;
139
-        $this->_message_type_collection_loader = $Message_Type_Collection_Loader;
140
-        $this->_message_template_group_model   = $Message_Template_Group_Model;
141
-    }
142
-
143
-
144
-    /**
145
-     * @return void
146
-     */
147
-    protected function _initialize_collections()
148
-    {
149
-        if ($this->_initialized) {
150
-            return;
151
-        }
152
-        $this->_initialized = true;
153
-        $this->_messenger_collection_loader->load_messengers_from_folder();
154
-        $this->_message_type_collection_loader->load_message_types_from_folder();
155
-        $this->get_has_activated_messengers_option(true);
156
-        $this->_set_active_messengers_and_message_types();
157
-    }
158
-
159
-
160
-    /**
161
-     * @return EE_Messenger_Collection
162
-     */
163
-    public function messenger_collection()
164
-    {
165
-        $this->_initialize_collections();
166
-        return $this->_messenger_collection_loader->messenger_collection();
167
-    }
168
-
169
-
170
-    /**
171
-     * @return EE_messenger[]
172
-     */
173
-    public function active_messengers()
174
-    {
175
-        $this->_initialize_collections();
176
-        return $this->_active_messengers;
177
-    }
178
-
179
-
180
-    /**
181
-     * @param string $messenger_name
182
-     * @return \EE_messenger
183
-     */
184
-    public function get_messenger($messenger_name)
185
-    {
186
-        return $this->messenger_collection()->get_by_info($messenger_name);
187
-    }
188
-
189
-
190
-    /**
191
-     * This returns the corresponding EE_messenger object for the given string if it is active.
192
-     *
193
-     * @param string $messenger
194
-     * @return EE_messenger | null
195
-     */
196
-    public function get_active_messenger($messenger)
197
-    {
198
-        $this->_initialize_collections();
199
-        return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
200
-    }
201
-
202
-
203
-    /**
204
-     * @return \EE_messenger[]
205
-     */
206
-    public function installed_messengers()
207
-    {
208
-        if (empty($this->_installed_messengers)) {
209
-            $this->_installed_messengers = array();
210
-            $this->messenger_collection()->rewind();
211
-            while ($this->messenger_collection()->valid()) {
212
-                $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
213
-                $this->messenger_collection()->next();
214
-            }
215
-        }
216
-        return $this->_installed_messengers;
217
-    }
218
-
219
-
220
-    /**
221
-     * @param string $messenger_name
222
-     * @return \EE_messenger
223
-     * @throws EE_Error
224
-     */
225
-    public function valid_messenger($messenger_name)
226
-    {
227
-        $messenger = $this->get_messenger($messenger_name);
228
-        if ($messenger instanceof EE_messenger) {
229
-            return $messenger;
230
-        }
231
-        throw new EE_Error(
232
-            sprintf(
233
-                __('The "%1$s" messenger is either invalid or not installed', 'event_espresso'),
234
-                $messenger_name
235
-            )
236
-        );
237
-    }
238
-
239
-
240
-    /**
241
-     * @return EE_Message_Type_Collection
242
-     */
243
-    public function message_type_collection()
244
-    {
245
-        $this->_initialize_collections();
246
-        return $this->_message_type_collection_loader->message_type_collection();
247
-    }
248
-
249
-
250
-    /**
251
-     * @return array
252
-     */
253
-    public function active_message_types()
254
-    {
255
-        $this->_initialize_collections();
256
-        return $this->_active_message_types;
257
-    }
258
-
259
-
260
-    /**
261
-     * @param string $message_type_name
262
-     * @return \EE_message_type
263
-     */
264
-    public function get_message_type($message_type_name)
265
-    {
266
-        return $this->message_type_collection()->get_by_info($message_type_name);
267
-    }
268
-
269
-
270
-    /**
271
-     * This returns the EE_message_type from the active message types array ( if present );
272
-     *
273
-     * @param string $messenger_name
274
-     * @param string $message_type_name
275
-     * @return \EE_message_type|null
276
-     */
277
-    public function get_active_message_type_for_messenger($messenger_name, $message_type_name)
278
-    {
279
-        return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
280
-            ? $this->get_message_type($message_type_name)
281
-            : null;
282
-    }
283
-
284
-
285
-    /**
286
-     * Returns whether the given message type is active for the given messenger.
287
-     *
288
-     * @param string $messenger_name
289
-     * @param string $message_type_name
290
-     * @return bool
291
-     */
292
-    public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293
-    {
294
-        $this->_initialize_collections();
295
-        return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
296
-    }
297
-
298
-
299
-    /**
300
-     * Returns whether the given messenger is active.
301
-     *
302
-     * @param string $messenger_name the name of the messenger to check if active.
303
-     * @return bool
304
-     */
305
-    public function is_messenger_active($messenger_name)
306
-    {
307
-        $this->_initialize_collections();
308
-        return ! empty($this->_active_message_types[ $messenger_name ]);
309
-    }
310
-
311
-
312
-    /**
313
-     * This returns any settings that might be on a message type for a messenger
314
-     *
315
-     * @param string $messenger_name    The slug of the messenger
316
-     * @param string $message_type_name The slug of the message type getting the settings for.
317
-     * @return array
318
-     */
319
-    public function get_message_type_settings_for_messenger($messenger_name, $message_type_name)
320
-    {
321
-        $settings = array();
322
-        if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
-            $settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
-                ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
325
-                : array();
326
-        }
327
-        return $settings;
328
-    }
329
-
330
-
331
-    /**
332
-     * Returns whether the given messenger name has active message types on it.
333
-     * Infers whether the messenger is active or not as well.
334
-     *
335
-     * @param string $messenger_name
336
-     * @return bool
337
-     */
338
-    public function messenger_has_active_message_types($messenger_name)
339
-    {
340
-        $this->_initialize_collections();
341
-        return
342
-            ! empty($this->_active_message_types[ $messenger_name ])
343
-            && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
344
-    }
345
-
346
-
347
-    /**
348
-     * This checks the _active_message_types property for any active message types
349
-     * that are present for the given messenger and returns them.
350
-     *
351
-     * @since 4.9.0
352
-     * @param string $messenger_name The messenger being checked
353
-     * @return EE_message_type[]|array    (empty array if no active_message_types)
354
-     */
355
-    public function get_active_message_types_for_messenger($messenger_name)
356
-    {
357
-        $message_types = array();
358
-        if (! $this->messenger_has_active_message_types($messenger_name)) {
359
-            return $message_types;
360
-        }
361
-        $installed_message_types = $this->installed_message_types();
362
-        foreach ($installed_message_types as $message_type_name => $message_type) {
363
-            if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
-                $message_types[ $message_type_name ] = $message_type;
365
-            }
366
-        }
367
-        return $message_types;
368
-    }
369
-
370
-
371
-    /**
372
-     * This does NOT return the _active_message_types property but
373
-     * simply returns an array of active message type names from that property.
374
-     * (The _active_message_types property is indexed by messenger and active message_types per messenger).
375
-     *
376
-     * @return array message_type references (string)
377
-     */
378
-    public function list_of_active_message_types()
379
-    {
380
-        $active_message_type_names = array();
381
-        $this->_initialize_collections();
382
-        foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
-            if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
384
-                continue;
385
-            }
386
-            foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
-                if (! in_array($message_type_name, $active_message_type_names)) {
388
-                    $active_message_type_names[] = $message_type_name;
389
-                }
390
-            }
391
-        }
392
-        return $active_message_type_names;
393
-    }
394
-
395
-
396
-    /**
397
-     * Same as list_of_active_message_types() except this returns actual EE_message_type objects
398
-     *
399
-     * @since 4.9.0
400
-     * @return \EE_message_type[]
401
-     */
402
-    public function get_active_message_type_objects()
403
-    {
404
-        $active_message_types      = array();
405
-        $installed_message_types   = $this->installed_message_types();
406
-        $active_message_type_names = $this->list_of_active_message_types();
407
-        foreach ($active_message_type_names as $active_message_type_name) {
408
-            if (isset($installed_message_types[ $active_message_type_name ])) {
409
-                $active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
410
-            }
411
-        }
412
-        return $active_message_types;
413
-    }
414
-
415
-
416
-    /**
417
-     * @return \EE_message_type[]
418
-     */
419
-    public function installed_message_types()
420
-    {
421
-        if (empty($this->_installed_message_types)) {
422
-            $this->message_type_collection()->rewind();
423
-            while ($this->message_type_collection()->valid()) {
424
-                $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
425
-                $this->message_type_collection()->next();
426
-            }
427
-        }
428
-        return $this->_installed_message_types;
429
-    }
430
-
431
-
432
-    /**
433
-     * @param string $message_type_name
434
-     * @return \EE_message_type
435
-     * @throws EE_Error
436
-     */
437
-    public function valid_message_type($message_type_name)
438
-    {
439
-        $message_type = $this->get_message_type($message_type_name);
440
-        if ($message_type instanceof EE_message_type) {
441
-            return $message_type;
442
-        }
443
-        throw new EE_Error(
444
-            sprintf(
445
-                __('The "%1$s" message type is either invalid or not installed', 'event_espresso'),
446
-                $message_type_name
447
-            )
448
-        );
449
-    }
450
-
451
-
452
-    /**
453
-     * valid_message_type_for_messenger
454
-     *
455
-     * @param EE_messenger $messenger
456
-     * @param string       $message_type_name
457
-     * @return boolean
458
-     * @throws EE_Error
459
-     */
460
-    public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461
-    {
462
-        $valid_message_types = $messenger->get_valid_message_types();
463
-        if (! in_array($message_type_name, $valid_message_types)) {
464
-            throw new EE_Error(
465
-                sprintf(
466
-                    __(
467
-                        'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger.  Double-check the spelling and verify that message type has been registered as a valid type with the messenger.',
468
-                        'event_espresso'
469
-                    ),
470
-                    $message_type_name,
471
-                    __METHOD__,
472
-                    $messenger->name
473
-                )
474
-            );
475
-        }
476
-        return true;
477
-    }
478
-
479
-
480
-    /**
481
-     * Used to return active messengers array stored in the wp options table.
482
-     * If no value is present in the option then an empty array is returned.
483
-     *
484
-     * @param   bool $reset     If true then we ignore whether the option is cached on the _active_message_types
485
-     *                          property and pull directly from the db.  Otherwise whatever is currently on the
486
-     *                          $_active_message_types property is pulled.
487
-     * @return array
488
-     */
489
-    public function get_active_messengers_option($reset = false)
490
-    {
491
-        if ($reset) {
492
-            $this->_active_message_types = get_option('ee_active_messengers', array());
493
-        }
494
-        return $this->_active_message_types;
495
-    }
496
-
497
-
498
-    /**
499
-     * Used to update the active messengers array stored in the wp options table.
500
-     *
501
-     * @param array $active_messenger_settings Incoming data to save.  If empty, then the internal cached property
502
-     *                                         representing this data is used.
503
-     * @return bool FALSE if not updated, TRUE if updated.
504
-     */
505
-    public function update_active_messengers_option($active_messenger_settings = array())
506
-    {
507
-        $active_messenger_settings = empty($active_messenger_settings) ? $this->_active_message_types : $active_messenger_settings;
508
-        // make sure _active_message_types is updated (this is the internal cache for the settings).
509
-        $this->_active_message_types = $active_messenger_settings;
510
-        return update_option('ee_active_messengers', $active_messenger_settings);
511
-    }
512
-
513
-
514
-    /**
515
-     * Used to return has activated message types for messengers array stored in the wp options table.
516
-     * If no value is present in the option then an empty array is returned.
517
-     * The value is cached on the $_has_activated_messengers_and_message_types property for future calls.
518
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
519
-     *
520
-     * @param   bool $reset Used to indicate that any cached value should be ignored.
521
-     * @return array
522
-     */
523
-    public function get_has_activated_messengers_option($reset = false)
524
-    {
525
-        if ($reset || empty($this->_has_activated_messengers_and_message_types)) {
526
-            $this->_has_activated_messengers_and_message_types = get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, array());
527
-        }
528
-        return $this->_has_activated_messengers_and_message_types;
529
-    }
530
-
531
-
532
-    /**
533
-     * Used to update the has activated option in the db.
534
-     *
535
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
536
-     *
537
-     * @param array $has_activated_messengers Incoming data to save.  If empty, then the internal cached property
538
-     *                                        representing this data is used.
539
-     * @return bool FALSE if not updated, TRUE if updated.
540
-     */
541
-    public function update_has_activated_messengers_option($has_activated_messengers = array())
542
-    {
543
-        // make sure the option has been retrieved from first so we don't overwrite it accidentally.
544
-        if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) {
545
-            $this->get_has_activated_messengers_option();
546
-        }
547
-        $has_activated_messengers = empty($has_activated_messengers)
548
-            ? $this->_has_activated_messengers_and_message_types
549
-            : $has_activated_messengers;
550
-        return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers);
551
-    }
552
-
553
-
554
-    /**
555
-     * wrapper for _set_active_messengers_and_message_types()
556
-     */
557
-    public function reset_active_messengers_and_message_types()
558
-    {
559
-        $this->_set_active_messengers_and_message_types();
560
-    }
561
-
562
-
563
-    /**
564
-     * Generate list of active messengers and message types from collection.
565
-     * This sets up the active messengers from what is present in the database.
566
-     */
567
-    protected function _set_active_messengers_and_message_types()
568
-    {
569
-        // echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n";
570
-        // list of activated messengers as set via the admin
571
-        // note calling `get_active_messengers_options` also initializes the _active_message_types property.
572
-        $this->get_active_messengers_option(true);
573
-        $this->ensure_messengers_are_active(array(), false, true);
574
-        $this->update_active_messengers_option();
575
-        $this->update_has_activated_messengers_option();
576
-    }
577
-
578
-
579
-    /**
580
-     * Ensures that the specified messenger is currently active.
581
-     * If not, activates it and its default message types.
582
-     *
583
-     * @param string $messenger_name
584
-     * @param bool   $update_option Whether to update the option in the db or not.
585
-     * @return boolean true if either already active or successfully activated.
586
-     */
587
-    public function ensure_messenger_is_active($messenger_name, $update_option = true)
588
-    {
589
-        if (! isset($this->_active_messengers[ $messenger_name ])) {
590
-            try {
591
-                $this->activate_messenger($messenger_name, array(), $update_option);
592
-            } catch (EE_Error $e) {
593
-                EE_Error::add_error(
594
-                    $e->getMessage(),
595
-                    __FILE__,
596
-                    __FUNCTION__,
597
-                    __LINE__
598
-                );
599
-                return false;
600
-            }
601
-        }
602
-        return true;
603
-    }
604
-
605
-
606
-    /**
607
-     * This ensures the given array of messenger names is active in the system.
608
-     * Note, this method will not activate any NEW message types for the messenger when it is called. Instead,
609
-     * it will automatically activate the default message types for the messenger if its not active.
610
-     *
611
-     * @param array $messenger_names  Array of messenger names for messengers to be activated.  If an empty array
612
-     *                                (default) then will attempt to set the active messengers from the
613
-     *                                activated_messengers option
614
-     *                                (stored in $_active_message_types property).
615
-     * @param bool  $update_option    Whether to update the related active messengers option.
616
-     * @param bool  $verify           Whether to verify the messengers are installed before activating. Note if this is
617
-     *                                set to true and a messenger is indicated as active, but is NOT installed, then it
618
-     *                                will automatically be deactivated.
619
-     */
620
-    public function ensure_messengers_are_active($messenger_names = array(), $update_option = true, $verify = false)
621
-    {
622
-        $messenger_names = empty($messenger_names) ? array_keys($this->_active_message_types) : $messenger_names;
623
-
624
-        $not_installed = array();
625
-        foreach ($messenger_names as $messenger_name) {
626
-            if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) {
627
-                $not_installed[] = $messenger_name;
628
-                $this->deactivate_messenger($messenger_name);
629
-                continue;
630
-            }
631
-            $this->ensure_messenger_is_active($messenger_name, $update_option);
632
-        }
633
-
634
-        if (! empty($not_installed)) {
635
-            EE_Error::add_error(
636
-                sprintf(
637
-                    __('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
638
-                    '<br />',
639
-                    implode(', ', $not_installed)
640
-                ),
641
-                __FILE__,
642
-                __FUNCTION__,
643
-                __LINE__
644
-            );
645
-        }
646
-    }
647
-
648
-
649
-    /**
650
-     * Ensures that the specified message type for the given messenger is currently active, if not activates it.
651
-     * This ALSO ensures that the given messenger is active as well!
652
-     *
653
-     * @param string $message_type_name message type name.
654
-     * @param        $messenger_name
655
-     * @param bool   $update_option     Whether to update the option in the db or not.
656
-     * @return bool  Returns true if already is active or if was activated successfully.
657
-     * @throws EE_Error
658
-     */
659
-    public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true)
660
-    {
661
-        // grab the messenger to work with.
662
-        $messenger = $this->valid_messenger($messenger_name);
663
-        if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) {
664
-            // ensure messenger is active (that's an inherent coupling between active message types and the
665
-            // messenger they are being activated for.
666
-            try {
667
-                if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668
-                    // all is good so let's just get it active
669
-                    $this->activate_messenger($messenger, array($message_type_name), $update_option);
670
-                }
671
-            } catch (EE_Error $e) {
672
-                EE_Error::add_error(
673
-                    $e->getMessage(),
674
-                    __FILE__,
675
-                    __FUNCTION__,
676
-                    __LINE__
677
-                );
678
-                return false;
679
-            }
680
-        }
681
-        return true;
682
-    }
683
-
684
-
685
-    /**
686
-     * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a
687
-     * messenger are active in one go.
688
-     *
689
-     * @param array  $message_type_names Array of message type names to ensure are active.
690
-     * @param string $messenger_name     The name of the messenger that the message types are to be activated on.
691
-     * @param bool   $update_option      Whether to persist the activation to the database or not (default true).
692
-     */
693
-    public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true)
694
-    {
695
-        $message_type_names = (array) $message_type_names;
696
-        foreach ($message_type_names as $message_type_name) {
697
-            // note, intentionally not updating option here because we're in a loop.
698
-            // We'll follow the instructions of the incoming $update_option argument after the loop.
699
-            $this->ensure_message_type_is_active($message_type_name, $messenger_name, false);
700
-        }
701
-        if ($update_option) {
702
-            $this->update_active_messengers_option();
703
-            $this->update_has_activated_messengers_option();
704
-        }
705
-    }
706
-
707
-
708
-    /**
709
-     * Activates the specified messenger.
710
-     *
711
-     * @param EE_messenger|string $messenger    Instantiated EE_messenger OR messenger name if not already loaded!
712
-     * @param array  $message_type_names        An array of message type names to activate with this messenger.
713
-     *                                          If included we do NOT setup the default message types
714
-     *                                          (assuming they are already setup.)
715
-     * @param bool   $update_active_messengers_option
716
-     * @return array of generated templates
717
-     * @throws EE_Error
718
-     */
719
-    public function activate_messenger(
720
-        $messenger,
721
-        $message_type_names = array(),
722
-        $update_active_messengers_option = true
723
-    ) {
724
-        $templates = array();
725
-        // grab the messenger to work with.
726
-        $messenger = $messenger instanceof EE_messenger
727
-            ? $messenger
728
-            : $this->messenger_collection()->get_by_info($messenger);
729
-        // it's inactive. Activate it.
730
-        if ($messenger instanceof EE_messenger) {
731
-            $this->_active_messengers[ $messenger->name ] = $messenger;
732
-            // activate incoming message types set to be activated with messenger.
733
-            $message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734
-            // setup any initial settings for the messenger if necessary.
735
-            $this->add_settings_for_messenger($messenger->name);
736
-            if ($update_active_messengers_option) {
737
-                $this->update_active_messengers_option();
738
-                $this->update_has_activated_messengers_option();
739
-            }
740
-            // generate new templates if necessary and ensure all related templates that are already in the database are
741
-            // marked active.  Note, this will also deactivate a message type for a messenger if the template
742
-            // cannot be successfully created during its attempt (only happens for global template attempts).
743
-            if (! empty($message_type_names)) {
744
-                $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745
-                EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746
-            }
747
-        }
748
-        return $templates;
749
-    }
750
-
751
-
752
-    /**
753
-     * Activates given message types for the given EE_messenger object.
754
-     * Note: (very important) This method does not persist the activation to the database.
755
-     * See code implementing this method in this class for examples of how to persist.
756
-     *
757
-     * @param \EE_messenger $messenger
758
-     * @param  array        $message_type_names
759
-     * @return array
760
-     */
761
-    protected function _activate_message_types(EE_messenger $messenger, $message_type_names = array())
762
-    {
763
-        // If $message_type_names is empty, AND $this->_active_message_types is empty, then that means
764
-        // things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765
-        // So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766
-        // only override _active_message_types when an explicit array of $message_type_names has been provided.
767
-        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
768
-            ? $messenger->get_default_message_types()
769
-            : (array) $message_type_names;
770
-
771
-        // now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
-        if (! isset($this->_active_message_types[ $messenger->name ])) {
773
-            $this->_active_message_types[ $messenger->name ]['settings'] = array();
774
-        }
775
-
776
-        if ($message_type_names) {
777
-            // cycle thru message types
778
-            foreach ($message_type_names as $message_type_name) {
779
-                // only register the message type as active IF it isn't already active
780
-                // and if its actually installed.
781
-                if (! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
782
-                ) {
783
-                    $this->add_settings_for_message_type($messenger->name, $message_type_name);
784
-                    $this->_set_messenger_has_activated_message_type(
785
-                        $messenger,
786
-                        $message_type_name
787
-                    );
788
-                }
789
-            }
790
-        }
791
-        return $message_type_names;
792
-    }
793
-
794
-
795
-    /**
796
-     * add_settings_for_message_type
797
-     * NOTE This does NOT automatically persist any settings to the db.  Client code should call
798
-     * $this->update_active_messengers_option to persist.
799
-     *
800
-     * @param  string $messenger_name    The name of the messenger adding the settings for
801
-     * @param  string $message_type_name The name of the message type adding the settings for
802
-     * @param  array  $new_settings      Any new settings being set for the message type and messenger
803
-     */
804
-    public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = array())
805
-    {
806
-        // get installed message type from collection
807
-        $message_type      = $this->message_type_collection()->get_by_info($message_type_name);
808
-        $existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name);
809
-        // we need to setup any initial settings for message types
810
-        if ($message_type instanceof EE_message_type) {
811
-            $default_settings = $message_type->get_admin_settings_fields();
812
-            foreach ($default_settings as $field => $values) {
813
-                if (isset($new_settings[ $field ])) {
814
-                    $existing_settings[ $field ] = $new_settings[ $field ];
815
-                    continue;
816
-                }
817
-                if (! isset($existing_settings[ $field ])) {
818
-                    $existing_settings[ $field ] = $values['default'];
819
-                }
820
-            }
821
-        }
822
-        $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
823
-    }
824
-
825
-
826
-    /**
827
-     * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger
828
-     * and message type.
829
-     *
830
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
831
-     *
832
-     * @access protected
833
-     * @param \EE_messenger $messenger
834
-     * @param string        $message_type_name
835
-     */
836
-    protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name)
837
-    {
838
-
839
-        // if _has_activated_messengers_and_message_types is empty then lets ensure its initialized
840
-        if (empty($this->_has_activated_messengers_and_message_types)) {
841
-            $this->get_has_activated_messengers_option();
842
-        }
843
-
844
-        // make sure this messenger has a record in the has_activated array
845
-        if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
846
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
847
-        }
848
-        // check if message type has already been added
849
-        if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
850
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
851
-        }
852
-    }
853
-
854
-
855
-    /**
856
-     * add_settings_for_messenger
857
-     * NOTE This does NOT automatically persist any settings to the db.  Client code should call
858
-     * $this->update_active_messengers_option to persist.
859
-     *
860
-     * @param string $messenger_name The name of the messenger the settings is being added for.
861
-     * @param array  $new_settings   An array of settings to update the existing settings.
862
-     */
863
-    public function add_settings_for_messenger($messenger_name, $new_settings = array())
864
-    {
865
-        $messenger = $this->get_messenger($messenger_name);
866
-        if ($messenger instanceof EE_messenger) {
867
-            $msgr_settings = $messenger->get_admin_settings_fields();
868
-            if (! empty($msgr_settings)) {
869
-                foreach ($msgr_settings as $field => $value) {
870
-                    // is there a new setting for this?
871
-                    if (isset($new_settings[ $field ])) {
872
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
873
-                        continue;
874
-                    }
875
-                    // only set the default if it isn't already set.
876
-                    if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
877
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
878
-                    }
879
-                }
880
-            }
881
-        }
882
-    }
883
-
884
-
885
-    /**
886
-     * deactivate_messenger
887
-     *
888
-     * @param  string|EE_messenger $messenger_name name of messenger
889
-     * @return void
890
-     */
891
-    public function deactivate_messenger($messenger_name)
892
-    {
893
-        $this->_initialize_collections();
894
-        if ($messenger_name instanceof EE_messenger) {
895
-            $messenger_name = $messenger_name->name;
896
-        }
897
-        unset($this->_active_messengers[ $messenger_name ]);
898
-        unset($this->_active_message_types[ $messenger_name ]);
899
-        $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
900
-        $this->update_active_messengers_option();
901
-    }
902
-
903
-
904
-    /**
905
-     * Deactivates a message type (note this will deactivate across all messenger's it is active on.
906
-     *
907
-     * @param  string $message_type_name     name of message type being deactivated
908
-     * @param bool    $set_has_active_record By default we always record the has_active record when deactivating a message
909
-     *                                       type.  However, this can be overridden if we don't want this set (usually when
910
-     *                                       this is called as a part of deregistration of a custom message type)
911
-     */
912
-    public function deactivate_message_type($message_type_name, $set_has_active_record = true)
913
-    {
914
-        $this->_initialize_collections();
915
-        if ($message_type_name instanceof EE_message_type) {
916
-            $message_type_name = $message_type_name->name;
917
-        }
918
-        foreach ($this->_active_message_types as $messenger_name => $settings) {
919
-            unset(
920
-                $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
921
-            );
922
-
923
-            // we always record (even on deactivation) that a message type has been activated because there should at
924
-            // least be a record in the "has_activated" option that it WAS active at one point.
925
-            if ($set_has_active_record) {
926
-                $messenger = $this->get_messenger($messenger_name);
927
-                $this->_set_messenger_has_activated_message_type($messenger, $message_type_name);
928
-            }
929
-        }
930
-        $this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name);
931
-        $this->update_active_messengers_option();
932
-        $this->update_has_activated_messengers_option();
933
-    }
934
-
935
-
936
-    /**
937
-     * Deactivates a message type for a specific messenger as opposed to all messengers.
938
-     *
939
-     * @param string $message_type_name Name of message type being deactivated.
940
-     * @param string $messenger_name    Name of messenger the message type is being deactivated for.
941
-     */
942
-    public function deactivate_message_type_for_messenger($message_type_name, $messenger_name)
943
-    {
944
-        $this->_initialize_collections();
945
-        if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
946
-            unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
947
-        }
948
-        $this->_message_template_group_model->deactivate_message_template_groups_for(
949
-            array($messenger_name),
950
-            array($message_type_name)
951
-        );
952
-        $this->update_active_messengers_option();
953
-    }
954
-
955
-
956
-    /**
957
-     * Used to verify if a message can be sent for the given messenger and message type
958
-     * and that it is a generating messenger (used for generating message templates).
959
-     *
960
-     * @param EE_messenger    $messenger    messenger used in trigger
961
-     * @param EE_message_type $message_type message type used in trigger
962
-     * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
963
-     */
964
-    public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type)
965
-    {
966
-        // get the $messengers the message type says it can be used with.
967
-        foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) {
968
-            if ($messenger->name === $generating_messenger
969
-                && $this->is_message_type_active_for_messenger($messenger->name, $message_type->name)
970
-            ) {
971
-                return true;
972
-            }
973
-        }
974
-        return false;
975
-    }
976
-
977
-
978
-    /**
979
-     * This returns all the contexts that are registered by all message types.
980
-     * If $slugs_only is true,
981
-     * then just an array indexed by unique context slugs with the latest label representation for that slug.
982
-     * array(
983
-     *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
984
-     * );
985
-     * If $slugs_only is false, then the format is:
986
-     * array(
987
-     *      'message_type_name' => array(
988
-     *          'context_slug' => array(
989
-     *              'label' => 'localized label for context',
990
-     *              'description' => 'localized description for context'
991
-     *          )
992
-     *      )
993
-     * );
994
-     * Keep in mind that although different message types may share the same context slugs,
995
-     * it is possible that the context is described differently by the message type.
996
-     *
997
-     * @since 4.9.0
998
-     * @param   bool $slugs_only Whether to return an array of just slugs and labels (true)
999
-     *                           or all contexts indexed by message type.
1000
-     * @return array
1001
-     */
1002
-    public function get_all_contexts($slugs_only = true)
1003
-    {
1004
-        $key = $slugs_only ? 'slugs' : 'all';
1005
-        // check if contexts has been setup yet.
1006
-        if (empty($this->_contexts[ $key ])) {
1007
-            // So let's get all active message type objects and loop through to get all unique contexts
1008
-            foreach ($this->get_active_message_type_objects() as $message_type) {
1009
-                if ($message_type instanceof EE_message_type) {
1010
-                    $message_type_contexts = $message_type->get_contexts();
1011
-                    if ($slugs_only) {
1012
-                        foreach ($message_type_contexts as $context => $context_details) {
1013
-                            $this->_contexts[ $key ][ $context ] = $context_details['label'];
1014
-                        }
1015
-                    } else {
1016
-                        $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1017
-                    }
1018
-                }
1019
-            }
1020
-        }
1021
-        return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * This checks the internal record of what message types are considered "active" and verifies that
1027
-     * there is an installed class definition for that message type.  If the active message type does not have a
1028
-     * corresponding accessible message type class then it will be deactivated from all messengers it is active on and
1029
-     * any related message templates will be inactivated as well.
1030
-     *
1031
-     * @return bool   true means all active message types are valid, false means at least one message type was
1032
-     *                deactivated.
1033
-     */
1034
-    public function validate_active_message_types_are_installed()
1035
-    {
1036
-        $list_of_active_message_type_names = $this->list_of_active_message_types();
1037
-        $installed_message_types           = $this->installed_message_types();
1038
-        $all_message_types_valid           = true;
1039
-        // loop through list of active message types and verify they are installed.
1040
-        foreach ($list_of_active_message_type_names as $message_type_name) {
1041
-            if (! isset($installed_message_types[ $message_type_name ])) {
1042
-                $this->remove_message_type_has_been_activated_from_all_messengers(
1043
-                    $message_type_name,
1044
-                    true
1045
-                );
1046
-                $this->deactivate_message_type($message_type_name, false);
1047
-                $all_message_types_valid = false;
1048
-            }
1049
-        }
1050
-        return $all_message_types_valid;
1051
-    }
1052
-
1053
-
1054
-    /**
1055
-     * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been
1056
-     * activated for the given messenger.  This can be called by client code on plugin updates etc to determine whether
1057
-     * to attempt automatically reactivating message types that should be activated by default or not.
1058
-     *
1059
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1060
-     *
1061
-     * @param $message_type_name
1062
-     * @param $messenger_name
1063
-     * @return bool
1064
-     */
1065
-    public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1066
-    {
1067
-        $has_activated = $this->get_has_activated_messengers_option();
1068
-        return isset($has_activated[ $messenger_name ])
1069
-               && in_array($message_type_name, $has_activated[ $messenger_name ]);
1070
-    }
1071
-
1072
-
1073
-    /**
1074
-     * This method unsets a message type from the given messenger has activated option.
1075
-     *
1076
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1077
-     *
1078
-     * @param string $message_type_name
1079
-     * @param string $messenger_name
1080
-     * @param bool   $consider_current_state  Whether to consider whether the  message type is currently active or not.
1081
-     *                                        If it is currently active, then remove.  Otherwise leave it alone.
1082
-     */
1083
-    public function remove_message_type_has_been_activated_for_messenger(
1084
-        $message_type_name,
1085
-        $messenger_name,
1086
-        $consider_current_state = false
1087
-    ) {
1088
-        if ($consider_current_state
1089
-            && ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
1090
-        ) {
1091
-            // when consider current state is true, this means we don't want to change anything on the "has_activated"
1092
-            // record if the message type is currently active for this messenger.  This is used when we want to retain
1093
-            // the record for user initiated inactivations of the message type.
1094
-            return;
1095
-        }
1096
-        $has_activated = $this->get_has_activated_messengers_option();
1097
-        $key_for_message_type = isset($has_activated[ $messenger_name ])
1098
-            ? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1099
-            : false;
1100
-        if ($key_for_message_type !== false) {
1101
-            unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1102
-            $this->update_has_activated_messengers_option($has_activated);
1103
-            // reset the internal cached property
1104
-            $this->get_has_activated_messengers_option(true);
1105
-        }
1106
-    }
1107
-
1108
-
1109
-    /**
1110
-     * Removes a message type active record from all messengers it is attached to.
1111
-     *
1112
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1113
-     *
1114
-     * @param      $message_type_name
1115
-     * @param bool $consider_current_state  Whether to consider whether the  message type is currently active or not.
1116
-     *                                      If it is currently active, then remove.  Otherwise leave it alone.
1117
-     */
1118
-    public function remove_message_type_has_been_activated_from_all_messengers(
1119
-        $message_type_name,
1120
-        $consider_current_state = false
1121
-    ) {
1122
-        foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) {
1123
-            $this->remove_message_type_has_been_activated_for_messenger(
1124
-                $message_type_name,
1125
-                $messenger_name,
1126
-                $consider_current_state
1127
-            );
1128
-        }
1129
-    }
15
+	/**
16
+	 * This option in the database is used to keep a record of message types that have been activated for a messenger
17
+	 * at some point in the history of the site.  It is utilized by the implementation of the 'force' flag in
18
+	 * EE_Register_Message_Type.  The force flag is an indication of whether a message type should be activated by
19
+	 * default when the message type is registered.  However, if a user has explicitly deactivated a message type, then
20
+	 * the force flag is ignored.  The method by which the code knows whether to ignore this flag is via this option.
21
+	 * Note, that this is NOT a historical record.  Its entirely possible for a message type to have been activated for
22
+	 * a messenger and yet not have a record in this option.  This occurs when a message type is inactivated through an
23
+	 * automated process (when an add-on registering the message type deactivates, or when some other code calls the
24
+	 * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to ensure
25
+	 * the "force" flag is respected if that message type is later re-registered.
26
+	 *
27
+	 * This option should NOT be used to determine the current "active" state of a message type for a given messenger.
28
+	 *
29
+	 * The name of this option (and related methods/properties) is due to matching the original intended purpose for the
30
+	 * option that got superseded by later behaviour requirements.
31
+	 */
32
+	const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger';
33
+
34
+	/**
35
+	 * @type boolean $_initialized
36
+	 */
37
+	protected $_initialized = false;
38
+
39
+	/**
40
+	 * @type EE_Messenger_Collection $_messenger_collection_loader
41
+	 */
42
+	protected $_messenger_collection_loader;
43
+
44
+	/**
45
+	 * @type EE_Message_Type_Collection $_message_type_collection_loader
46
+	 */
47
+	protected $_message_type_collection_loader;
48
+
49
+	/**
50
+	 * @type EEM_Message_Template_Group $_message_template_group_model
51
+	 */
52
+	protected $_message_template_group_model;
53
+
54
+	/**
55
+	 * @type EE_messenger[]
56
+	 */
57
+	protected $_installed_messengers = array();
58
+
59
+	/**
60
+	 * @type EE_message_type[]
61
+	 */
62
+	protected $_installed_message_types = array();
63
+
64
+	/**
65
+	 * Array of active messengers.
66
+	 * Format is this:
67
+	 * array(
68
+	 *      'messenger_name' => EE_messenger
69
+	 * )
70
+	 *
71
+	 * @type EE_messenger[]
72
+	 */
73
+	protected $_active_messengers = array();
74
+
75
+	/**
76
+	 * Formatted array of active message types grouped per messenger.
77
+	 * Format is this:
78
+	 * array(
79
+	 *      'messenger_name' => array(
80
+	 *          'settings' => array(
81
+	 *              '{messenger_name}-message_types' => array(
82
+	 *                  'message_type_name' => array() //variable array of settings corresponding to message type.
83
+	 *              )
84
+	 *          )
85
+	 *      )
86
+	 * )
87
+	 *
88
+	 * @type array
89
+	 */
90
+	protected $_active_message_types = array();
91
+
92
+
93
+	/**
94
+	 * This holds the array of messengers and their corresponding message types that have
95
+	 * been activated on a site at some point.  This is an important record that helps the messages system
96
+	 * not accidentally reactivate something that was intentionally deactivated by a user.
97
+	 *
98
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
99
+	 *
100
+	 * @type array
101
+	 */
102
+	protected $_has_activated_messengers_and_message_types = array();
103
+
104
+	/**
105
+	 * An array of unique message type contexts across all active message types.
106
+	 * The array will be indexed by either 'slugs' or 'all'.
107
+	 * The slugs index contains an array indexed by unique context slugs with the latest label representation for that
108
+	 * slug. array(
109
+	 *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
110
+	 * );
111
+	 * The all index returns an array in this format:
112
+	 * array(
113
+	 *      'message_type_name' => array(
114
+	 *          'context_slug' => array(
115
+	 *              'label' => 'localized label for context',
116
+	 *              'description' => 'localized description for context'
117
+	 *          )
118
+	 *      )
119
+	 * );
120
+	 *
121
+	 * @type array
122
+	 */
123
+	protected $_contexts = array();
124
+
125
+
126
+	/**
127
+	 * EE_Message_Resource_Manager constructor.
128
+	 *
129
+	 * @param \EE_Messenger_Collection_Loader    $Messenger_Collection_Loader
130
+	 * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader
131
+	 * @param \EEM_Message_Template_Group        $Message_Template_Group_Model
132
+	 */
133
+	public function __construct(
134
+		EE_Messenger_Collection_Loader $Messenger_Collection_Loader,
135
+		EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader,
136
+		EEM_Message_Template_Group $Message_Template_Group_Model
137
+	) {
138
+		$this->_messenger_collection_loader    = $Messenger_Collection_Loader;
139
+		$this->_message_type_collection_loader = $Message_Type_Collection_Loader;
140
+		$this->_message_template_group_model   = $Message_Template_Group_Model;
141
+	}
142
+
143
+
144
+	/**
145
+	 * @return void
146
+	 */
147
+	protected function _initialize_collections()
148
+	{
149
+		if ($this->_initialized) {
150
+			return;
151
+		}
152
+		$this->_initialized = true;
153
+		$this->_messenger_collection_loader->load_messengers_from_folder();
154
+		$this->_message_type_collection_loader->load_message_types_from_folder();
155
+		$this->get_has_activated_messengers_option(true);
156
+		$this->_set_active_messengers_and_message_types();
157
+	}
158
+
159
+
160
+	/**
161
+	 * @return EE_Messenger_Collection
162
+	 */
163
+	public function messenger_collection()
164
+	{
165
+		$this->_initialize_collections();
166
+		return $this->_messenger_collection_loader->messenger_collection();
167
+	}
168
+
169
+
170
+	/**
171
+	 * @return EE_messenger[]
172
+	 */
173
+	public function active_messengers()
174
+	{
175
+		$this->_initialize_collections();
176
+		return $this->_active_messengers;
177
+	}
178
+
179
+
180
+	/**
181
+	 * @param string $messenger_name
182
+	 * @return \EE_messenger
183
+	 */
184
+	public function get_messenger($messenger_name)
185
+	{
186
+		return $this->messenger_collection()->get_by_info($messenger_name);
187
+	}
188
+
189
+
190
+	/**
191
+	 * This returns the corresponding EE_messenger object for the given string if it is active.
192
+	 *
193
+	 * @param string $messenger
194
+	 * @return EE_messenger | null
195
+	 */
196
+	public function get_active_messenger($messenger)
197
+	{
198
+		$this->_initialize_collections();
199
+		return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
200
+	}
201
+
202
+
203
+	/**
204
+	 * @return \EE_messenger[]
205
+	 */
206
+	public function installed_messengers()
207
+	{
208
+		if (empty($this->_installed_messengers)) {
209
+			$this->_installed_messengers = array();
210
+			$this->messenger_collection()->rewind();
211
+			while ($this->messenger_collection()->valid()) {
212
+				$this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
213
+				$this->messenger_collection()->next();
214
+			}
215
+		}
216
+		return $this->_installed_messengers;
217
+	}
218
+
219
+
220
+	/**
221
+	 * @param string $messenger_name
222
+	 * @return \EE_messenger
223
+	 * @throws EE_Error
224
+	 */
225
+	public function valid_messenger($messenger_name)
226
+	{
227
+		$messenger = $this->get_messenger($messenger_name);
228
+		if ($messenger instanceof EE_messenger) {
229
+			return $messenger;
230
+		}
231
+		throw new EE_Error(
232
+			sprintf(
233
+				__('The "%1$s" messenger is either invalid or not installed', 'event_espresso'),
234
+				$messenger_name
235
+			)
236
+		);
237
+	}
238
+
239
+
240
+	/**
241
+	 * @return EE_Message_Type_Collection
242
+	 */
243
+	public function message_type_collection()
244
+	{
245
+		$this->_initialize_collections();
246
+		return $this->_message_type_collection_loader->message_type_collection();
247
+	}
248
+
249
+
250
+	/**
251
+	 * @return array
252
+	 */
253
+	public function active_message_types()
254
+	{
255
+		$this->_initialize_collections();
256
+		return $this->_active_message_types;
257
+	}
258
+
259
+
260
+	/**
261
+	 * @param string $message_type_name
262
+	 * @return \EE_message_type
263
+	 */
264
+	public function get_message_type($message_type_name)
265
+	{
266
+		return $this->message_type_collection()->get_by_info($message_type_name);
267
+	}
268
+
269
+
270
+	/**
271
+	 * This returns the EE_message_type from the active message types array ( if present );
272
+	 *
273
+	 * @param string $messenger_name
274
+	 * @param string $message_type_name
275
+	 * @return \EE_message_type|null
276
+	 */
277
+	public function get_active_message_type_for_messenger($messenger_name, $message_type_name)
278
+	{
279
+		return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
280
+			? $this->get_message_type($message_type_name)
281
+			: null;
282
+	}
283
+
284
+
285
+	/**
286
+	 * Returns whether the given message type is active for the given messenger.
287
+	 *
288
+	 * @param string $messenger_name
289
+	 * @param string $message_type_name
290
+	 * @return bool
291
+	 */
292
+	public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293
+	{
294
+		$this->_initialize_collections();
295
+		return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
296
+	}
297
+
298
+
299
+	/**
300
+	 * Returns whether the given messenger is active.
301
+	 *
302
+	 * @param string $messenger_name the name of the messenger to check if active.
303
+	 * @return bool
304
+	 */
305
+	public function is_messenger_active($messenger_name)
306
+	{
307
+		$this->_initialize_collections();
308
+		return ! empty($this->_active_message_types[ $messenger_name ]);
309
+	}
310
+
311
+
312
+	/**
313
+	 * This returns any settings that might be on a message type for a messenger
314
+	 *
315
+	 * @param string $messenger_name    The slug of the messenger
316
+	 * @param string $message_type_name The slug of the message type getting the settings for.
317
+	 * @return array
318
+	 */
319
+	public function get_message_type_settings_for_messenger($messenger_name, $message_type_name)
320
+	{
321
+		$settings = array();
322
+		if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
+			$settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
+				? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
325
+				: array();
326
+		}
327
+		return $settings;
328
+	}
329
+
330
+
331
+	/**
332
+	 * Returns whether the given messenger name has active message types on it.
333
+	 * Infers whether the messenger is active or not as well.
334
+	 *
335
+	 * @param string $messenger_name
336
+	 * @return bool
337
+	 */
338
+	public function messenger_has_active_message_types($messenger_name)
339
+	{
340
+		$this->_initialize_collections();
341
+		return
342
+			! empty($this->_active_message_types[ $messenger_name ])
343
+			&& ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
344
+	}
345
+
346
+
347
+	/**
348
+	 * This checks the _active_message_types property for any active message types
349
+	 * that are present for the given messenger and returns them.
350
+	 *
351
+	 * @since 4.9.0
352
+	 * @param string $messenger_name The messenger being checked
353
+	 * @return EE_message_type[]|array    (empty array if no active_message_types)
354
+	 */
355
+	public function get_active_message_types_for_messenger($messenger_name)
356
+	{
357
+		$message_types = array();
358
+		if (! $this->messenger_has_active_message_types($messenger_name)) {
359
+			return $message_types;
360
+		}
361
+		$installed_message_types = $this->installed_message_types();
362
+		foreach ($installed_message_types as $message_type_name => $message_type) {
363
+			if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
+				$message_types[ $message_type_name ] = $message_type;
365
+			}
366
+		}
367
+		return $message_types;
368
+	}
369
+
370
+
371
+	/**
372
+	 * This does NOT return the _active_message_types property but
373
+	 * simply returns an array of active message type names from that property.
374
+	 * (The _active_message_types property is indexed by messenger and active message_types per messenger).
375
+	 *
376
+	 * @return array message_type references (string)
377
+	 */
378
+	public function list_of_active_message_types()
379
+	{
380
+		$active_message_type_names = array();
381
+		$this->_initialize_collections();
382
+		foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
+			if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
384
+				continue;
385
+			}
386
+			foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
+				if (! in_array($message_type_name, $active_message_type_names)) {
388
+					$active_message_type_names[] = $message_type_name;
389
+				}
390
+			}
391
+		}
392
+		return $active_message_type_names;
393
+	}
394
+
395
+
396
+	/**
397
+	 * Same as list_of_active_message_types() except this returns actual EE_message_type objects
398
+	 *
399
+	 * @since 4.9.0
400
+	 * @return \EE_message_type[]
401
+	 */
402
+	public function get_active_message_type_objects()
403
+	{
404
+		$active_message_types      = array();
405
+		$installed_message_types   = $this->installed_message_types();
406
+		$active_message_type_names = $this->list_of_active_message_types();
407
+		foreach ($active_message_type_names as $active_message_type_name) {
408
+			if (isset($installed_message_types[ $active_message_type_name ])) {
409
+				$active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
410
+			}
411
+		}
412
+		return $active_message_types;
413
+	}
414
+
415
+
416
+	/**
417
+	 * @return \EE_message_type[]
418
+	 */
419
+	public function installed_message_types()
420
+	{
421
+		if (empty($this->_installed_message_types)) {
422
+			$this->message_type_collection()->rewind();
423
+			while ($this->message_type_collection()->valid()) {
424
+				$this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
425
+				$this->message_type_collection()->next();
426
+			}
427
+		}
428
+		return $this->_installed_message_types;
429
+	}
430
+
431
+
432
+	/**
433
+	 * @param string $message_type_name
434
+	 * @return \EE_message_type
435
+	 * @throws EE_Error
436
+	 */
437
+	public function valid_message_type($message_type_name)
438
+	{
439
+		$message_type = $this->get_message_type($message_type_name);
440
+		if ($message_type instanceof EE_message_type) {
441
+			return $message_type;
442
+		}
443
+		throw new EE_Error(
444
+			sprintf(
445
+				__('The "%1$s" message type is either invalid or not installed', 'event_espresso'),
446
+				$message_type_name
447
+			)
448
+		);
449
+	}
450
+
451
+
452
+	/**
453
+	 * valid_message_type_for_messenger
454
+	 *
455
+	 * @param EE_messenger $messenger
456
+	 * @param string       $message_type_name
457
+	 * @return boolean
458
+	 * @throws EE_Error
459
+	 */
460
+	public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461
+	{
462
+		$valid_message_types = $messenger->get_valid_message_types();
463
+		if (! in_array($message_type_name, $valid_message_types)) {
464
+			throw new EE_Error(
465
+				sprintf(
466
+					__(
467
+						'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger.  Double-check the spelling and verify that message type has been registered as a valid type with the messenger.',
468
+						'event_espresso'
469
+					),
470
+					$message_type_name,
471
+					__METHOD__,
472
+					$messenger->name
473
+				)
474
+			);
475
+		}
476
+		return true;
477
+	}
478
+
479
+
480
+	/**
481
+	 * Used to return active messengers array stored in the wp options table.
482
+	 * If no value is present in the option then an empty array is returned.
483
+	 *
484
+	 * @param   bool $reset     If true then we ignore whether the option is cached on the _active_message_types
485
+	 *                          property and pull directly from the db.  Otherwise whatever is currently on the
486
+	 *                          $_active_message_types property is pulled.
487
+	 * @return array
488
+	 */
489
+	public function get_active_messengers_option($reset = false)
490
+	{
491
+		if ($reset) {
492
+			$this->_active_message_types = get_option('ee_active_messengers', array());
493
+		}
494
+		return $this->_active_message_types;
495
+	}
496
+
497
+
498
+	/**
499
+	 * Used to update the active messengers array stored in the wp options table.
500
+	 *
501
+	 * @param array $active_messenger_settings Incoming data to save.  If empty, then the internal cached property
502
+	 *                                         representing this data is used.
503
+	 * @return bool FALSE if not updated, TRUE if updated.
504
+	 */
505
+	public function update_active_messengers_option($active_messenger_settings = array())
506
+	{
507
+		$active_messenger_settings = empty($active_messenger_settings) ? $this->_active_message_types : $active_messenger_settings;
508
+		// make sure _active_message_types is updated (this is the internal cache for the settings).
509
+		$this->_active_message_types = $active_messenger_settings;
510
+		return update_option('ee_active_messengers', $active_messenger_settings);
511
+	}
512
+
513
+
514
+	/**
515
+	 * Used to return has activated message types for messengers array stored in the wp options table.
516
+	 * If no value is present in the option then an empty array is returned.
517
+	 * The value is cached on the $_has_activated_messengers_and_message_types property for future calls.
518
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
519
+	 *
520
+	 * @param   bool $reset Used to indicate that any cached value should be ignored.
521
+	 * @return array
522
+	 */
523
+	public function get_has_activated_messengers_option($reset = false)
524
+	{
525
+		if ($reset || empty($this->_has_activated_messengers_and_message_types)) {
526
+			$this->_has_activated_messengers_and_message_types = get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, array());
527
+		}
528
+		return $this->_has_activated_messengers_and_message_types;
529
+	}
530
+
531
+
532
+	/**
533
+	 * Used to update the has activated option in the db.
534
+	 *
535
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
536
+	 *
537
+	 * @param array $has_activated_messengers Incoming data to save.  If empty, then the internal cached property
538
+	 *                                        representing this data is used.
539
+	 * @return bool FALSE if not updated, TRUE if updated.
540
+	 */
541
+	public function update_has_activated_messengers_option($has_activated_messengers = array())
542
+	{
543
+		// make sure the option has been retrieved from first so we don't overwrite it accidentally.
544
+		if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) {
545
+			$this->get_has_activated_messengers_option();
546
+		}
547
+		$has_activated_messengers = empty($has_activated_messengers)
548
+			? $this->_has_activated_messengers_and_message_types
549
+			: $has_activated_messengers;
550
+		return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers);
551
+	}
552
+
553
+
554
+	/**
555
+	 * wrapper for _set_active_messengers_and_message_types()
556
+	 */
557
+	public function reset_active_messengers_and_message_types()
558
+	{
559
+		$this->_set_active_messengers_and_message_types();
560
+	}
561
+
562
+
563
+	/**
564
+	 * Generate list of active messengers and message types from collection.
565
+	 * This sets up the active messengers from what is present in the database.
566
+	 */
567
+	protected function _set_active_messengers_and_message_types()
568
+	{
569
+		// echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n";
570
+		// list of activated messengers as set via the admin
571
+		// note calling `get_active_messengers_options` also initializes the _active_message_types property.
572
+		$this->get_active_messengers_option(true);
573
+		$this->ensure_messengers_are_active(array(), false, true);
574
+		$this->update_active_messengers_option();
575
+		$this->update_has_activated_messengers_option();
576
+	}
577
+
578
+
579
+	/**
580
+	 * Ensures that the specified messenger is currently active.
581
+	 * If not, activates it and its default message types.
582
+	 *
583
+	 * @param string $messenger_name
584
+	 * @param bool   $update_option Whether to update the option in the db or not.
585
+	 * @return boolean true if either already active or successfully activated.
586
+	 */
587
+	public function ensure_messenger_is_active($messenger_name, $update_option = true)
588
+	{
589
+		if (! isset($this->_active_messengers[ $messenger_name ])) {
590
+			try {
591
+				$this->activate_messenger($messenger_name, array(), $update_option);
592
+			} catch (EE_Error $e) {
593
+				EE_Error::add_error(
594
+					$e->getMessage(),
595
+					__FILE__,
596
+					__FUNCTION__,
597
+					__LINE__
598
+				);
599
+				return false;
600
+			}
601
+		}
602
+		return true;
603
+	}
604
+
605
+
606
+	/**
607
+	 * This ensures the given array of messenger names is active in the system.
608
+	 * Note, this method will not activate any NEW message types for the messenger when it is called. Instead,
609
+	 * it will automatically activate the default message types for the messenger if its not active.
610
+	 *
611
+	 * @param array $messenger_names  Array of messenger names for messengers to be activated.  If an empty array
612
+	 *                                (default) then will attempt to set the active messengers from the
613
+	 *                                activated_messengers option
614
+	 *                                (stored in $_active_message_types property).
615
+	 * @param bool  $update_option    Whether to update the related active messengers option.
616
+	 * @param bool  $verify           Whether to verify the messengers are installed before activating. Note if this is
617
+	 *                                set to true and a messenger is indicated as active, but is NOT installed, then it
618
+	 *                                will automatically be deactivated.
619
+	 */
620
+	public function ensure_messengers_are_active($messenger_names = array(), $update_option = true, $verify = false)
621
+	{
622
+		$messenger_names = empty($messenger_names) ? array_keys($this->_active_message_types) : $messenger_names;
623
+
624
+		$not_installed = array();
625
+		foreach ($messenger_names as $messenger_name) {
626
+			if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) {
627
+				$not_installed[] = $messenger_name;
628
+				$this->deactivate_messenger($messenger_name);
629
+				continue;
630
+			}
631
+			$this->ensure_messenger_is_active($messenger_name, $update_option);
632
+		}
633
+
634
+		if (! empty($not_installed)) {
635
+			EE_Error::add_error(
636
+				sprintf(
637
+					__('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
638
+					'<br />',
639
+					implode(', ', $not_installed)
640
+				),
641
+				__FILE__,
642
+				__FUNCTION__,
643
+				__LINE__
644
+			);
645
+		}
646
+	}
647
+
648
+
649
+	/**
650
+	 * Ensures that the specified message type for the given messenger is currently active, if not activates it.
651
+	 * This ALSO ensures that the given messenger is active as well!
652
+	 *
653
+	 * @param string $message_type_name message type name.
654
+	 * @param        $messenger_name
655
+	 * @param bool   $update_option     Whether to update the option in the db or not.
656
+	 * @return bool  Returns true if already is active or if was activated successfully.
657
+	 * @throws EE_Error
658
+	 */
659
+	public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true)
660
+	{
661
+		// grab the messenger to work with.
662
+		$messenger = $this->valid_messenger($messenger_name);
663
+		if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) {
664
+			// ensure messenger is active (that's an inherent coupling between active message types and the
665
+			// messenger they are being activated for.
666
+			try {
667
+				if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668
+					// all is good so let's just get it active
669
+					$this->activate_messenger($messenger, array($message_type_name), $update_option);
670
+				}
671
+			} catch (EE_Error $e) {
672
+				EE_Error::add_error(
673
+					$e->getMessage(),
674
+					__FILE__,
675
+					__FUNCTION__,
676
+					__LINE__
677
+				);
678
+				return false;
679
+			}
680
+		}
681
+		return true;
682
+	}
683
+
684
+
685
+	/**
686
+	 * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a
687
+	 * messenger are active in one go.
688
+	 *
689
+	 * @param array  $message_type_names Array of message type names to ensure are active.
690
+	 * @param string $messenger_name     The name of the messenger that the message types are to be activated on.
691
+	 * @param bool   $update_option      Whether to persist the activation to the database or not (default true).
692
+	 */
693
+	public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true)
694
+	{
695
+		$message_type_names = (array) $message_type_names;
696
+		foreach ($message_type_names as $message_type_name) {
697
+			// note, intentionally not updating option here because we're in a loop.
698
+			// We'll follow the instructions of the incoming $update_option argument after the loop.
699
+			$this->ensure_message_type_is_active($message_type_name, $messenger_name, false);
700
+		}
701
+		if ($update_option) {
702
+			$this->update_active_messengers_option();
703
+			$this->update_has_activated_messengers_option();
704
+		}
705
+	}
706
+
707
+
708
+	/**
709
+	 * Activates the specified messenger.
710
+	 *
711
+	 * @param EE_messenger|string $messenger    Instantiated EE_messenger OR messenger name if not already loaded!
712
+	 * @param array  $message_type_names        An array of message type names to activate with this messenger.
713
+	 *                                          If included we do NOT setup the default message types
714
+	 *                                          (assuming they are already setup.)
715
+	 * @param bool   $update_active_messengers_option
716
+	 * @return array of generated templates
717
+	 * @throws EE_Error
718
+	 */
719
+	public function activate_messenger(
720
+		$messenger,
721
+		$message_type_names = array(),
722
+		$update_active_messengers_option = true
723
+	) {
724
+		$templates = array();
725
+		// grab the messenger to work with.
726
+		$messenger = $messenger instanceof EE_messenger
727
+			? $messenger
728
+			: $this->messenger_collection()->get_by_info($messenger);
729
+		// it's inactive. Activate it.
730
+		if ($messenger instanceof EE_messenger) {
731
+			$this->_active_messengers[ $messenger->name ] = $messenger;
732
+			// activate incoming message types set to be activated with messenger.
733
+			$message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734
+			// setup any initial settings for the messenger if necessary.
735
+			$this->add_settings_for_messenger($messenger->name);
736
+			if ($update_active_messengers_option) {
737
+				$this->update_active_messengers_option();
738
+				$this->update_has_activated_messengers_option();
739
+			}
740
+			// generate new templates if necessary and ensure all related templates that are already in the database are
741
+			// marked active.  Note, this will also deactivate a message type for a messenger if the template
742
+			// cannot be successfully created during its attempt (only happens for global template attempts).
743
+			if (! empty($message_type_names)) {
744
+				$templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745
+				EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746
+			}
747
+		}
748
+		return $templates;
749
+	}
750
+
751
+
752
+	/**
753
+	 * Activates given message types for the given EE_messenger object.
754
+	 * Note: (very important) This method does not persist the activation to the database.
755
+	 * See code implementing this method in this class for examples of how to persist.
756
+	 *
757
+	 * @param \EE_messenger $messenger
758
+	 * @param  array        $message_type_names
759
+	 * @return array
760
+	 */
761
+	protected function _activate_message_types(EE_messenger $messenger, $message_type_names = array())
762
+	{
763
+		// If $message_type_names is empty, AND $this->_active_message_types is empty, then that means
764
+		// things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765
+		// So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766
+		// only override _active_message_types when an explicit array of $message_type_names has been provided.
767
+		$message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
768
+			? $messenger->get_default_message_types()
769
+			: (array) $message_type_names;
770
+
771
+		// now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
+		if (! isset($this->_active_message_types[ $messenger->name ])) {
773
+			$this->_active_message_types[ $messenger->name ]['settings'] = array();
774
+		}
775
+
776
+		if ($message_type_names) {
777
+			// cycle thru message types
778
+			foreach ($message_type_names as $message_type_name) {
779
+				// only register the message type as active IF it isn't already active
780
+				// and if its actually installed.
781
+				if (! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
782
+				) {
783
+					$this->add_settings_for_message_type($messenger->name, $message_type_name);
784
+					$this->_set_messenger_has_activated_message_type(
785
+						$messenger,
786
+						$message_type_name
787
+					);
788
+				}
789
+			}
790
+		}
791
+		return $message_type_names;
792
+	}
793
+
794
+
795
+	/**
796
+	 * add_settings_for_message_type
797
+	 * NOTE This does NOT automatically persist any settings to the db.  Client code should call
798
+	 * $this->update_active_messengers_option to persist.
799
+	 *
800
+	 * @param  string $messenger_name    The name of the messenger adding the settings for
801
+	 * @param  string $message_type_name The name of the message type adding the settings for
802
+	 * @param  array  $new_settings      Any new settings being set for the message type and messenger
803
+	 */
804
+	public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = array())
805
+	{
806
+		// get installed message type from collection
807
+		$message_type      = $this->message_type_collection()->get_by_info($message_type_name);
808
+		$existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name);
809
+		// we need to setup any initial settings for message types
810
+		if ($message_type instanceof EE_message_type) {
811
+			$default_settings = $message_type->get_admin_settings_fields();
812
+			foreach ($default_settings as $field => $values) {
813
+				if (isset($new_settings[ $field ])) {
814
+					$existing_settings[ $field ] = $new_settings[ $field ];
815
+					continue;
816
+				}
817
+				if (! isset($existing_settings[ $field ])) {
818
+					$existing_settings[ $field ] = $values['default'];
819
+				}
820
+			}
821
+		}
822
+		$this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
823
+	}
824
+
825
+
826
+	/**
827
+	 * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger
828
+	 * and message type.
829
+	 *
830
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
831
+	 *
832
+	 * @access protected
833
+	 * @param \EE_messenger $messenger
834
+	 * @param string        $message_type_name
835
+	 */
836
+	protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name)
837
+	{
838
+
839
+		// if _has_activated_messengers_and_message_types is empty then lets ensure its initialized
840
+		if (empty($this->_has_activated_messengers_and_message_types)) {
841
+			$this->get_has_activated_messengers_option();
842
+		}
843
+
844
+		// make sure this messenger has a record in the has_activated array
845
+		if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
846
+			$this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
847
+		}
848
+		// check if message type has already been added
849
+		if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
850
+			$this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
851
+		}
852
+	}
853
+
854
+
855
+	/**
856
+	 * add_settings_for_messenger
857
+	 * NOTE This does NOT automatically persist any settings to the db.  Client code should call
858
+	 * $this->update_active_messengers_option to persist.
859
+	 *
860
+	 * @param string $messenger_name The name of the messenger the settings is being added for.
861
+	 * @param array  $new_settings   An array of settings to update the existing settings.
862
+	 */
863
+	public function add_settings_for_messenger($messenger_name, $new_settings = array())
864
+	{
865
+		$messenger = $this->get_messenger($messenger_name);
866
+		if ($messenger instanceof EE_messenger) {
867
+			$msgr_settings = $messenger->get_admin_settings_fields();
868
+			if (! empty($msgr_settings)) {
869
+				foreach ($msgr_settings as $field => $value) {
870
+					// is there a new setting for this?
871
+					if (isset($new_settings[ $field ])) {
872
+						$this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
873
+						continue;
874
+					}
875
+					// only set the default if it isn't already set.
876
+					if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
877
+						$this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
878
+					}
879
+				}
880
+			}
881
+		}
882
+	}
883
+
884
+
885
+	/**
886
+	 * deactivate_messenger
887
+	 *
888
+	 * @param  string|EE_messenger $messenger_name name of messenger
889
+	 * @return void
890
+	 */
891
+	public function deactivate_messenger($messenger_name)
892
+	{
893
+		$this->_initialize_collections();
894
+		if ($messenger_name instanceof EE_messenger) {
895
+			$messenger_name = $messenger_name->name;
896
+		}
897
+		unset($this->_active_messengers[ $messenger_name ]);
898
+		unset($this->_active_message_types[ $messenger_name ]);
899
+		$this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
900
+		$this->update_active_messengers_option();
901
+	}
902
+
903
+
904
+	/**
905
+	 * Deactivates a message type (note this will deactivate across all messenger's it is active on.
906
+	 *
907
+	 * @param  string $message_type_name     name of message type being deactivated
908
+	 * @param bool    $set_has_active_record By default we always record the has_active record when deactivating a message
909
+	 *                                       type.  However, this can be overridden if we don't want this set (usually when
910
+	 *                                       this is called as a part of deregistration of a custom message type)
911
+	 */
912
+	public function deactivate_message_type($message_type_name, $set_has_active_record = true)
913
+	{
914
+		$this->_initialize_collections();
915
+		if ($message_type_name instanceof EE_message_type) {
916
+			$message_type_name = $message_type_name->name;
917
+		}
918
+		foreach ($this->_active_message_types as $messenger_name => $settings) {
919
+			unset(
920
+				$this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
921
+			);
922
+
923
+			// we always record (even on deactivation) that a message type has been activated because there should at
924
+			// least be a record in the "has_activated" option that it WAS active at one point.
925
+			if ($set_has_active_record) {
926
+				$messenger = $this->get_messenger($messenger_name);
927
+				$this->_set_messenger_has_activated_message_type($messenger, $message_type_name);
928
+			}
929
+		}
930
+		$this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name);
931
+		$this->update_active_messengers_option();
932
+		$this->update_has_activated_messengers_option();
933
+	}
934
+
935
+
936
+	/**
937
+	 * Deactivates a message type for a specific messenger as opposed to all messengers.
938
+	 *
939
+	 * @param string $message_type_name Name of message type being deactivated.
940
+	 * @param string $messenger_name    Name of messenger the message type is being deactivated for.
941
+	 */
942
+	public function deactivate_message_type_for_messenger($message_type_name, $messenger_name)
943
+	{
944
+		$this->_initialize_collections();
945
+		if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
946
+			unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
947
+		}
948
+		$this->_message_template_group_model->deactivate_message_template_groups_for(
949
+			array($messenger_name),
950
+			array($message_type_name)
951
+		);
952
+		$this->update_active_messengers_option();
953
+	}
954
+
955
+
956
+	/**
957
+	 * Used to verify if a message can be sent for the given messenger and message type
958
+	 * and that it is a generating messenger (used for generating message templates).
959
+	 *
960
+	 * @param EE_messenger    $messenger    messenger used in trigger
961
+	 * @param EE_message_type $message_type message type used in trigger
962
+	 * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
963
+	 */
964
+	public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type)
965
+	{
966
+		// get the $messengers the message type says it can be used with.
967
+		foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) {
968
+			if ($messenger->name === $generating_messenger
969
+				&& $this->is_message_type_active_for_messenger($messenger->name, $message_type->name)
970
+			) {
971
+				return true;
972
+			}
973
+		}
974
+		return false;
975
+	}
976
+
977
+
978
+	/**
979
+	 * This returns all the contexts that are registered by all message types.
980
+	 * If $slugs_only is true,
981
+	 * then just an array indexed by unique context slugs with the latest label representation for that slug.
982
+	 * array(
983
+	 *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
984
+	 * );
985
+	 * If $slugs_only is false, then the format is:
986
+	 * array(
987
+	 *      'message_type_name' => array(
988
+	 *          'context_slug' => array(
989
+	 *              'label' => 'localized label for context',
990
+	 *              'description' => 'localized description for context'
991
+	 *          )
992
+	 *      )
993
+	 * );
994
+	 * Keep in mind that although different message types may share the same context slugs,
995
+	 * it is possible that the context is described differently by the message type.
996
+	 *
997
+	 * @since 4.9.0
998
+	 * @param   bool $slugs_only Whether to return an array of just slugs and labels (true)
999
+	 *                           or all contexts indexed by message type.
1000
+	 * @return array
1001
+	 */
1002
+	public function get_all_contexts($slugs_only = true)
1003
+	{
1004
+		$key = $slugs_only ? 'slugs' : 'all';
1005
+		// check if contexts has been setup yet.
1006
+		if (empty($this->_contexts[ $key ])) {
1007
+			// So let's get all active message type objects and loop through to get all unique contexts
1008
+			foreach ($this->get_active_message_type_objects() as $message_type) {
1009
+				if ($message_type instanceof EE_message_type) {
1010
+					$message_type_contexts = $message_type->get_contexts();
1011
+					if ($slugs_only) {
1012
+						foreach ($message_type_contexts as $context => $context_details) {
1013
+							$this->_contexts[ $key ][ $context ] = $context_details['label'];
1014
+						}
1015
+					} else {
1016
+						$this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1017
+					}
1018
+				}
1019
+			}
1020
+		}
1021
+		return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * This checks the internal record of what message types are considered "active" and verifies that
1027
+	 * there is an installed class definition for that message type.  If the active message type does not have a
1028
+	 * corresponding accessible message type class then it will be deactivated from all messengers it is active on and
1029
+	 * any related message templates will be inactivated as well.
1030
+	 *
1031
+	 * @return bool   true means all active message types are valid, false means at least one message type was
1032
+	 *                deactivated.
1033
+	 */
1034
+	public function validate_active_message_types_are_installed()
1035
+	{
1036
+		$list_of_active_message_type_names = $this->list_of_active_message_types();
1037
+		$installed_message_types           = $this->installed_message_types();
1038
+		$all_message_types_valid           = true;
1039
+		// loop through list of active message types and verify they are installed.
1040
+		foreach ($list_of_active_message_type_names as $message_type_name) {
1041
+			if (! isset($installed_message_types[ $message_type_name ])) {
1042
+				$this->remove_message_type_has_been_activated_from_all_messengers(
1043
+					$message_type_name,
1044
+					true
1045
+				);
1046
+				$this->deactivate_message_type($message_type_name, false);
1047
+				$all_message_types_valid = false;
1048
+			}
1049
+		}
1050
+		return $all_message_types_valid;
1051
+	}
1052
+
1053
+
1054
+	/**
1055
+	 * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been
1056
+	 * activated for the given messenger.  This can be called by client code on plugin updates etc to determine whether
1057
+	 * to attempt automatically reactivating message types that should be activated by default or not.
1058
+	 *
1059
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1060
+	 *
1061
+	 * @param $message_type_name
1062
+	 * @param $messenger_name
1063
+	 * @return bool
1064
+	 */
1065
+	public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1066
+	{
1067
+		$has_activated = $this->get_has_activated_messengers_option();
1068
+		return isset($has_activated[ $messenger_name ])
1069
+			   && in_array($message_type_name, $has_activated[ $messenger_name ]);
1070
+	}
1071
+
1072
+
1073
+	/**
1074
+	 * This method unsets a message type from the given messenger has activated option.
1075
+	 *
1076
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1077
+	 *
1078
+	 * @param string $message_type_name
1079
+	 * @param string $messenger_name
1080
+	 * @param bool   $consider_current_state  Whether to consider whether the  message type is currently active or not.
1081
+	 *                                        If it is currently active, then remove.  Otherwise leave it alone.
1082
+	 */
1083
+	public function remove_message_type_has_been_activated_for_messenger(
1084
+		$message_type_name,
1085
+		$messenger_name,
1086
+		$consider_current_state = false
1087
+	) {
1088
+		if ($consider_current_state
1089
+			&& ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
1090
+		) {
1091
+			// when consider current state is true, this means we don't want to change anything on the "has_activated"
1092
+			// record if the message type is currently active for this messenger.  This is used when we want to retain
1093
+			// the record for user initiated inactivations of the message type.
1094
+			return;
1095
+		}
1096
+		$has_activated = $this->get_has_activated_messengers_option();
1097
+		$key_for_message_type = isset($has_activated[ $messenger_name ])
1098
+			? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1099
+			: false;
1100
+		if ($key_for_message_type !== false) {
1101
+			unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1102
+			$this->update_has_activated_messengers_option($has_activated);
1103
+			// reset the internal cached property
1104
+			$this->get_has_activated_messengers_option(true);
1105
+		}
1106
+	}
1107
+
1108
+
1109
+	/**
1110
+	 * Removes a message type active record from all messengers it is attached to.
1111
+	 *
1112
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1113
+	 *
1114
+	 * @param      $message_type_name
1115
+	 * @param bool $consider_current_state  Whether to consider whether the  message type is currently active or not.
1116
+	 *                                      If it is currently active, then remove.  Otherwise leave it alone.
1117
+	 */
1118
+	public function remove_message_type_has_been_activated_from_all_messengers(
1119
+		$message_type_name,
1120
+		$consider_current_state = false
1121
+	) {
1122
+		foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) {
1123
+			$this->remove_message_type_has_been_activated_for_messenger(
1124
+				$message_type_name,
1125
+				$messenger_name,
1126
+				$consider_current_state
1127
+			);
1128
+		}
1129
+	}
1130 1130
 }
Please login to merge, or discard this patch.
Spacing   +54 added lines, -54 removed lines patch added patch discarded remove patch
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
     public function get_active_messenger($messenger)
197 197
     {
198 198
         $this->_initialize_collections();
199
-        return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
199
+        return ! empty($this->_active_messengers[$messenger]) ? $this->_active_messengers[$messenger] : null;
200 200
     }
201 201
 
202 202
 
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
             $this->_installed_messengers = array();
210 210
             $this->messenger_collection()->rewind();
211 211
             while ($this->messenger_collection()->valid()) {
212
-                $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
212
+                $this->_installed_messengers[$this->messenger_collection()->current()->name] = $this->messenger_collection()->current();
213 213
                 $this->messenger_collection()->next();
214 214
             }
215 215
         }
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
     public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293 293
     {
294 294
         $this->_initialize_collections();
295
-        return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
295
+        return ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]);
296 296
     }
297 297
 
298 298
 
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
     public function is_messenger_active($messenger_name)
306 306
     {
307 307
         $this->_initialize_collections();
308
-        return ! empty($this->_active_message_types[ $messenger_name ]);
308
+        return ! empty($this->_active_message_types[$messenger_name]);
309 309
     }
310 310
 
311 311
 
@@ -320,8 +320,8 @@  discard block
 block discarded – undo
320 320
     {
321 321
         $settings = array();
322 322
         if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
-            $settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
-                ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
323
+            $settings = isset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'])
324
+                ? $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings']
325 325
                 : array();
326 326
         }
327 327
         return $settings;
@@ -339,8 +339,8 @@  discard block
 block discarded – undo
339 339
     {
340 340
         $this->_initialize_collections();
341 341
         return
342
-            ! empty($this->_active_message_types[ $messenger_name ])
343
-            && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
342
+            ! empty($this->_active_message_types[$messenger_name])
343
+            && ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types']);
344 344
     }
345 345
 
346 346
 
@@ -355,13 +355,13 @@  discard block
 block discarded – undo
355 355
     public function get_active_message_types_for_messenger($messenger_name)
356 356
     {
357 357
         $message_types = array();
358
-        if (! $this->messenger_has_active_message_types($messenger_name)) {
358
+        if ( ! $this->messenger_has_active_message_types($messenger_name)) {
359 359
             return $message_types;
360 360
         }
361 361
         $installed_message_types = $this->installed_message_types();
362 362
         foreach ($installed_message_types as $message_type_name => $message_type) {
363 363
             if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
-                $message_types[ $message_type_name ] = $message_type;
364
+                $message_types[$message_type_name] = $message_type;
365 365
             }
366 366
         }
367 367
         return $message_types;
@@ -380,11 +380,11 @@  discard block
 block discarded – undo
380 380
         $active_message_type_names = array();
381 381
         $this->_initialize_collections();
382 382
         foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
-            if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
383
+            if ( ! isset($messenger_settings['settings'][$messenger.'-message_types'])) {
384 384
                 continue;
385 385
             }
386
-            foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
-                if (! in_array($message_type_name, $active_message_type_names)) {
386
+            foreach ($messenger_settings['settings'][$messenger.'-message_types'] as $message_type_name => $message_type_config) {
387
+                if ( ! in_array($message_type_name, $active_message_type_names)) {
388 388
                     $active_message_type_names[] = $message_type_name;
389 389
                 }
390 390
             }
@@ -405,8 +405,8 @@  discard block
 block discarded – undo
405 405
         $installed_message_types   = $this->installed_message_types();
406 406
         $active_message_type_names = $this->list_of_active_message_types();
407 407
         foreach ($active_message_type_names as $active_message_type_name) {
408
-            if (isset($installed_message_types[ $active_message_type_name ])) {
409
-                $active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
408
+            if (isset($installed_message_types[$active_message_type_name])) {
409
+                $active_message_types[$active_message_type_name] = $installed_message_types[$active_message_type_name];
410 410
             }
411 411
         }
412 412
         return $active_message_types;
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
         if (empty($this->_installed_message_types)) {
422 422
             $this->message_type_collection()->rewind();
423 423
             while ($this->message_type_collection()->valid()) {
424
-                $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
424
+                $this->_installed_message_types[$this->message_type_collection()->current()->name] = $this->message_type_collection()->current();
425 425
                 $this->message_type_collection()->next();
426 426
             }
427 427
         }
@@ -460,7 +460,7 @@  discard block
 block discarded – undo
460 460
     public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461 461
     {
462 462
         $valid_message_types = $messenger->get_valid_message_types();
463
-        if (! in_array($message_type_name, $valid_message_types)) {
463
+        if ( ! in_array($message_type_name, $valid_message_types)) {
464 464
             throw new EE_Error(
465 465
                 sprintf(
466 466
                     __(
@@ -586,7 +586,7 @@  discard block
 block discarded – undo
586 586
      */
587 587
     public function ensure_messenger_is_active($messenger_name, $update_option = true)
588 588
     {
589
-        if (! isset($this->_active_messengers[ $messenger_name ])) {
589
+        if ( ! isset($this->_active_messengers[$messenger_name])) {
590 590
             try {
591 591
                 $this->activate_messenger($messenger_name, array(), $update_option);
592 592
             } catch (EE_Error $e) {
@@ -631,7 +631,7 @@  discard block
 block discarded – undo
631 631
             $this->ensure_messenger_is_active($messenger_name, $update_option);
632 632
         }
633 633
 
634
-        if (! empty($not_installed)) {
634
+        if ( ! empty($not_installed)) {
635 635
             EE_Error::add_error(
636 636
                 sprintf(
637 637
                     __('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
@@ -664,7 +664,7 @@  discard block
 block discarded – undo
664 664
             // ensure messenger is active (that's an inherent coupling between active message types and the
665 665
             // messenger they are being activated for.
666 666
             try {
667
-                if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
667
+                if ( ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668 668
                     // all is good so let's just get it active
669 669
                     $this->activate_messenger($messenger, array($message_type_name), $update_option);
670 670
                 }
@@ -728,7 +728,7 @@  discard block
 block discarded – undo
728 728
             : $this->messenger_collection()->get_by_info($messenger);
729 729
         // it's inactive. Activate it.
730 730
         if ($messenger instanceof EE_messenger) {
731
-            $this->_active_messengers[ $messenger->name ] = $messenger;
731
+            $this->_active_messengers[$messenger->name] = $messenger;
732 732
             // activate incoming message types set to be activated with messenger.
733 733
             $message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734 734
             // setup any initial settings for the messenger if necessary.
@@ -740,7 +740,7 @@  discard block
 block discarded – undo
740 740
             // generate new templates if necessary and ensure all related templates that are already in the database are
741 741
             // marked active.  Note, this will also deactivate a message type for a messenger if the template
742 742
             // cannot be successfully created during its attempt (only happens for global template attempts).
743
-            if (! empty($message_type_names)) {
743
+            if ( ! empty($message_type_names)) {
744 744
                 $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745 745
                 EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746 746
             }
@@ -764,13 +764,13 @@  discard block
 block discarded – undo
764 764
         // things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765 765
         // So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766 766
         // only override _active_message_types when an explicit array of $message_type_names has been provided.
767
-        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
767
+        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[$messenger->name])
768 768
             ? $messenger->get_default_message_types()
769 769
             : (array) $message_type_names;
770 770
 
771 771
         // now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
-        if (! isset($this->_active_message_types[ $messenger->name ])) {
773
-            $this->_active_message_types[ $messenger->name ]['settings'] = array();
772
+        if ( ! isset($this->_active_message_types[$messenger->name])) {
773
+            $this->_active_message_types[$messenger->name]['settings'] = array();
774 774
         }
775 775
 
776 776
         if ($message_type_names) {
@@ -778,7 +778,7 @@  discard block
 block discarded – undo
778 778
             foreach ($message_type_names as $message_type_name) {
779 779
                 // only register the message type as active IF it isn't already active
780 780
                 // and if its actually installed.
781
-                if (! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
781
+                if ( ! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
782 782
                 ) {
783 783
                     $this->add_settings_for_message_type($messenger->name, $message_type_name);
784 784
                     $this->_set_messenger_has_activated_message_type(
@@ -810,16 +810,16 @@  discard block
 block discarded – undo
810 810
         if ($message_type instanceof EE_message_type) {
811 811
             $default_settings = $message_type->get_admin_settings_fields();
812 812
             foreach ($default_settings as $field => $values) {
813
-                if (isset($new_settings[ $field ])) {
814
-                    $existing_settings[ $field ] = $new_settings[ $field ];
813
+                if (isset($new_settings[$field])) {
814
+                    $existing_settings[$field] = $new_settings[$field];
815 815
                     continue;
816 816
                 }
817
-                if (! isset($existing_settings[ $field ])) {
818
-                    $existing_settings[ $field ] = $values['default'];
817
+                if ( ! isset($existing_settings[$field])) {
818
+                    $existing_settings[$field] = $values['default'];
819 819
                 }
820 820
             }
821 821
         }
822
-        $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
822
+        $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'] = $existing_settings;
823 823
     }
824 824
 
825 825
 
@@ -842,12 +842,12 @@  discard block
 block discarded – undo
842 842
         }
843 843
 
844 844
         // make sure this messenger has a record in the has_activated array
845
-        if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
846
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
845
+        if ( ! isset($this->_has_activated_messengers_and_message_types[$messenger->name])) {
846
+            $this->_has_activated_messengers_and_message_types[$messenger->name] = array();
847 847
         }
848 848
         // check if message type has already been added
849
-        if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
850
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
849
+        if ( ! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[$messenger->name])) {
850
+            $this->_has_activated_messengers_and_message_types[$messenger->name][] = $message_type_name;
851 851
         }
852 852
     }
853 853
 
@@ -865,16 +865,16 @@  discard block
 block discarded – undo
865 865
         $messenger = $this->get_messenger($messenger_name);
866 866
         if ($messenger instanceof EE_messenger) {
867 867
             $msgr_settings = $messenger->get_admin_settings_fields();
868
-            if (! empty($msgr_settings)) {
868
+            if ( ! empty($msgr_settings)) {
869 869
                 foreach ($msgr_settings as $field => $value) {
870 870
                     // is there a new setting for this?
871
-                    if (isset($new_settings[ $field ])) {
872
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
871
+                    if (isset($new_settings[$field])) {
872
+                        $this->_active_message_types[$messenger->name]['settings'][$field] = $new_settings[$field];
873 873
                         continue;
874 874
                     }
875 875
                     // only set the default if it isn't already set.
876
-                    if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
877
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
876
+                    if ( ! isset($this->_active_message_types[$messenger->name]['settings'][$field])) {
877
+                        $this->_active_message_types[$messenger->name]['settings'][$field] = $value;
878 878
                     }
879 879
                 }
880 880
             }
@@ -894,8 +894,8 @@  discard block
 block discarded – undo
894 894
         if ($messenger_name instanceof EE_messenger) {
895 895
             $messenger_name = $messenger_name->name;
896 896
         }
897
-        unset($this->_active_messengers[ $messenger_name ]);
898
-        unset($this->_active_message_types[ $messenger_name ]);
897
+        unset($this->_active_messengers[$messenger_name]);
898
+        unset($this->_active_message_types[$messenger_name]);
899 899
         $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
900 900
         $this->update_active_messengers_option();
901 901
     }
@@ -917,7 +917,7 @@  discard block
 block discarded – undo
917 917
         }
918 918
         foreach ($this->_active_message_types as $messenger_name => $settings) {
919 919
             unset(
920
-                $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
920
+                $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]
921 921
             );
922 922
 
923 923
             // we always record (even on deactivation) that a message type has been activated because there should at
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
     {
944 944
         $this->_initialize_collections();
945 945
         if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
946
-            unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
946
+            unset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]);
947 947
         }
948 948
         $this->_message_template_group_model->deactivate_message_template_groups_for(
949 949
             array($messenger_name),
@@ -1003,22 +1003,22 @@  discard block
 block discarded – undo
1003 1003
     {
1004 1004
         $key = $slugs_only ? 'slugs' : 'all';
1005 1005
         // check if contexts has been setup yet.
1006
-        if (empty($this->_contexts[ $key ])) {
1006
+        if (empty($this->_contexts[$key])) {
1007 1007
             // So let's get all active message type objects and loop through to get all unique contexts
1008 1008
             foreach ($this->get_active_message_type_objects() as $message_type) {
1009 1009
                 if ($message_type instanceof EE_message_type) {
1010 1010
                     $message_type_contexts = $message_type->get_contexts();
1011 1011
                     if ($slugs_only) {
1012 1012
                         foreach ($message_type_contexts as $context => $context_details) {
1013
-                            $this->_contexts[ $key ][ $context ] = $context_details['label'];
1013
+                            $this->_contexts[$key][$context] = $context_details['label'];
1014 1014
                         }
1015 1015
                     } else {
1016
-                        $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1016
+                        $this->_contexts[$key][$message_type->name] = $message_type_contexts;
1017 1017
                     }
1018 1018
                 }
1019 1019
             }
1020 1020
         }
1021
-        return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1021
+        return ! empty($this->_contexts[$key]) ? $this->_contexts[$key] : array();
1022 1022
     }
1023 1023
 
1024 1024
 
@@ -1038,7 +1038,7 @@  discard block
 block discarded – undo
1038 1038
         $all_message_types_valid           = true;
1039 1039
         // loop through list of active message types and verify they are installed.
1040 1040
         foreach ($list_of_active_message_type_names as $message_type_name) {
1041
-            if (! isset($installed_message_types[ $message_type_name ])) {
1041
+            if ( ! isset($installed_message_types[$message_type_name])) {
1042 1042
                 $this->remove_message_type_has_been_activated_from_all_messengers(
1043 1043
                     $message_type_name,
1044 1044
                     true
@@ -1065,8 +1065,8 @@  discard block
 block discarded – undo
1065 1065
     public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1066 1066
     {
1067 1067
         $has_activated = $this->get_has_activated_messengers_option();
1068
-        return isset($has_activated[ $messenger_name ])
1069
-               && in_array($message_type_name, $has_activated[ $messenger_name ]);
1068
+        return isset($has_activated[$messenger_name])
1069
+               && in_array($message_type_name, $has_activated[$messenger_name]);
1070 1070
     }
1071 1071
 
1072 1072
 
@@ -1094,11 +1094,11 @@  discard block
 block discarded – undo
1094 1094
             return;
1095 1095
         }
1096 1096
         $has_activated = $this->get_has_activated_messengers_option();
1097
-        $key_for_message_type = isset($has_activated[ $messenger_name ])
1098
-            ? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1097
+        $key_for_message_type = isset($has_activated[$messenger_name])
1098
+            ? array_search($message_type_name, $has_activated[$messenger_name], true)
1099 1099
             : false;
1100 1100
         if ($key_for_message_type !== false) {
1101
-            unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1101
+            unset($has_activated[$messenger_name][$key_for_message_type]);
1102 1102
             $this->update_has_activated_messengers_option($has_activated);
1103 1103
             // reset the internal cached property
1104 1104
             $this->get_has_activated_messengers_option(true);
Please login to merge, or discard this patch.
core/libraries/plugin_api/EE_Register_Addon.lib.php 1 patch
Indentation   +1164 added lines, -1164 removed lines patch added patch discarded remove patch
@@ -22,1228 +22,1228 @@
 block discarded – undo
22 22
 class EE_Register_Addon implements EEI_Plugin_API
23 23
 {
24 24
 
25
-    /**
26
-     * possibly truncated version of the EE core version string
27
-     *
28
-     * @var string
29
-     */
30
-    protected static $_core_version = '';
25
+	/**
26
+	 * possibly truncated version of the EE core version string
27
+	 *
28
+	 * @var string
29
+	 */
30
+	protected static $_core_version = '';
31 31
 
32
-    /**
33
-     * Holds values for registered addons
34
-     *
35
-     * @var array
36
-     */
37
-    protected static $_settings = array();
32
+	/**
33
+	 * Holds values for registered addons
34
+	 *
35
+	 * @var array
36
+	 */
37
+	protected static $_settings = array();
38 38
 
39
-    /**
40
-     * @var  array $_incompatible_addons keys are addon SLUGS
41
-     * (first argument passed to EE_Register_Addon::register()), keys are
42
-     * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004).
43
-     * Generally this should be used sparingly, as we don't want to muddle up
44
-     * EE core with knowledge of ALL the addons out there.
45
-     * If you want NO versions of an addon to run with a certain version of core,
46
-     * it's usually best to define the addon's "min_core_version" as part of its call
47
-     * to EE_Register_Addon::register(), rather than using this array with a super high value for its
48
-     * minimum plugin version.
49
-     * @access    protected
50
-     */
51
-    protected static $_incompatible_addons = array(
52
-        'Multi_Event_Registration' => '2.0.11.rc.002',
53
-        'Promotions'               => '1.0.0.rc.084',
54
-    );
39
+	/**
40
+	 * @var  array $_incompatible_addons keys are addon SLUGS
41
+	 * (first argument passed to EE_Register_Addon::register()), keys are
42
+	 * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004).
43
+	 * Generally this should be used sparingly, as we don't want to muddle up
44
+	 * EE core with knowledge of ALL the addons out there.
45
+	 * If you want NO versions of an addon to run with a certain version of core,
46
+	 * it's usually best to define the addon's "min_core_version" as part of its call
47
+	 * to EE_Register_Addon::register(), rather than using this array with a super high value for its
48
+	 * minimum plugin version.
49
+	 * @access    protected
50
+	 */
51
+	protected static $_incompatible_addons = array(
52
+		'Multi_Event_Registration' => '2.0.11.rc.002',
53
+		'Promotions'               => '1.0.0.rc.084',
54
+	);
55 55
 
56 56
 
57
-    /**
58
-     * We should always be comparing core to a version like '4.3.0.rc.000',
59
-     * not just '4.3.0'.
60
-     * So if the addon developer doesn't provide that full version string,
61
-     * fill in the blanks for them
62
-     *
63
-     * @param string $min_core_version
64
-     * @return string always like '4.3.0.rc.000'
65
-     */
66
-    protected static function _effective_version($min_core_version)
67
-    {
68
-        // versions: 4 . 3 . 1 . p . 123
69
-        // offsets:    0 . 1 . 2 . 3 . 4
70
-        $version_parts = explode('.', $min_core_version);
71
-        // check they specified the micro version (after 2nd period)
72
-        if (! isset($version_parts[2])) {
73
-            $version_parts[2] = '0';
74
-        }
75
-        // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76
-        // soon we can assume that's 'rc', but this current version is 'alpha'
77
-        if (! isset($version_parts[3])) {
78
-            $version_parts[3] = 'dev';
79
-        }
80
-        if (! isset($version_parts[4])) {
81
-            $version_parts[4] = '000';
82
-        }
83
-        return implode('.', $version_parts);
84
-    }
57
+	/**
58
+	 * We should always be comparing core to a version like '4.3.0.rc.000',
59
+	 * not just '4.3.0'.
60
+	 * So if the addon developer doesn't provide that full version string,
61
+	 * fill in the blanks for them
62
+	 *
63
+	 * @param string $min_core_version
64
+	 * @return string always like '4.3.0.rc.000'
65
+	 */
66
+	protected static function _effective_version($min_core_version)
67
+	{
68
+		// versions: 4 . 3 . 1 . p . 123
69
+		// offsets:    0 . 1 . 2 . 3 . 4
70
+		$version_parts = explode('.', $min_core_version);
71
+		// check they specified the micro version (after 2nd period)
72
+		if (! isset($version_parts[2])) {
73
+			$version_parts[2] = '0';
74
+		}
75
+		// if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76
+		// soon we can assume that's 'rc', but this current version is 'alpha'
77
+		if (! isset($version_parts[3])) {
78
+			$version_parts[3] = 'dev';
79
+		}
80
+		if (! isset($version_parts[4])) {
81
+			$version_parts[4] = '000';
82
+		}
83
+		return implode('.', $version_parts);
84
+	}
85 85
 
86 86
 
87
-    /**
88
-     * Returns whether or not the min core version requirement of the addon is met
89
-     *
90
-     * @param string $min_core_version    the minimum core version required by the addon
91
-     * @param string $actual_core_version the actual core version, optional
92
-     * @return boolean
93
-     */
94
-    public static function _meets_min_core_version_requirement(
95
-        $min_core_version,
96
-        $actual_core_version = EVENT_ESPRESSO_VERSION
97
-    ) {
98
-        return version_compare(
99
-            self::_effective_version($actual_core_version),
100
-            self::_effective_version($min_core_version),
101
-            '>='
102
-        );
103
-    }
87
+	/**
88
+	 * Returns whether or not the min core version requirement of the addon is met
89
+	 *
90
+	 * @param string $min_core_version    the minimum core version required by the addon
91
+	 * @param string $actual_core_version the actual core version, optional
92
+	 * @return boolean
93
+	 */
94
+	public static function _meets_min_core_version_requirement(
95
+		$min_core_version,
96
+		$actual_core_version = EVENT_ESPRESSO_VERSION
97
+	) {
98
+		return version_compare(
99
+			self::_effective_version($actual_core_version),
100
+			self::_effective_version($min_core_version),
101
+			'>='
102
+		);
103
+	}
104 104
 
105 105
 
106
-    /**
107
-     * Method for registering new EE_Addons.
108
-     * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE
109
-     * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it
110
-     * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon
111
-     * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after
112
-     * 'activate_plugin', it registers the addon still, but its components are not registered
113
-     * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do
114
-     * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns
115
-     * (so that we can detect that the addon has activated on the subsequent request)
116
-     *
117
-     * @since    4.3.0
118
-     * @param string                  $addon_name                       [Required] the EE_Addon's name.
119
-     * @param  array                  $setup_args                       {
120
-     *                                                                  An array of arguments provided for registering
121
-     *                                                                  the message type.
122
-     * @type  string                  $class_name                       the addon's main file name.
123
-     *                                                                  If left blank, generated from the addon name,
124
-     *                                                                  changes something like "calendar" to
125
-     *                                                                  "EE_Calendar"
126
-     * @type string                   $min_core_version                 the minimum version of EE Core that the
127
-     *                                                                  addon will work with. eg "4.8.1.rc.084"
128
-     * @type string                   $version                          the "software" version for the addon. eg
129
-     *                                                                  "1.0.0.p" for a first stable release, or
130
-     *                                                                  "1.0.0.rc.043" for a version in progress
131
-     * @type string                   $main_file_path                   the full server path to the main file
132
-     *                                                                  loaded directly by WP
133
-     * @type DomainInterface $domain                                    child class of
134
-     *                                                                  EventEspresso\core\domain\DomainBase
135
-     * @type string                   $domain_fqcn                      Fully Qualified Class Name
136
-     *                                                                  for the addon's Domain class
137
-     *                                                                  (see EventEspresso\core\domain\Domain)
138
-     * @type string                   $admin_path                       full server path to the folder where the
139
-     *                                                                  addon\'s admin files reside
140
-     * @type string                   $admin_callback                   a method to be called when the EE Admin is
141
-     *                                                                  first invoked, can be used for hooking into
142
-     *                                                                  any admin page
143
-     * @type string                   $config_section                   the section name for this addon's
144
-     *                                                                  configuration settings section
145
-     *                                                                  (defaults to "addons")
146
-     * @type string                   $config_class                     the class name for this addon's
147
-     *                                                                  configuration settings object
148
-     * @type string                   $config_name                      the class name for this addon's
149
-     *                                                                  configuration settings object
150
-     * @type string                   $autoloader_paths                 [Required] an array of class names and the full
151
-     *                                                                  server paths to those files.
152
-     * @type string                   $autoloader_folders               an array of  "full server paths" for any
153
-     *                                                                  folders containing classes that might be
154
-     *                                                                  invoked by the addon
155
-     * @type string                   $dms_paths                        [Required] an array of full server paths to
156
-     *                                                                  folders that contain data migration scripts.
157
-     *                                                                  The key should be the EE_Addon class name that
158
-     *                                                                  this set of data migration scripts belongs to.
159
-     *                                                                  If the EE_Addon class is namespaced, then this
160
-     *                                                                  needs to be the Fully Qualified Class Name
161
-     * @type string                   $module_paths                     an array of full server paths to any
162
-     *                                                                  EED_Modules used by the addon
163
-     * @type string                   $shortcode_paths                  an array of full server paths to folders
164
-     *                                                                  that contain EES_Shortcodes
165
-     * @type string                   $widget_paths                     an array of full server paths to folders
166
-     *                                                                  that contain WP_Widgets
167
-     * @type string                   $pue_options
168
-     * @type array                    $capabilities                     an array indexed by role name
169
-     *                                                                  (i.e administrator,author ) and the values
170
-     *                                                                  are an array of caps to add to the role.
171
-     *                                                                  'administrator' => array(
172
-     *                                                                  'read_addon',
173
-     *                                                                  'edit_addon',
174
-     *                                                                  etc.
175
-     *                                                                  ).
176
-     * @type EE_Meta_Capability_Map[] $capability_maps                  an array of EE_Meta_Capability_Map object
177
-     *                                                                  for any addons that need to register any
178
-     *                                                                  special meta mapped capabilities.  Should
179
-     *                                                                  be indexed where the key is the
180
-     *                                                                  EE_Meta_Capability_Map class name and the
181
-     *                                                                  values are the arguments sent to the class.
182
-     * @type array                    $model_paths                      array of folders containing DB models
183
-     * @see      EE_Register_Model
184
-     * @type array                    $class_paths                      array of folders containing DB classes
185
-     * @see      EE_Register_Model
186
-     * @type array                    $model_extension_paths            array of folders containing DB model
187
-     *                                                                  extensions
188
-     * @see      EE_Register_Model_Extension
189
-     * @type array                    $class_extension_paths            array of folders containing DB class
190
-     *                                                                  extensions
191
-     * @see      EE_Register_Model_Extension
192
-     * @type array message_types {
193
-     *                                                                  An array of message types with the key as
194
-     *                                                                  the message type name and the values as
195
-     *                                                                  below:
196
-     * @type string                   $mtfilename                       [Required] The filename of the message type
197
-     *                                                                  being registered. This will be the main
198
-     *                                                                  EE_{Message Type Name}_message_type class.
199
-     *                                                                  for example:
200
-     *                                                                  EE_Declined_Registration_message_type.class.php
201
-     * @type array                    $autoloadpaths                    [Required] An array of paths to add to the
202
-     *                                                                  messages autoloader for the new message type.
203
-     * @type array                    $messengers_to_activate_with      An array of messengers that this message
204
-     *                                                                  type should activate with. Each value in
205
-     *                                                                  the
206
-     *                                                                  array
207
-     *                                                                  should match the name property of a
208
-     *                                                                  EE_messenger. Optional.
209
-     * @type array                    $messengers_to_validate_with      An array of messengers that this message
210
-     *                                                                  type should validate with. Each value in
211
-     *                                                                  the
212
-     *                                                                  array
213
-     *                                                                  should match the name property of an
214
-     *                                                                  EE_messenger.
215
-     *                                                                  Optional.
216
-     *                                                                  }
217
-     * @type array                    $custom_post_types
218
-     * @type array                    $custom_taxonomies
219
-     * @type array                    $payment_method_paths             each element is the folder containing the
220
-     *                                                                  EE_PMT_Base child class
221
-     *                                                                  (eg,
222
-     *                                                                  '/wp-content/plugins/my_plugin/Payomatic/'
223
-     *                                                                  which contains the files
224
-     *                                                                  EE_PMT_Payomatic.pm.php)
225
-     * @type array                    $default_terms
226
-     * @type array                    $namespace                        {
227
-     *                                                                  An array with two items for registering the
228
-     *                                                                  addon's namespace. (If, for some reason, you
229
-     *                                                                  require additional namespaces,
230
-     *                                                                  use
231
-     *                                                                  EventEspresso\core\Psr4Autoloader::addNamespace()
232
-     *                                                                  directly)
233
-     * @see      EventEspresso\core\Psr4Autoloader::addNamespace()
234
-     * @type string                   $FQNS                             the namespace prefix
235
-     * @type string                   $DIR                              a base directory for class files in the
236
-     *                                                                  namespace.
237
-     *                                                                  }
238
-     *                                                                  }
239
-     * @type string                   $privacy_policies                 FQNSs (namespaces, each of which contains only
240
-     *                                                                  privacy policy classes) or FQCNs (specific
241
-     *                                                                  classnames of privacy policy classes)
242
-     * @type string                   $personal_data_exporters          FQNSs (namespaces, each of which contains only
243
-     *                                                                  privacy policy classes) or FQCNs (specific
244
-     *                                                                  classnames of privacy policy classes)
245
-     * @type string                   $personal_data_erasers            FQNSs (namespaces, each of which contains only
246
-     *                                                                  privacy policy classes) or FQCNs (specific
247
-     *                                                                  classnames of privacy policy classes)
248
-     * @return void
249
-     * @throws DomainException
250
-     * @throws EE_Error
251
-     * @throws InvalidArgumentException
252
-     * @throws ReflectionException
253
-     * @throws InvalidDataTypeException
254
-     * @throws InvalidInterfaceException
255
-     */
256
-    public static function register($addon_name = '', $setup_args = array())
257
-    {
258
-        // required fields MUST be present, so let's make sure they are.
259
-        EE_Register_Addon::_verify_parameters($addon_name, $setup_args);
260
-        // get class name for addon
261
-        $class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args);
262
-        // setup $_settings array from incoming values.
263
-        $addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args);
264
-        // setup PUE
265
-        EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
266
-        // does this addon work with this version of core or WordPress ?
267
-        if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268
-            return;
269
-        }
270
-        // register namespaces
271
-        EE_Register_Addon::_setup_namespaces($addon_settings);
272
-        // check if this is an activation request
273
-        if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) {
274
-            // dont bother setting up the rest of the addon atm
275
-            return;
276
-        }
277
-        // we need cars
278
-        EE_Register_Addon::_setup_autoloaders($addon_name);
279
-        // register new models and extensions
280
-        EE_Register_Addon::_register_models_and_extensions($addon_name);
281
-        // setup DMS
282
-        EE_Register_Addon::_register_data_migration_scripts($addon_name);
283
-        // if config_class is present let's register config.
284
-        EE_Register_Addon::_register_config($addon_name);
285
-        // register admin pages
286
-        EE_Register_Addon::_register_admin_pages($addon_name);
287
-        // add to list of modules to be registered
288
-        EE_Register_Addon::_register_modules($addon_name);
289
-        // add to list of shortcodes to be registered
290
-        EE_Register_Addon::_register_shortcodes($addon_name);
291
-        // add to list of widgets to be registered
292
-        EE_Register_Addon::_register_widgets($addon_name);
293
-        // register capability related stuff.
294
-        EE_Register_Addon::_register_capabilities($addon_name);
295
-        // any message type to register?
296
-        EE_Register_Addon::_register_message_types($addon_name);
297
-        // any custom post type/ custom capabilities or default terms to register
298
-        EE_Register_Addon::_register_custom_post_types($addon_name);
299
-        // and any payment methods
300
-        EE_Register_Addon::_register_payment_methods($addon_name);
301
-        // and privacy policy generators
302
-        EE_Register_Addon::registerPrivacyPolicies($addon_name);
303
-        // and privacy policy generators
304
-        EE_Register_Addon::registerPersonalDataExporters($addon_name);
305
-        // and privacy policy generators
306
-        EE_Register_Addon::registerPersonalDataErasers($addon_name);
307
-        // load and instantiate main addon class
308
-        $addon = EE_Register_Addon::_load_and_init_addon_class($addon_name);
309
-        // delay calling after_registration hook on each addon until after all add-ons have been registered.
310
-        add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999);
311
-    }
106
+	/**
107
+	 * Method for registering new EE_Addons.
108
+	 * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE
109
+	 * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it
110
+	 * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon
111
+	 * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after
112
+	 * 'activate_plugin', it registers the addon still, but its components are not registered
113
+	 * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do
114
+	 * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns
115
+	 * (so that we can detect that the addon has activated on the subsequent request)
116
+	 *
117
+	 * @since    4.3.0
118
+	 * @param string                  $addon_name                       [Required] the EE_Addon's name.
119
+	 * @param  array                  $setup_args                       {
120
+	 *                                                                  An array of arguments provided for registering
121
+	 *                                                                  the message type.
122
+	 * @type  string                  $class_name                       the addon's main file name.
123
+	 *                                                                  If left blank, generated from the addon name,
124
+	 *                                                                  changes something like "calendar" to
125
+	 *                                                                  "EE_Calendar"
126
+	 * @type string                   $min_core_version                 the minimum version of EE Core that the
127
+	 *                                                                  addon will work with. eg "4.8.1.rc.084"
128
+	 * @type string                   $version                          the "software" version for the addon. eg
129
+	 *                                                                  "1.0.0.p" for a first stable release, or
130
+	 *                                                                  "1.0.0.rc.043" for a version in progress
131
+	 * @type string                   $main_file_path                   the full server path to the main file
132
+	 *                                                                  loaded directly by WP
133
+	 * @type DomainInterface $domain                                    child class of
134
+	 *                                                                  EventEspresso\core\domain\DomainBase
135
+	 * @type string                   $domain_fqcn                      Fully Qualified Class Name
136
+	 *                                                                  for the addon's Domain class
137
+	 *                                                                  (see EventEspresso\core\domain\Domain)
138
+	 * @type string                   $admin_path                       full server path to the folder where the
139
+	 *                                                                  addon\'s admin files reside
140
+	 * @type string                   $admin_callback                   a method to be called when the EE Admin is
141
+	 *                                                                  first invoked, can be used for hooking into
142
+	 *                                                                  any admin page
143
+	 * @type string                   $config_section                   the section name for this addon's
144
+	 *                                                                  configuration settings section
145
+	 *                                                                  (defaults to "addons")
146
+	 * @type string                   $config_class                     the class name for this addon's
147
+	 *                                                                  configuration settings object
148
+	 * @type string                   $config_name                      the class name for this addon's
149
+	 *                                                                  configuration settings object
150
+	 * @type string                   $autoloader_paths                 [Required] an array of class names and the full
151
+	 *                                                                  server paths to those files.
152
+	 * @type string                   $autoloader_folders               an array of  "full server paths" for any
153
+	 *                                                                  folders containing classes that might be
154
+	 *                                                                  invoked by the addon
155
+	 * @type string                   $dms_paths                        [Required] an array of full server paths to
156
+	 *                                                                  folders that contain data migration scripts.
157
+	 *                                                                  The key should be the EE_Addon class name that
158
+	 *                                                                  this set of data migration scripts belongs to.
159
+	 *                                                                  If the EE_Addon class is namespaced, then this
160
+	 *                                                                  needs to be the Fully Qualified Class Name
161
+	 * @type string                   $module_paths                     an array of full server paths to any
162
+	 *                                                                  EED_Modules used by the addon
163
+	 * @type string                   $shortcode_paths                  an array of full server paths to folders
164
+	 *                                                                  that contain EES_Shortcodes
165
+	 * @type string                   $widget_paths                     an array of full server paths to folders
166
+	 *                                                                  that contain WP_Widgets
167
+	 * @type string                   $pue_options
168
+	 * @type array                    $capabilities                     an array indexed by role name
169
+	 *                                                                  (i.e administrator,author ) and the values
170
+	 *                                                                  are an array of caps to add to the role.
171
+	 *                                                                  'administrator' => array(
172
+	 *                                                                  'read_addon',
173
+	 *                                                                  'edit_addon',
174
+	 *                                                                  etc.
175
+	 *                                                                  ).
176
+	 * @type EE_Meta_Capability_Map[] $capability_maps                  an array of EE_Meta_Capability_Map object
177
+	 *                                                                  for any addons that need to register any
178
+	 *                                                                  special meta mapped capabilities.  Should
179
+	 *                                                                  be indexed where the key is the
180
+	 *                                                                  EE_Meta_Capability_Map class name and the
181
+	 *                                                                  values are the arguments sent to the class.
182
+	 * @type array                    $model_paths                      array of folders containing DB models
183
+	 * @see      EE_Register_Model
184
+	 * @type array                    $class_paths                      array of folders containing DB classes
185
+	 * @see      EE_Register_Model
186
+	 * @type array                    $model_extension_paths            array of folders containing DB model
187
+	 *                                                                  extensions
188
+	 * @see      EE_Register_Model_Extension
189
+	 * @type array                    $class_extension_paths            array of folders containing DB class
190
+	 *                                                                  extensions
191
+	 * @see      EE_Register_Model_Extension
192
+	 * @type array message_types {
193
+	 *                                                                  An array of message types with the key as
194
+	 *                                                                  the message type name and the values as
195
+	 *                                                                  below:
196
+	 * @type string                   $mtfilename                       [Required] The filename of the message type
197
+	 *                                                                  being registered. This will be the main
198
+	 *                                                                  EE_{Message Type Name}_message_type class.
199
+	 *                                                                  for example:
200
+	 *                                                                  EE_Declined_Registration_message_type.class.php
201
+	 * @type array                    $autoloadpaths                    [Required] An array of paths to add to the
202
+	 *                                                                  messages autoloader for the new message type.
203
+	 * @type array                    $messengers_to_activate_with      An array of messengers that this message
204
+	 *                                                                  type should activate with. Each value in
205
+	 *                                                                  the
206
+	 *                                                                  array
207
+	 *                                                                  should match the name property of a
208
+	 *                                                                  EE_messenger. Optional.
209
+	 * @type array                    $messengers_to_validate_with      An array of messengers that this message
210
+	 *                                                                  type should validate with. Each value in
211
+	 *                                                                  the
212
+	 *                                                                  array
213
+	 *                                                                  should match the name property of an
214
+	 *                                                                  EE_messenger.
215
+	 *                                                                  Optional.
216
+	 *                                                                  }
217
+	 * @type array                    $custom_post_types
218
+	 * @type array                    $custom_taxonomies
219
+	 * @type array                    $payment_method_paths             each element is the folder containing the
220
+	 *                                                                  EE_PMT_Base child class
221
+	 *                                                                  (eg,
222
+	 *                                                                  '/wp-content/plugins/my_plugin/Payomatic/'
223
+	 *                                                                  which contains the files
224
+	 *                                                                  EE_PMT_Payomatic.pm.php)
225
+	 * @type array                    $default_terms
226
+	 * @type array                    $namespace                        {
227
+	 *                                                                  An array with two items for registering the
228
+	 *                                                                  addon's namespace. (If, for some reason, you
229
+	 *                                                                  require additional namespaces,
230
+	 *                                                                  use
231
+	 *                                                                  EventEspresso\core\Psr4Autoloader::addNamespace()
232
+	 *                                                                  directly)
233
+	 * @see      EventEspresso\core\Psr4Autoloader::addNamespace()
234
+	 * @type string                   $FQNS                             the namespace prefix
235
+	 * @type string                   $DIR                              a base directory for class files in the
236
+	 *                                                                  namespace.
237
+	 *                                                                  }
238
+	 *                                                                  }
239
+	 * @type string                   $privacy_policies                 FQNSs (namespaces, each of which contains only
240
+	 *                                                                  privacy policy classes) or FQCNs (specific
241
+	 *                                                                  classnames of privacy policy classes)
242
+	 * @type string                   $personal_data_exporters          FQNSs (namespaces, each of which contains only
243
+	 *                                                                  privacy policy classes) or FQCNs (specific
244
+	 *                                                                  classnames of privacy policy classes)
245
+	 * @type string                   $personal_data_erasers            FQNSs (namespaces, each of which contains only
246
+	 *                                                                  privacy policy classes) or FQCNs (specific
247
+	 *                                                                  classnames of privacy policy classes)
248
+	 * @return void
249
+	 * @throws DomainException
250
+	 * @throws EE_Error
251
+	 * @throws InvalidArgumentException
252
+	 * @throws ReflectionException
253
+	 * @throws InvalidDataTypeException
254
+	 * @throws InvalidInterfaceException
255
+	 */
256
+	public static function register($addon_name = '', $setup_args = array())
257
+	{
258
+		// required fields MUST be present, so let's make sure they are.
259
+		EE_Register_Addon::_verify_parameters($addon_name, $setup_args);
260
+		// get class name for addon
261
+		$class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args);
262
+		// setup $_settings array from incoming values.
263
+		$addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args);
264
+		// setup PUE
265
+		EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
266
+		// does this addon work with this version of core or WordPress ?
267
+		if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268
+			return;
269
+		}
270
+		// register namespaces
271
+		EE_Register_Addon::_setup_namespaces($addon_settings);
272
+		// check if this is an activation request
273
+		if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) {
274
+			// dont bother setting up the rest of the addon atm
275
+			return;
276
+		}
277
+		// we need cars
278
+		EE_Register_Addon::_setup_autoloaders($addon_name);
279
+		// register new models and extensions
280
+		EE_Register_Addon::_register_models_and_extensions($addon_name);
281
+		// setup DMS
282
+		EE_Register_Addon::_register_data_migration_scripts($addon_name);
283
+		// if config_class is present let's register config.
284
+		EE_Register_Addon::_register_config($addon_name);
285
+		// register admin pages
286
+		EE_Register_Addon::_register_admin_pages($addon_name);
287
+		// add to list of modules to be registered
288
+		EE_Register_Addon::_register_modules($addon_name);
289
+		// add to list of shortcodes to be registered
290
+		EE_Register_Addon::_register_shortcodes($addon_name);
291
+		// add to list of widgets to be registered
292
+		EE_Register_Addon::_register_widgets($addon_name);
293
+		// register capability related stuff.
294
+		EE_Register_Addon::_register_capabilities($addon_name);
295
+		// any message type to register?
296
+		EE_Register_Addon::_register_message_types($addon_name);
297
+		// any custom post type/ custom capabilities or default terms to register
298
+		EE_Register_Addon::_register_custom_post_types($addon_name);
299
+		// and any payment methods
300
+		EE_Register_Addon::_register_payment_methods($addon_name);
301
+		// and privacy policy generators
302
+		EE_Register_Addon::registerPrivacyPolicies($addon_name);
303
+		// and privacy policy generators
304
+		EE_Register_Addon::registerPersonalDataExporters($addon_name);
305
+		// and privacy policy generators
306
+		EE_Register_Addon::registerPersonalDataErasers($addon_name);
307
+		// load and instantiate main addon class
308
+		$addon = EE_Register_Addon::_load_and_init_addon_class($addon_name);
309
+		// delay calling after_registration hook on each addon until after all add-ons have been registered.
310
+		add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999);
311
+	}
312 312
 
313 313
 
314
-    /**
315
-     * @param string $addon_name
316
-     * @param array  $setup_args
317
-     * @return void
318
-     * @throws EE_Error
319
-     */
320
-    private static function _verify_parameters($addon_name, array $setup_args)
321
-    {
322
-        // required fields MUST be present, so let's make sure they are.
323
-        if (empty($addon_name) || ! is_array($setup_args)) {
324
-            throw new EE_Error(
325
-                __(
326
-                    'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.',
327
-                    'event_espresso'
328
-                )
329
-            );
330
-        }
331
-        if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332
-            throw new EE_Error(
333
-                sprintf(
334
-                    __(
335
-                        'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s',
336
-                        'event_espresso'
337
-                    ),
338
-                    implode(',', array_keys($setup_args))
339
-                )
340
-            );
341
-        }
342
-        // check that addon has not already been registered with that name
343
-        if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
344
-            throw new EE_Error(
345
-                sprintf(
346
-                    __(
347
-                        'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.',
348
-                        'event_espresso'
349
-                    ),
350
-                    $addon_name
351
-                )
352
-            );
353
-        }
354
-    }
314
+	/**
315
+	 * @param string $addon_name
316
+	 * @param array  $setup_args
317
+	 * @return void
318
+	 * @throws EE_Error
319
+	 */
320
+	private static function _verify_parameters($addon_name, array $setup_args)
321
+	{
322
+		// required fields MUST be present, so let's make sure they are.
323
+		if (empty($addon_name) || ! is_array($setup_args)) {
324
+			throw new EE_Error(
325
+				__(
326
+					'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.',
327
+					'event_espresso'
328
+				)
329
+			);
330
+		}
331
+		if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332
+			throw new EE_Error(
333
+				sprintf(
334
+					__(
335
+						'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s',
336
+						'event_espresso'
337
+					),
338
+					implode(',', array_keys($setup_args))
339
+				)
340
+			);
341
+		}
342
+		// check that addon has not already been registered with that name
343
+		if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
344
+			throw new EE_Error(
345
+				sprintf(
346
+					__(
347
+						'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.',
348
+						'event_espresso'
349
+					),
350
+					$addon_name
351
+				)
352
+			);
353
+		}
354
+	}
355 355
 
356 356
 
357
-    /**
358
-     * @param string $addon_name
359
-     * @param array  $setup_args
360
-     * @return string
361
-     */
362
-    private static function _parse_class_name($addon_name, array $setup_args)
363
-    {
364
-        if (empty($setup_args['class_name'])) {
365
-            // generate one by first separating name with spaces
366
-            $class_name = str_replace(array('-', '_'), ' ', trim($addon_name));
367
-            // capitalize, then replace spaces with underscores
368
-            $class_name = str_replace(' ', '_', ucwords($class_name));
369
-        } else {
370
-            $class_name = $setup_args['class_name'];
371
-        }
372
-        // check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373
-        return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374
-            ? $class_name
375
-            : 'EE_' . $class_name;
376
-    }
357
+	/**
358
+	 * @param string $addon_name
359
+	 * @param array  $setup_args
360
+	 * @return string
361
+	 */
362
+	private static function _parse_class_name($addon_name, array $setup_args)
363
+	{
364
+		if (empty($setup_args['class_name'])) {
365
+			// generate one by first separating name with spaces
366
+			$class_name = str_replace(array('-', '_'), ' ', trim($addon_name));
367
+			// capitalize, then replace spaces with underscores
368
+			$class_name = str_replace(' ', '_', ucwords($class_name));
369
+		} else {
370
+			$class_name = $setup_args['class_name'];
371
+		}
372
+		// check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373
+		return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374
+			? $class_name
375
+			: 'EE_' . $class_name;
376
+	}
377 377
 
378 378
 
379
-    /**
380
-     * @param string $class_name
381
-     * @param array  $setup_args
382
-     * @return array
383
-     */
384
-    private static function _get_addon_settings($class_name, array $setup_args)
385
-    {
386
-        // setup $_settings array from incoming values.
387
-        $addon_settings = array(
388
-            // generated from the addon name, changes something like "calendar" to "EE_Calendar"
389
-            'class_name'            => $class_name,
390
-            // the addon slug for use in URLs, etc
391
-            'plugin_slug'           => isset($setup_args['plugin_slug'])
392
-                ? (string) $setup_args['plugin_slug']
393
-                : '',
394
-            // page slug to be used when generating the "Settings" link on the WP plugin page
395
-            'plugin_action_slug'    => isset($setup_args['plugin_action_slug'])
396
-                ? (string) $setup_args['plugin_action_slug']
397
-                : '',
398
-            // the "software" version for the addon
399
-            'version'               => isset($setup_args['version'])
400
-                ? (string) $setup_args['version']
401
-                : '',
402
-            // the minimum version of EE Core that the addon will work with
403
-            'min_core_version'      => isset($setup_args['min_core_version'])
404
-                ? (string) $setup_args['min_core_version']
405
-                : '',
406
-            // the minimum version of WordPress that the addon will work with
407
-            'min_wp_version'        => isset($setup_args['min_wp_version'])
408
-                ? (string) $setup_args['min_wp_version']
409
-                : EE_MIN_WP_VER_REQUIRED,
410
-            // full server path to main file (file loaded directly by WP)
411
-            'main_file_path'        => isset($setup_args['main_file_path'])
412
-                ? (string) $setup_args['main_file_path']
413
-                : '',
414
-            // instance of \EventEspresso\core\domain\DomainInterface
415
-            'domain'                => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface
416
-                ? $setup_args['domain']
417
-                : null,
418
-            // Fully Qualified Class Name for the addon's Domain class
419
-            'domain_fqcn'           => isset($setup_args['domain_fqcn'])
420
-                ? (string) $setup_args['domain_fqcn']
421
-                : '',
422
-            // path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages
423
-            'admin_path'            => isset($setup_args['admin_path'])
424
-                ? (string) $setup_args['admin_path'] : '',
425
-            // a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page
426
-            'admin_callback'        => isset($setup_args['admin_callback'])
427
-                ? (string) $setup_args['admin_callback']
428
-                : '',
429
-            // the section name for this addon's configuration settings section (defaults to "addons")
430
-            'config_section'        => isset($setup_args['config_section'])
431
-                ? (string) $setup_args['config_section']
432
-                : 'addons',
433
-            // the class name for this addon's configuration settings object
434
-            'config_class'          => isset($setup_args['config_class'])
435
-                ? (string) $setup_args['config_class'] : '',
436
-            // the name given to the config for this addons' configuration settings object (optional)
437
-            'config_name'           => isset($setup_args['config_name'])
438
-                ? (string) $setup_args['config_name'] : '',
439
-            // an array of "class names" => "full server paths" for any classes that might be invoked by the addon
440
-            'autoloader_paths'      => isset($setup_args['autoloader_paths'])
441
-                ? (array) $setup_args['autoloader_paths']
442
-                : array(),
443
-            // an array of  "full server paths" for any folders containing classes that might be invoked by the addon
444
-            'autoloader_folders'    => isset($setup_args['autoloader_folders'])
445
-                ? (array) $setup_args['autoloader_folders']
446
-                : array(),
447
-            // array of full server paths to any EE_DMS data migration scripts used by the addon.
448
-            // The key should be the EE_Addon class name that this set of data migration scripts belongs to.
449
-            // If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name
450
-            'dms_paths'             => isset($setup_args['dms_paths'])
451
-                ? (array) $setup_args['dms_paths']
452
-                : array(),
453
-            // array of full server paths to any EED_Modules used by the addon
454
-            'module_paths'          => isset($setup_args['module_paths'])
455
-                ? (array) $setup_args['module_paths']
456
-                : array(),
457
-            // array of full server paths to any EES_Shortcodes used by the addon
458
-            'shortcode_paths'       => isset($setup_args['shortcode_paths'])
459
-                ? (array) $setup_args['shortcode_paths']
460
-                : array(),
461
-            'shortcode_fqcns'       => isset($setup_args['shortcode_fqcns'])
462
-                ? (array) $setup_args['shortcode_fqcns']
463
-                : array(),
464
-            // array of full server paths to any WP_Widgets used by the addon
465
-            'widget_paths'          => isset($setup_args['widget_paths'])
466
-                ? (array) $setup_args['widget_paths']
467
-                : array(),
468
-            // array of PUE options used by the addon
469
-            'pue_options'           => isset($setup_args['pue_options'])
470
-                ? (array) $setup_args['pue_options']
471
-                : array(),
472
-            'message_types'         => isset($setup_args['message_types'])
473
-                ? (array) $setup_args['message_types']
474
-                : array(),
475
-            'capabilities'          => isset($setup_args['capabilities'])
476
-                ? (array) $setup_args['capabilities']
477
-                : array(),
478
-            'capability_maps'       => isset($setup_args['capability_maps'])
479
-                ? (array) $setup_args['capability_maps']
480
-                : array(),
481
-            'model_paths'           => isset($setup_args['model_paths'])
482
-                ? (array) $setup_args['model_paths']
483
-                : array(),
484
-            'class_paths'           => isset($setup_args['class_paths'])
485
-                ? (array) $setup_args['class_paths']
486
-                : array(),
487
-            'model_extension_paths' => isset($setup_args['model_extension_paths'])
488
-                ? (array) $setup_args['model_extension_paths']
489
-                : array(),
490
-            'class_extension_paths' => isset($setup_args['class_extension_paths'])
491
-                ? (array) $setup_args['class_extension_paths']
492
-                : array(),
493
-            'custom_post_types'     => isset($setup_args['custom_post_types'])
494
-                ? (array) $setup_args['custom_post_types']
495
-                : array(),
496
-            'custom_taxonomies'     => isset($setup_args['custom_taxonomies'])
497
-                ? (array) $setup_args['custom_taxonomies']
498
-                : array(),
499
-            'payment_method_paths'  => isset($setup_args['payment_method_paths'])
500
-                ? (array) $setup_args['payment_method_paths']
501
-                : array(),
502
-            'default_terms'         => isset($setup_args['default_terms'])
503
-                ? (array) $setup_args['default_terms']
504
-                : array(),
505
-            // if not empty, inserts a new table row after this plugin's row on the WP Plugins page
506
-            // that can be used for adding upgrading/marketing info
507
-            'plugins_page_row'      => isset($setup_args['plugins_page_row'])
508
-                ? $setup_args['plugins_page_row']
509
-                : '',
510
-            'namespace'             => isset(
511
-                $setup_args['namespace']['FQNS'],
512
-                $setup_args['namespace']['DIR']
513
-            )
514
-                ? (array) $setup_args['namespace']
515
-                : array(),
516
-            'privacy_policies'      => isset($setup_args['privacy_policies'])
517
-                ? (array) $setup_args['privacy_policies']
518
-                : '',
519
-        );
520
-        // if plugin_action_slug is NOT set, but an admin page path IS set,
521
-        // then let's just use the plugin_slug since that will be used for linking to the admin page
522
-        $addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug'])
523
-                                                && ! empty($addon_settings['admin_path'])
524
-            ? $addon_settings['plugin_slug']
525
-            : $addon_settings['plugin_action_slug'];
526
-        // full server path to main file (file loaded directly by WP)
527
-        $addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']);
528
-        return $addon_settings;
529
-    }
379
+	/**
380
+	 * @param string $class_name
381
+	 * @param array  $setup_args
382
+	 * @return array
383
+	 */
384
+	private static function _get_addon_settings($class_name, array $setup_args)
385
+	{
386
+		// setup $_settings array from incoming values.
387
+		$addon_settings = array(
388
+			// generated from the addon name, changes something like "calendar" to "EE_Calendar"
389
+			'class_name'            => $class_name,
390
+			// the addon slug for use in URLs, etc
391
+			'plugin_slug'           => isset($setup_args['plugin_slug'])
392
+				? (string) $setup_args['plugin_slug']
393
+				: '',
394
+			// page slug to be used when generating the "Settings" link on the WP plugin page
395
+			'plugin_action_slug'    => isset($setup_args['plugin_action_slug'])
396
+				? (string) $setup_args['plugin_action_slug']
397
+				: '',
398
+			// the "software" version for the addon
399
+			'version'               => isset($setup_args['version'])
400
+				? (string) $setup_args['version']
401
+				: '',
402
+			// the minimum version of EE Core that the addon will work with
403
+			'min_core_version'      => isset($setup_args['min_core_version'])
404
+				? (string) $setup_args['min_core_version']
405
+				: '',
406
+			// the minimum version of WordPress that the addon will work with
407
+			'min_wp_version'        => isset($setup_args['min_wp_version'])
408
+				? (string) $setup_args['min_wp_version']
409
+				: EE_MIN_WP_VER_REQUIRED,
410
+			// full server path to main file (file loaded directly by WP)
411
+			'main_file_path'        => isset($setup_args['main_file_path'])
412
+				? (string) $setup_args['main_file_path']
413
+				: '',
414
+			// instance of \EventEspresso\core\domain\DomainInterface
415
+			'domain'                => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface
416
+				? $setup_args['domain']
417
+				: null,
418
+			// Fully Qualified Class Name for the addon's Domain class
419
+			'domain_fqcn'           => isset($setup_args['domain_fqcn'])
420
+				? (string) $setup_args['domain_fqcn']
421
+				: '',
422
+			// path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages
423
+			'admin_path'            => isset($setup_args['admin_path'])
424
+				? (string) $setup_args['admin_path'] : '',
425
+			// a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page
426
+			'admin_callback'        => isset($setup_args['admin_callback'])
427
+				? (string) $setup_args['admin_callback']
428
+				: '',
429
+			// the section name for this addon's configuration settings section (defaults to "addons")
430
+			'config_section'        => isset($setup_args['config_section'])
431
+				? (string) $setup_args['config_section']
432
+				: 'addons',
433
+			// the class name for this addon's configuration settings object
434
+			'config_class'          => isset($setup_args['config_class'])
435
+				? (string) $setup_args['config_class'] : '',
436
+			// the name given to the config for this addons' configuration settings object (optional)
437
+			'config_name'           => isset($setup_args['config_name'])
438
+				? (string) $setup_args['config_name'] : '',
439
+			// an array of "class names" => "full server paths" for any classes that might be invoked by the addon
440
+			'autoloader_paths'      => isset($setup_args['autoloader_paths'])
441
+				? (array) $setup_args['autoloader_paths']
442
+				: array(),
443
+			// an array of  "full server paths" for any folders containing classes that might be invoked by the addon
444
+			'autoloader_folders'    => isset($setup_args['autoloader_folders'])
445
+				? (array) $setup_args['autoloader_folders']
446
+				: array(),
447
+			// array of full server paths to any EE_DMS data migration scripts used by the addon.
448
+			// The key should be the EE_Addon class name that this set of data migration scripts belongs to.
449
+			// If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name
450
+			'dms_paths'             => isset($setup_args['dms_paths'])
451
+				? (array) $setup_args['dms_paths']
452
+				: array(),
453
+			// array of full server paths to any EED_Modules used by the addon
454
+			'module_paths'          => isset($setup_args['module_paths'])
455
+				? (array) $setup_args['module_paths']
456
+				: array(),
457
+			// array of full server paths to any EES_Shortcodes used by the addon
458
+			'shortcode_paths'       => isset($setup_args['shortcode_paths'])
459
+				? (array) $setup_args['shortcode_paths']
460
+				: array(),
461
+			'shortcode_fqcns'       => isset($setup_args['shortcode_fqcns'])
462
+				? (array) $setup_args['shortcode_fqcns']
463
+				: array(),
464
+			// array of full server paths to any WP_Widgets used by the addon
465
+			'widget_paths'          => isset($setup_args['widget_paths'])
466
+				? (array) $setup_args['widget_paths']
467
+				: array(),
468
+			// array of PUE options used by the addon
469
+			'pue_options'           => isset($setup_args['pue_options'])
470
+				? (array) $setup_args['pue_options']
471
+				: array(),
472
+			'message_types'         => isset($setup_args['message_types'])
473
+				? (array) $setup_args['message_types']
474
+				: array(),
475
+			'capabilities'          => isset($setup_args['capabilities'])
476
+				? (array) $setup_args['capabilities']
477
+				: array(),
478
+			'capability_maps'       => isset($setup_args['capability_maps'])
479
+				? (array) $setup_args['capability_maps']
480
+				: array(),
481
+			'model_paths'           => isset($setup_args['model_paths'])
482
+				? (array) $setup_args['model_paths']
483
+				: array(),
484
+			'class_paths'           => isset($setup_args['class_paths'])
485
+				? (array) $setup_args['class_paths']
486
+				: array(),
487
+			'model_extension_paths' => isset($setup_args['model_extension_paths'])
488
+				? (array) $setup_args['model_extension_paths']
489
+				: array(),
490
+			'class_extension_paths' => isset($setup_args['class_extension_paths'])
491
+				? (array) $setup_args['class_extension_paths']
492
+				: array(),
493
+			'custom_post_types'     => isset($setup_args['custom_post_types'])
494
+				? (array) $setup_args['custom_post_types']
495
+				: array(),
496
+			'custom_taxonomies'     => isset($setup_args['custom_taxonomies'])
497
+				? (array) $setup_args['custom_taxonomies']
498
+				: array(),
499
+			'payment_method_paths'  => isset($setup_args['payment_method_paths'])
500
+				? (array) $setup_args['payment_method_paths']
501
+				: array(),
502
+			'default_terms'         => isset($setup_args['default_terms'])
503
+				? (array) $setup_args['default_terms']
504
+				: array(),
505
+			// if not empty, inserts a new table row after this plugin's row on the WP Plugins page
506
+			// that can be used for adding upgrading/marketing info
507
+			'plugins_page_row'      => isset($setup_args['plugins_page_row'])
508
+				? $setup_args['plugins_page_row']
509
+				: '',
510
+			'namespace'             => isset(
511
+				$setup_args['namespace']['FQNS'],
512
+				$setup_args['namespace']['DIR']
513
+			)
514
+				? (array) $setup_args['namespace']
515
+				: array(),
516
+			'privacy_policies'      => isset($setup_args['privacy_policies'])
517
+				? (array) $setup_args['privacy_policies']
518
+				: '',
519
+		);
520
+		// if plugin_action_slug is NOT set, but an admin page path IS set,
521
+		// then let's just use the plugin_slug since that will be used for linking to the admin page
522
+		$addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug'])
523
+												&& ! empty($addon_settings['admin_path'])
524
+			? $addon_settings['plugin_slug']
525
+			: $addon_settings['plugin_action_slug'];
526
+		// full server path to main file (file loaded directly by WP)
527
+		$addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']);
528
+		return $addon_settings;
529
+	}
530 530
 
531 531
 
532
-    /**
533
-     * @param string $addon_name
534
-     * @param array  $addon_settings
535
-     * @return boolean
536
-     */
537
-    private static function _addon_is_compatible($addon_name, array $addon_settings)
538
-    {
539
-        global $wp_version;
540
-        $incompatibility_message = '';
541
-        // check whether this addon version is compatible with EE core
542
-        if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
543
-            && ! self::_meets_min_core_version_requirement(
544
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
545
-                $addon_settings['version']
546
-            )
547
-        ) {
548
-            $incompatibility_message = sprintf(
549
-                __(
550
-                    '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.',
551
-                    'event_espresso'
552
-                ),
553
-                $addon_name,
554
-                '<br />',
555
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
556
-                '<span style="font-weight: bold; color: #D54E21;">',
557
-                '</span><br />'
558
-            );
559
-        } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
560
-        ) {
561
-            $incompatibility_message = sprintf(
562
-                __(
563
-                    '%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".',
564
-                    'event_espresso'
565
-                ),
566
-                $addon_name,
567
-                self::_effective_version($addon_settings['min_core_version']),
568
-                self::_effective_version(espresso_version()),
569
-                '<br />',
570
-                '<span style="font-weight: bold; color: #D54E21;">',
571
-                '</span><br />'
572
-            );
573
-        } elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) {
574
-            $incompatibility_message = sprintf(
575
-                __(
576
-                    '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.',
577
-                    'event_espresso'
578
-                ),
579
-                $addon_name,
580
-                $addon_settings['min_wp_version'],
581
-                '<br />',
582
-                '<span style="font-weight: bold; color: #D54E21;">',
583
-                '</span><br />'
584
-            );
585
-        }
586
-        if (! empty($incompatibility_message)) {
587
-            // remove 'activate' from the REQUEST
588
-            // so WP doesn't erroneously tell the user the plugin activated fine when it didn't
589
-            unset($_GET['activate'], $_REQUEST['activate']);
590
-            if (current_user_can('activate_plugins')) {
591
-                // show an error message indicating the plugin didn't activate properly
592
-                EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__);
593
-            }
594
-            // BAIL FROM THE ADDON REGISTRATION PROCESS
595
-            return false;
596
-        }
597
-        // addon IS compatible
598
-        return true;
599
-    }
532
+	/**
533
+	 * @param string $addon_name
534
+	 * @param array  $addon_settings
535
+	 * @return boolean
536
+	 */
537
+	private static function _addon_is_compatible($addon_name, array $addon_settings)
538
+	{
539
+		global $wp_version;
540
+		$incompatibility_message = '';
541
+		// check whether this addon version is compatible with EE core
542
+		if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
543
+			&& ! self::_meets_min_core_version_requirement(
544
+				EE_Register_Addon::$_incompatible_addons[ $addon_name ],
545
+				$addon_settings['version']
546
+			)
547
+		) {
548
+			$incompatibility_message = sprintf(
549
+				__(
550
+					'%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.',
551
+					'event_espresso'
552
+				),
553
+				$addon_name,
554
+				'<br />',
555
+				EE_Register_Addon::$_incompatible_addons[ $addon_name ],
556
+				'<span style="font-weight: bold; color: #D54E21;">',
557
+				'</span><br />'
558
+			);
559
+		} elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
560
+		) {
561
+			$incompatibility_message = sprintf(
562
+				__(
563
+					'%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".',
564
+					'event_espresso'
565
+				),
566
+				$addon_name,
567
+				self::_effective_version($addon_settings['min_core_version']),
568
+				self::_effective_version(espresso_version()),
569
+				'<br />',
570
+				'<span style="font-weight: bold; color: #D54E21;">',
571
+				'</span><br />'
572
+			);
573
+		} elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) {
574
+			$incompatibility_message = sprintf(
575
+				__(
576
+					'%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.',
577
+					'event_espresso'
578
+				),
579
+				$addon_name,
580
+				$addon_settings['min_wp_version'],
581
+				'<br />',
582
+				'<span style="font-weight: bold; color: #D54E21;">',
583
+				'</span><br />'
584
+			);
585
+		}
586
+		if (! empty($incompatibility_message)) {
587
+			// remove 'activate' from the REQUEST
588
+			// so WP doesn't erroneously tell the user the plugin activated fine when it didn't
589
+			unset($_GET['activate'], $_REQUEST['activate']);
590
+			if (current_user_can('activate_plugins')) {
591
+				// show an error message indicating the plugin didn't activate properly
592
+				EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__);
593
+			}
594
+			// BAIL FROM THE ADDON REGISTRATION PROCESS
595
+			return false;
596
+		}
597
+		// addon IS compatible
598
+		return true;
599
+	}
600 600
 
601 601
 
602
-    /**
603
-     * if plugin update engine is being used for auto-updates,
604
-     * then let's set that up now before going any further so that ALL addons can be updated
605
-     * (not needed if PUE is not being used)
606
-     *
607
-     * @param string $addon_name
608
-     * @param string $class_name
609
-     * @param array  $setup_args
610
-     * @return void
611
-     */
612
-    private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
613
-    {
614
-        if (! empty($setup_args['pue_options'])) {
615
-            self::$_settings[ $addon_name ]['pue_options'] = array(
616
-                'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
617
-                    ? (string) $setup_args['pue_options']['pue_plugin_slug']
618
-                    : 'espresso_' . strtolower($class_name),
619
-                'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
620
-                    ? (string) $setup_args['pue_options']['plugin_basename']
621
-                    : plugin_basename($setup_args['main_file_path']),
622
-                'checkPeriod'     => isset($setup_args['pue_options']['checkPeriod'])
623
-                    ? (string) $setup_args['pue_options']['checkPeriod']
624
-                    : '24',
625
-                'use_wp_update'   => isset($setup_args['pue_options']['use_wp_update'])
626
-                    ? (string) $setup_args['pue_options']['use_wp_update']
627
-                    : false,
628
-            );
629
-            add_action(
630
-                'AHEE__EE_System__brew_espresso__after_pue_init',
631
-                array('EE_Register_Addon', 'load_pue_update')
632
-            );
633
-        }
634
-    }
602
+	/**
603
+	 * if plugin update engine is being used for auto-updates,
604
+	 * then let's set that up now before going any further so that ALL addons can be updated
605
+	 * (not needed if PUE is not being used)
606
+	 *
607
+	 * @param string $addon_name
608
+	 * @param string $class_name
609
+	 * @param array  $setup_args
610
+	 * @return void
611
+	 */
612
+	private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
613
+	{
614
+		if (! empty($setup_args['pue_options'])) {
615
+			self::$_settings[ $addon_name ]['pue_options'] = array(
616
+				'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
617
+					? (string) $setup_args['pue_options']['pue_plugin_slug']
618
+					: 'espresso_' . strtolower($class_name),
619
+				'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
620
+					? (string) $setup_args['pue_options']['plugin_basename']
621
+					: plugin_basename($setup_args['main_file_path']),
622
+				'checkPeriod'     => isset($setup_args['pue_options']['checkPeriod'])
623
+					? (string) $setup_args['pue_options']['checkPeriod']
624
+					: '24',
625
+				'use_wp_update'   => isset($setup_args['pue_options']['use_wp_update'])
626
+					? (string) $setup_args['pue_options']['use_wp_update']
627
+					: false,
628
+			);
629
+			add_action(
630
+				'AHEE__EE_System__brew_espresso__after_pue_init',
631
+				array('EE_Register_Addon', 'load_pue_update')
632
+			);
633
+		}
634
+	}
635 635
 
636 636
 
637
-    /**
638
-     * register namespaces right away before any other files or classes get loaded, but AFTER the version checks
639
-     *
640
-     * @param array $addon_settings
641
-     * @return void
642
-     */
643
-    private static function _setup_namespaces(array $addon_settings)
644
-    {
645
-        //
646
-        if (isset(
647
-            $addon_settings['namespace']['FQNS'],
648
-            $addon_settings['namespace']['DIR']
649
-        )) {
650
-            EE_Psr4AutoloaderInit::psr4_loader()->addNamespace(
651
-                $addon_settings['namespace']['FQNS'],
652
-                $addon_settings['namespace']['DIR']
653
-            );
654
-        }
655
-    }
637
+	/**
638
+	 * register namespaces right away before any other files or classes get loaded, but AFTER the version checks
639
+	 *
640
+	 * @param array $addon_settings
641
+	 * @return void
642
+	 */
643
+	private static function _setup_namespaces(array $addon_settings)
644
+	{
645
+		//
646
+		if (isset(
647
+			$addon_settings['namespace']['FQNS'],
648
+			$addon_settings['namespace']['DIR']
649
+		)) {
650
+			EE_Psr4AutoloaderInit::psr4_loader()->addNamespace(
651
+				$addon_settings['namespace']['FQNS'],
652
+				$addon_settings['namespace']['DIR']
653
+			);
654
+		}
655
+	}
656 656
 
657 657
 
658
-    /**
659
-     * @param string $addon_name
660
-     * @param array  $addon_settings
661
-     * @return bool
662
-     * @throws EE_Error
663
-     * @throws InvalidArgumentException
664
-     * @throws ReflectionException
665
-     * @throws InvalidDataTypeException
666
-     * @throws InvalidInterfaceException
667
-     */
668
-    private static function _addon_activation($addon_name, array $addon_settings)
669
-    {
670
-        // this is an activation request
671
-        if (did_action('activate_plugin')) {
672
-            // to find if THIS is the addon that was activated, just check if we have already registered it or not
673
-            // (as the newly-activated addon wasn't around the first time addons were registered).
674
-            // Note: the presence of pue_options in the addon registration options will initialize the $_settings
675
-            // property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
676
-            if (! isset(self::$_settings[ $addon_name ])
677
-                || (isset(self::$_settings[ $addon_name ])
678
-                    && ! isset(self::$_settings[ $addon_name ]['class_name'])
679
-                )
680
-            ) {
681
-                self::$_settings[ $addon_name ] = $addon_settings;
682
-                $addon = self::_load_and_init_addon_class($addon_name);
683
-                $addon->set_activation_indicator_option();
684
-                // dont bother setting up the rest of the addon.
685
-                // we know it was just activated and the request will end soon
686
-            }
687
-            return true;
688
-        }
689
-        // make sure this was called in the right place!
690
-        if (! did_action('AHEE__EE_System__load_espresso_addons')
691
-            || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
692
-        ) {
693
-            EE_Error::doing_it_wrong(
694
-                __METHOD__,
695
-                sprintf(
696
-                    __(
697
-                        'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.',
698
-                        'event_espresso'
699
-                    ),
700
-                    $addon_name
701
-                ),
702
-                '4.3.0'
703
-            );
704
-        }
705
-        // make sure addon settings are set correctly without overwriting anything existing
706
-        if (isset(self::$_settings[ $addon_name ])) {
707
-            self::$_settings[ $addon_name ] += $addon_settings;
708
-        } else {
709
-            self::$_settings[ $addon_name ] = $addon_settings;
710
-        }
711
-        return false;
712
-    }
658
+	/**
659
+	 * @param string $addon_name
660
+	 * @param array  $addon_settings
661
+	 * @return bool
662
+	 * @throws EE_Error
663
+	 * @throws InvalidArgumentException
664
+	 * @throws ReflectionException
665
+	 * @throws InvalidDataTypeException
666
+	 * @throws InvalidInterfaceException
667
+	 */
668
+	private static function _addon_activation($addon_name, array $addon_settings)
669
+	{
670
+		// this is an activation request
671
+		if (did_action('activate_plugin')) {
672
+			// to find if THIS is the addon that was activated, just check if we have already registered it or not
673
+			// (as the newly-activated addon wasn't around the first time addons were registered).
674
+			// Note: the presence of pue_options in the addon registration options will initialize the $_settings
675
+			// property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
676
+			if (! isset(self::$_settings[ $addon_name ])
677
+				|| (isset(self::$_settings[ $addon_name ])
678
+					&& ! isset(self::$_settings[ $addon_name ]['class_name'])
679
+				)
680
+			) {
681
+				self::$_settings[ $addon_name ] = $addon_settings;
682
+				$addon = self::_load_and_init_addon_class($addon_name);
683
+				$addon->set_activation_indicator_option();
684
+				// dont bother setting up the rest of the addon.
685
+				// we know it was just activated and the request will end soon
686
+			}
687
+			return true;
688
+		}
689
+		// make sure this was called in the right place!
690
+		if (! did_action('AHEE__EE_System__load_espresso_addons')
691
+			|| did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
692
+		) {
693
+			EE_Error::doing_it_wrong(
694
+				__METHOD__,
695
+				sprintf(
696
+					__(
697
+						'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.',
698
+						'event_espresso'
699
+					),
700
+					$addon_name
701
+				),
702
+				'4.3.0'
703
+			);
704
+		}
705
+		// make sure addon settings are set correctly without overwriting anything existing
706
+		if (isset(self::$_settings[ $addon_name ])) {
707
+			self::$_settings[ $addon_name ] += $addon_settings;
708
+		} else {
709
+			self::$_settings[ $addon_name ] = $addon_settings;
710
+		}
711
+		return false;
712
+	}
713 713
 
714 714
 
715
-    /**
716
-     * @param string $addon_name
717
-     * @return void
718
-     * @throws EE_Error
719
-     */
720
-    private static function _setup_autoloaders($addon_name)
721
-    {
722
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
723
-            // setup autoloader for single file
724
-            EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
725
-        }
726
-        // setup autoloaders for folders
727
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
728
-            foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
729
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
730
-            }
731
-        }
732
-    }
715
+	/**
716
+	 * @param string $addon_name
717
+	 * @return void
718
+	 * @throws EE_Error
719
+	 */
720
+	private static function _setup_autoloaders($addon_name)
721
+	{
722
+		if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
723
+			// setup autoloader for single file
724
+			EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
725
+		}
726
+		// setup autoloaders for folders
727
+		if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
728
+			foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
729
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
730
+			}
731
+		}
732
+	}
733 733
 
734 734
 
735
-    /**
736
-     * register new models and extensions
737
-     *
738
-     * @param string $addon_name
739
-     * @return void
740
-     * @throws EE_Error
741
-     */
742
-    private static function _register_models_and_extensions($addon_name)
743
-    {
744
-        // register new models
745
-        if (! empty(self::$_settings[ $addon_name ]['model_paths'])
746
-            || ! empty(self::$_settings[ $addon_name ]['class_paths'])
747
-        ) {
748
-            EE_Register_Model::register(
749
-                $addon_name,
750
-                array(
751
-                    'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
752
-                    'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
753
-                )
754
-            );
755
-        }
756
-        // register model extensions
757
-        if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
758
-            || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
759
-        ) {
760
-            EE_Register_Model_Extensions::register(
761
-                $addon_name,
762
-                array(
763
-                    'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
764
-                    'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
765
-                )
766
-            );
767
-        }
768
-    }
735
+	/**
736
+	 * register new models and extensions
737
+	 *
738
+	 * @param string $addon_name
739
+	 * @return void
740
+	 * @throws EE_Error
741
+	 */
742
+	private static function _register_models_and_extensions($addon_name)
743
+	{
744
+		// register new models
745
+		if (! empty(self::$_settings[ $addon_name ]['model_paths'])
746
+			|| ! empty(self::$_settings[ $addon_name ]['class_paths'])
747
+		) {
748
+			EE_Register_Model::register(
749
+				$addon_name,
750
+				array(
751
+					'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
752
+					'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
753
+				)
754
+			);
755
+		}
756
+		// register model extensions
757
+		if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
758
+			|| ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
759
+		) {
760
+			EE_Register_Model_Extensions::register(
761
+				$addon_name,
762
+				array(
763
+					'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
764
+					'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
765
+				)
766
+			);
767
+		}
768
+	}
769 769
 
770 770
 
771
-    /**
772
-     * @param string $addon_name
773
-     * @return void
774
-     * @throws EE_Error
775
-     */
776
-    private static function _register_data_migration_scripts($addon_name)
777
-    {
778
-        // setup DMS
779
-        if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
780
-            EE_Register_Data_Migration_Scripts::register(
781
-                $addon_name,
782
-                array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
783
-            );
784
-        }
785
-    }
771
+	/**
772
+	 * @param string $addon_name
773
+	 * @return void
774
+	 * @throws EE_Error
775
+	 */
776
+	private static function _register_data_migration_scripts($addon_name)
777
+	{
778
+		// setup DMS
779
+		if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
780
+			EE_Register_Data_Migration_Scripts::register(
781
+				$addon_name,
782
+				array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
783
+			);
784
+		}
785
+	}
786 786
 
787 787
 
788
-    /**
789
-     * @param string $addon_name
790
-     * @return void
791
-     * @throws EE_Error
792
-     */
793
-    private static function _register_config($addon_name)
794
-    {
795
-        // if config_class is present let's register config.
796
-        if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
797
-            EE_Register_Config::register(
798
-                self::$_settings[ $addon_name ]['config_class'],
799
-                array(
800
-                    'config_section' => self::$_settings[ $addon_name ]['config_section'],
801
-                    'config_name'    => self::$_settings[ $addon_name ]['config_name'],
802
-                )
803
-            );
804
-        }
805
-    }
788
+	/**
789
+	 * @param string $addon_name
790
+	 * @return void
791
+	 * @throws EE_Error
792
+	 */
793
+	private static function _register_config($addon_name)
794
+	{
795
+		// if config_class is present let's register config.
796
+		if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
797
+			EE_Register_Config::register(
798
+				self::$_settings[ $addon_name ]['config_class'],
799
+				array(
800
+					'config_section' => self::$_settings[ $addon_name ]['config_section'],
801
+					'config_name'    => self::$_settings[ $addon_name ]['config_name'],
802
+				)
803
+			);
804
+		}
805
+	}
806 806
 
807 807
 
808
-    /**
809
-     * @param string $addon_name
810
-     * @return void
811
-     * @throws EE_Error
812
-     */
813
-    private static function _register_admin_pages($addon_name)
814
-    {
815
-        if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
816
-            EE_Register_Admin_Page::register(
817
-                $addon_name,
818
-                array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
819
-            );
820
-        }
821
-    }
808
+	/**
809
+	 * @param string $addon_name
810
+	 * @return void
811
+	 * @throws EE_Error
812
+	 */
813
+	private static function _register_admin_pages($addon_name)
814
+	{
815
+		if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
816
+			EE_Register_Admin_Page::register(
817
+				$addon_name,
818
+				array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
819
+			);
820
+		}
821
+	}
822 822
 
823 823
 
824
-    /**
825
-     * @param string $addon_name
826
-     * @return void
827
-     * @throws EE_Error
828
-     */
829
-    private static function _register_modules($addon_name)
830
-    {
831
-        if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
832
-            EE_Register_Module::register(
833
-                $addon_name,
834
-                array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
835
-            );
836
-        }
837
-    }
824
+	/**
825
+	 * @param string $addon_name
826
+	 * @return void
827
+	 * @throws EE_Error
828
+	 */
829
+	private static function _register_modules($addon_name)
830
+	{
831
+		if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
832
+			EE_Register_Module::register(
833
+				$addon_name,
834
+				array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
835
+			);
836
+		}
837
+	}
838 838
 
839 839
 
840
-    /**
841
-     * @param string $addon_name
842
-     * @return void
843
-     * @throws EE_Error
844
-     */
845
-    private static function _register_shortcodes($addon_name)
846
-    {
847
-        if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
848
-            || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
849
-        ) {
850
-            EE_Register_Shortcode::register(
851
-                $addon_name,
852
-                array(
853
-                    'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
854
-                        ? self::$_settings[ $addon_name ]['shortcode_paths']
855
-                        : array(),
856
-                    'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
857
-                        ? self::$_settings[ $addon_name ]['shortcode_fqcns']
858
-                        : array(),
859
-                )
860
-            );
861
-        }
862
-    }
840
+	/**
841
+	 * @param string $addon_name
842
+	 * @return void
843
+	 * @throws EE_Error
844
+	 */
845
+	private static function _register_shortcodes($addon_name)
846
+	{
847
+		if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
848
+			|| ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
849
+		) {
850
+			EE_Register_Shortcode::register(
851
+				$addon_name,
852
+				array(
853
+					'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
854
+						? self::$_settings[ $addon_name ]['shortcode_paths']
855
+						: array(),
856
+					'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
857
+						? self::$_settings[ $addon_name ]['shortcode_fqcns']
858
+						: array(),
859
+				)
860
+			);
861
+		}
862
+	}
863 863
 
864 864
 
865
-    /**
866
-     * @param string $addon_name
867
-     * @return void
868
-     * @throws EE_Error
869
-     */
870
-    private static function _register_widgets($addon_name)
871
-    {
872
-        if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
873
-            EE_Register_Widget::register(
874
-                $addon_name,
875
-                array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
876
-            );
877
-        }
878
-    }
865
+	/**
866
+	 * @param string $addon_name
867
+	 * @return void
868
+	 * @throws EE_Error
869
+	 */
870
+	private static function _register_widgets($addon_name)
871
+	{
872
+		if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
873
+			EE_Register_Widget::register(
874
+				$addon_name,
875
+				array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
876
+			);
877
+		}
878
+	}
879 879
 
880 880
 
881
-    /**
882
-     * @param string $addon_name
883
-     * @return void
884
-     * @throws EE_Error
885
-     */
886
-    private static function _register_capabilities($addon_name)
887
-    {
888
-        if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
889
-            EE_Register_Capabilities::register(
890
-                $addon_name,
891
-                array(
892
-                    'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
893
-                    'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
894
-                )
895
-            );
896
-        }
897
-    }
881
+	/**
882
+	 * @param string $addon_name
883
+	 * @return void
884
+	 * @throws EE_Error
885
+	 */
886
+	private static function _register_capabilities($addon_name)
887
+	{
888
+		if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
889
+			EE_Register_Capabilities::register(
890
+				$addon_name,
891
+				array(
892
+					'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
893
+					'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
894
+				)
895
+			);
896
+		}
897
+	}
898 898
 
899 899
 
900
-    /**
901
-     * @param string $addon_name
902
-     * @return void
903
-     * @throws EE_Error
904
-     */
905
-    private static function _register_message_types($addon_name)
906
-    {
907
-        if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
908
-            add_action(
909
-                'EE_Brewing_Regular___messages_caf',
910
-                array('EE_Register_Addon', 'register_message_types')
911
-            );
912
-        }
913
-    }
900
+	/**
901
+	 * @param string $addon_name
902
+	 * @return void
903
+	 * @throws EE_Error
904
+	 */
905
+	private static function _register_message_types($addon_name)
906
+	{
907
+		if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
908
+			add_action(
909
+				'EE_Brewing_Regular___messages_caf',
910
+				array('EE_Register_Addon', 'register_message_types')
911
+			);
912
+		}
913
+	}
914 914
 
915 915
 
916
-    /**
917
-     * @param string $addon_name
918
-     * @return void
919
-     * @throws EE_Error
920
-     */
921
-    private static function _register_custom_post_types($addon_name)
922
-    {
923
-        if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
924
-            || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
925
-        ) {
926
-            EE_Register_CPT::register(
927
-                $addon_name,
928
-                array(
929
-                    'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
930
-                    'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
931
-                    'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
932
-                )
933
-            );
934
-        }
935
-    }
916
+	/**
917
+	 * @param string $addon_name
918
+	 * @return void
919
+	 * @throws EE_Error
920
+	 */
921
+	private static function _register_custom_post_types($addon_name)
922
+	{
923
+		if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
924
+			|| ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
925
+		) {
926
+			EE_Register_CPT::register(
927
+				$addon_name,
928
+				array(
929
+					'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
930
+					'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
931
+					'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
932
+				)
933
+			);
934
+		}
935
+	}
936 936
 
937 937
 
938
-    /**
939
-     * @param string $addon_name
940
-     * @return void
941
-     * @throws InvalidArgumentException
942
-     * @throws InvalidInterfaceException
943
-     * @throws InvalidDataTypeException
944
-     * @throws DomainException
945
-     * @throws EE_Error
946
-     */
947
-    private static function _register_payment_methods($addon_name)
948
-    {
949
-        if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
950
-            EE_Register_Payment_Method::register(
951
-                $addon_name,
952
-                array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
953
-            );
954
-        }
955
-    }
938
+	/**
939
+	 * @param string $addon_name
940
+	 * @return void
941
+	 * @throws InvalidArgumentException
942
+	 * @throws InvalidInterfaceException
943
+	 * @throws InvalidDataTypeException
944
+	 * @throws DomainException
945
+	 * @throws EE_Error
946
+	 */
947
+	private static function _register_payment_methods($addon_name)
948
+	{
949
+		if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
950
+			EE_Register_Payment_Method::register(
951
+				$addon_name,
952
+				array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
953
+			);
954
+		}
955
+	}
956 956
 
957 957
 
958
-    /**
959
-     * @param string $addon_name
960
-     * @return void
961
-     * @throws InvalidArgumentException
962
-     * @throws InvalidInterfaceException
963
-     * @throws InvalidDataTypeException
964
-     * @throws DomainException
965
-     * @throws EE_Error
966
-     */
967
-    private static function registerPrivacyPolicies($addon_name)
968
-    {
969
-        if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
970
-            EE_Register_Privacy_Policy::register(
971
-                $addon_name,
972
-                self::$_settings[ $addon_name ]['privacy_policies']
973
-            );
974
-        }
975
-    }
958
+	/**
959
+	 * @param string $addon_name
960
+	 * @return void
961
+	 * @throws InvalidArgumentException
962
+	 * @throws InvalidInterfaceException
963
+	 * @throws InvalidDataTypeException
964
+	 * @throws DomainException
965
+	 * @throws EE_Error
966
+	 */
967
+	private static function registerPrivacyPolicies($addon_name)
968
+	{
969
+		if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
970
+			EE_Register_Privacy_Policy::register(
971
+				$addon_name,
972
+				self::$_settings[ $addon_name ]['privacy_policies']
973
+			);
974
+		}
975
+	}
976 976
 
977 977
 
978
-    /**
979
-     * @param string $addon_name
980
-     * @return void
981
-     */
982
-    private static function registerPersonalDataExporters($addon_name)
983
-    {
984
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
985
-            EE_Register_Personal_Data_Eraser::register(
986
-                $addon_name,
987
-                self::$_settings[ $addon_name ]['personal_data_exporters']
988
-            );
989
-        }
990
-    }
978
+	/**
979
+	 * @param string $addon_name
980
+	 * @return void
981
+	 */
982
+	private static function registerPersonalDataExporters($addon_name)
983
+	{
984
+		if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
985
+			EE_Register_Personal_Data_Eraser::register(
986
+				$addon_name,
987
+				self::$_settings[ $addon_name ]['personal_data_exporters']
988
+			);
989
+		}
990
+	}
991 991
 
992 992
 
993
-    /**
994
-     * @param string $addon_name
995
-     * @return void
996
-     */
997
-    private static function registerPersonalDataErasers($addon_name)
998
-    {
999
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
1000
-            EE_Register_Personal_Data_Eraser::register(
1001
-                $addon_name,
1002
-                self::$_settings[ $addon_name ]['personal_data_erasers']
1003
-            );
1004
-        }
1005
-    }
993
+	/**
994
+	 * @param string $addon_name
995
+	 * @return void
996
+	 */
997
+	private static function registerPersonalDataErasers($addon_name)
998
+	{
999
+		if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
1000
+			EE_Register_Personal_Data_Eraser::register(
1001
+				$addon_name,
1002
+				self::$_settings[ $addon_name ]['personal_data_erasers']
1003
+			);
1004
+		}
1005
+	}
1006 1006
 
1007 1007
 
1008
-    /**
1009
-     * Loads and instantiates the EE_Addon class and adds it onto the registry
1010
-     *
1011
-     * @param string $addon_name
1012
-     * @return EE_Addon
1013
-     * @throws InvalidArgumentException
1014
-     * @throws InvalidInterfaceException
1015
-     * @throws InvalidDataTypeException
1016
-     * @throws ReflectionException
1017
-     * @throws EE_Error
1018
-     */
1019
-    private static function _load_and_init_addon_class($addon_name)
1020
-    {
1021
-        $loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader();
1022
-        $addon = $loader->getShared(
1023
-            self::$_settings[ $addon_name ]['class_name'],
1024
-            array('EE_Registry::create(addon)' => true)
1025
-        );
1026
-        // setter inject dep map if required
1027
-        if ($addon instanceof RequiresDependencyMapInterface && $addon->dependencyMap() === null) {
1028
-            $addon->setDependencyMap($loader->getShared('EE_Dependency_Map'));
1029
-        }
1030
-        // setter inject domain if required
1031
-        if ($addon instanceof RequiresDomainInterface
1032
-            && $addon->domain() === null
1033
-        ) {
1034
-            // using supplied Domain object
1035
-            $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1036
-                ? self::$_settings[ $addon_name ]['domain']
1037
-                : null;
1038
-            // or construct one using Domain FQCN
1039
-            if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1040
-                $domain = $loader->getShared(
1041
-                    self::$_settings[ $addon_name ]['domain_fqcn'],
1042
-                    array(
1043
-                        new EventEspresso\core\domain\values\FilePath(
1044
-                            self::$_settings[ $addon_name ]['main_file_path']
1045
-                        ),
1046
-                        EventEspresso\core\domain\values\Version::fromString(
1047
-                            self::$_settings[ $addon_name ]['version']
1048
-                        ),
1049
-                    )
1050
-                );
1051
-            }
1052
-            if ($domain instanceof DomainInterface) {
1053
-                $addon->setDomain($domain);
1054
-            }
1055
-        }
1056
-        $addon->set_name($addon_name);
1057
-        $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1058
-        $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1059
-        $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1060
-        $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1061
-        $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1062
-        $addon->set_version(self::$_settings[ $addon_name ]['version']);
1063
-        $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1064
-        $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1065
-        $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1066
-        $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1067
-        // setup the add-on's pue_slug if we have one.
1068
-        if (! empty(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug'])) {
1069
-            $addon->setPueSlug(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug']);
1070
-        }
1071
-        // unfortunately this can't be hooked in upon construction, because we don't have
1072
-        // the plugin mainfile's path upon construction.
1073
-        register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1074
-        // call any additional admin_callback functions during load_admin_controller hook
1075
-        if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1076
-            add_action(
1077
-                'AHEE__EE_System__load_controllers__load_admin_controllers',
1078
-                array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1079
-            );
1080
-        }
1081
-        return $addon;
1082
-    }
1008
+	/**
1009
+	 * Loads and instantiates the EE_Addon class and adds it onto the registry
1010
+	 *
1011
+	 * @param string $addon_name
1012
+	 * @return EE_Addon
1013
+	 * @throws InvalidArgumentException
1014
+	 * @throws InvalidInterfaceException
1015
+	 * @throws InvalidDataTypeException
1016
+	 * @throws ReflectionException
1017
+	 * @throws EE_Error
1018
+	 */
1019
+	private static function _load_and_init_addon_class($addon_name)
1020
+	{
1021
+		$loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader();
1022
+		$addon = $loader->getShared(
1023
+			self::$_settings[ $addon_name ]['class_name'],
1024
+			array('EE_Registry::create(addon)' => true)
1025
+		);
1026
+		// setter inject dep map if required
1027
+		if ($addon instanceof RequiresDependencyMapInterface && $addon->dependencyMap() === null) {
1028
+			$addon->setDependencyMap($loader->getShared('EE_Dependency_Map'));
1029
+		}
1030
+		// setter inject domain if required
1031
+		if ($addon instanceof RequiresDomainInterface
1032
+			&& $addon->domain() === null
1033
+		) {
1034
+			// using supplied Domain object
1035
+			$domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1036
+				? self::$_settings[ $addon_name ]['domain']
1037
+				: null;
1038
+			// or construct one using Domain FQCN
1039
+			if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1040
+				$domain = $loader->getShared(
1041
+					self::$_settings[ $addon_name ]['domain_fqcn'],
1042
+					array(
1043
+						new EventEspresso\core\domain\values\FilePath(
1044
+							self::$_settings[ $addon_name ]['main_file_path']
1045
+						),
1046
+						EventEspresso\core\domain\values\Version::fromString(
1047
+							self::$_settings[ $addon_name ]['version']
1048
+						),
1049
+					)
1050
+				);
1051
+			}
1052
+			if ($domain instanceof DomainInterface) {
1053
+				$addon->setDomain($domain);
1054
+			}
1055
+		}
1056
+		$addon->set_name($addon_name);
1057
+		$addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1058
+		$addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1059
+		$addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1060
+		$addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1061
+		$addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1062
+		$addon->set_version(self::$_settings[ $addon_name ]['version']);
1063
+		$addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1064
+		$addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1065
+		$addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1066
+		$addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1067
+		// setup the add-on's pue_slug if we have one.
1068
+		if (! empty(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug'])) {
1069
+			$addon->setPueSlug(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug']);
1070
+		}
1071
+		// unfortunately this can't be hooked in upon construction, because we don't have
1072
+		// the plugin mainfile's path upon construction.
1073
+		register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1074
+		// call any additional admin_callback functions during load_admin_controller hook
1075
+		if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1076
+			add_action(
1077
+				'AHEE__EE_System__load_controllers__load_admin_controllers',
1078
+				array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1079
+			);
1080
+		}
1081
+		return $addon;
1082
+	}
1083 1083
 
1084 1084
 
1085
-    /**
1086
-     *    load_pue_update - Update notifications
1087
-     *
1088
-     * @return void
1089
-     * @throws InvalidArgumentException
1090
-     * @throws InvalidDataTypeException
1091
-     * @throws InvalidInterfaceException
1092
-     */
1093
-    public static function load_pue_update()
1094
-    {
1095
-        // load PUE client
1096
-        require_once EE_THIRD_PARTY . 'pue/pue-client.php';
1097
-        $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1098
-        // cycle thru settings
1099
-        foreach (self::$_settings as $settings) {
1100
-            if (! empty($settings['pue_options'])) {
1101
-                // initiate the class and start the plugin update engine!
1102
-                new PluginUpdateEngineChecker(
1103
-                    // host file URL
1104
-                    $license_server,
1105
-                    // plugin slug(s)
1106
-                    array(
1107
-                        'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1108
-                        'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1109
-                    ),
1110
-                    // options
1111
-                    array(
1112
-                        'apikey'            => EE_Registry::instance()->NET_CFG->core->site_license_key,
1113
-                        'lang_domain'       => 'event_espresso',
1114
-                        'checkPeriod'       => $settings['pue_options']['checkPeriod'],
1115
-                        'option_key'        => 'ee_site_license_key',
1116
-                        'options_page_slug' => 'event_espresso',
1117
-                        'plugin_basename'   => $settings['pue_options']['plugin_basename'],
1118
-                        // if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP
1119
-                        'use_wp_update'     => $settings['pue_options']['use_wp_update'],
1120
-                    )
1121
-                );
1122
-            }
1123
-        }
1124
-    }
1085
+	/**
1086
+	 *    load_pue_update - Update notifications
1087
+	 *
1088
+	 * @return void
1089
+	 * @throws InvalidArgumentException
1090
+	 * @throws InvalidDataTypeException
1091
+	 * @throws InvalidInterfaceException
1092
+	 */
1093
+	public static function load_pue_update()
1094
+	{
1095
+		// load PUE client
1096
+		require_once EE_THIRD_PARTY . 'pue/pue-client.php';
1097
+		$license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1098
+		// cycle thru settings
1099
+		foreach (self::$_settings as $settings) {
1100
+			if (! empty($settings['pue_options'])) {
1101
+				// initiate the class and start the plugin update engine!
1102
+				new PluginUpdateEngineChecker(
1103
+					// host file URL
1104
+					$license_server,
1105
+					// plugin slug(s)
1106
+					array(
1107
+						'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1108
+						'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1109
+					),
1110
+					// options
1111
+					array(
1112
+						'apikey'            => EE_Registry::instance()->NET_CFG->core->site_license_key,
1113
+						'lang_domain'       => 'event_espresso',
1114
+						'checkPeriod'       => $settings['pue_options']['checkPeriod'],
1115
+						'option_key'        => 'ee_site_license_key',
1116
+						'options_page_slug' => 'event_espresso',
1117
+						'plugin_basename'   => $settings['pue_options']['plugin_basename'],
1118
+						// if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP
1119
+						'use_wp_update'     => $settings['pue_options']['use_wp_update'],
1120
+					)
1121
+				);
1122
+			}
1123
+		}
1124
+	}
1125 1125
 
1126 1126
 
1127
-    /**
1128
-     * Callback for EE_Brewing_Regular__messages_caf hook used to register message types.
1129
-     *
1130
-     * @since 4.4.0
1131
-     * @return void
1132
-     * @throws EE_Error
1133
-     */
1134
-    public static function register_message_types()
1135
-    {
1136
-        foreach (self::$_settings as $addon_name => $settings) {
1137
-            if (! empty($settings['message_types'])) {
1138
-                foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1139
-                    EE_Register_Message_Type::register($message_type, $message_type_settings);
1140
-                }
1141
-            }
1142
-        }
1143
-    }
1127
+	/**
1128
+	 * Callback for EE_Brewing_Regular__messages_caf hook used to register message types.
1129
+	 *
1130
+	 * @since 4.4.0
1131
+	 * @return void
1132
+	 * @throws EE_Error
1133
+	 */
1134
+	public static function register_message_types()
1135
+	{
1136
+		foreach (self::$_settings as $addon_name => $settings) {
1137
+			if (! empty($settings['message_types'])) {
1138
+				foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1139
+					EE_Register_Message_Type::register($message_type, $message_type_settings);
1140
+				}
1141
+			}
1142
+		}
1143
+	}
1144 1144
 
1145 1145
 
1146
-    /**
1147
-     * This deregisters an addon that was previously registered with a specific addon_name.
1148
-     *
1149
-     * @since    4.3.0
1150
-     * @param string $addon_name the name for the addon that was previously registered
1151
-     * @throws DomainException
1152
-     * @throws EE_Error
1153
-     * @throws InvalidArgumentException
1154
-     * @throws InvalidDataTypeException
1155
-     * @throws InvalidInterfaceException
1156
-     */
1157
-    public static function deregister($addon_name = null)
1158
-    {
1159
-        if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1160
-            try {
1161
-                do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1162
-                $class_name = self::$_settings[ $addon_name ]['class_name'];
1163
-                if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1164
-                    // setup DMS
1165
-                    EE_Register_Data_Migration_Scripts::deregister($addon_name);
1166
-                }
1167
-                if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1168
-                    // register admin page
1169
-                    EE_Register_Admin_Page::deregister($addon_name);
1170
-                }
1171
-                if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1172
-                    // add to list of modules to be registered
1173
-                    EE_Register_Module::deregister($addon_name);
1174
-                }
1175
-                if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1176
-                    || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1177
-                ) {
1178
-                    // add to list of shortcodes to be registered
1179
-                    EE_Register_Shortcode::deregister($addon_name);
1180
-                }
1181
-                if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1182
-                    // if config_class present let's register config.
1183
-                    EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1184
-                }
1185
-                if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1186
-                    // add to list of widgets to be registered
1187
-                    EE_Register_Widget::deregister($addon_name);
1188
-                }
1189
-                if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1190
-                    || ! empty(self::$_settings[ $addon_name ]['class_paths'])
1191
-                ) {
1192
-                    // add to list of shortcodes to be registered
1193
-                    EE_Register_Model::deregister($addon_name);
1194
-                }
1195
-                if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1196
-                    || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1197
-                ) {
1198
-                    // add to list of shortcodes to be registered
1199
-                    EE_Register_Model_Extensions::deregister($addon_name);
1200
-                }
1201
-                if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1202
-                    foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1203
-                        EE_Register_Message_Type::deregister($message_type);
1204
-                    }
1205
-                }
1206
-                // deregister capabilities for addon
1207
-                if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1208
-                    || ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1209
-                ) {
1210
-                    EE_Register_Capabilities::deregister($addon_name);
1211
-                }
1212
-                // deregister custom_post_types for addon
1213
-                if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1214
-                    EE_Register_CPT::deregister($addon_name);
1215
-                }
1216
-                if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1217
-                    EE_Register_Payment_Method::deregister($addon_name);
1218
-                }
1219
-                $addon = EE_Registry::instance()->getAddon($class_name);
1220
-                if ($addon instanceof EE_Addon) {
1221
-                    remove_action(
1222
-                        'deactivate_' . $addon->get_main_plugin_file_basename(),
1223
-                        array($addon, 'deactivation')
1224
-                    );
1225
-                    remove_action(
1226
-                        'AHEE__EE_System__perform_activations_upgrades_and_migrations',
1227
-                        array($addon, 'initialize_db_if_no_migrations_required')
1228
-                    );
1229
-                    // remove `after_registration` call
1230
-                    remove_action(
1231
-                        'AHEE__EE_System__load_espresso_addons__complete',
1232
-                        array($addon, 'after_registration'),
1233
-                        999
1234
-                    );
1235
-                }
1236
-                EE_Registry::instance()->removeAddon($class_name);
1237
-            } catch (OutOfBoundsException $addon_not_yet_registered_exception) {
1238
-                // the add-on was not yet registered in the registry,
1239
-                // so RegistryContainer::__get() throws this exception.
1240
-                // also no need to worry about this or log it,
1241
-                // it's ok to deregister an add-on before its registered in the registry
1242
-            } catch (Exception $e) {
1243
-                new ExceptionLogger($e);
1244
-            }
1245
-            unset(self::$_settings[ $addon_name ]);
1246
-            do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1247
-        }
1248
-    }
1146
+	/**
1147
+	 * This deregisters an addon that was previously registered with a specific addon_name.
1148
+	 *
1149
+	 * @since    4.3.0
1150
+	 * @param string $addon_name the name for the addon that was previously registered
1151
+	 * @throws DomainException
1152
+	 * @throws EE_Error
1153
+	 * @throws InvalidArgumentException
1154
+	 * @throws InvalidDataTypeException
1155
+	 * @throws InvalidInterfaceException
1156
+	 */
1157
+	public static function deregister($addon_name = null)
1158
+	{
1159
+		if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1160
+			try {
1161
+				do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1162
+				$class_name = self::$_settings[ $addon_name ]['class_name'];
1163
+				if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1164
+					// setup DMS
1165
+					EE_Register_Data_Migration_Scripts::deregister($addon_name);
1166
+				}
1167
+				if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1168
+					// register admin page
1169
+					EE_Register_Admin_Page::deregister($addon_name);
1170
+				}
1171
+				if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1172
+					// add to list of modules to be registered
1173
+					EE_Register_Module::deregister($addon_name);
1174
+				}
1175
+				if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1176
+					|| ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1177
+				) {
1178
+					// add to list of shortcodes to be registered
1179
+					EE_Register_Shortcode::deregister($addon_name);
1180
+				}
1181
+				if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1182
+					// if config_class present let's register config.
1183
+					EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1184
+				}
1185
+				if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1186
+					// add to list of widgets to be registered
1187
+					EE_Register_Widget::deregister($addon_name);
1188
+				}
1189
+				if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1190
+					|| ! empty(self::$_settings[ $addon_name ]['class_paths'])
1191
+				) {
1192
+					// add to list of shortcodes to be registered
1193
+					EE_Register_Model::deregister($addon_name);
1194
+				}
1195
+				if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1196
+					|| ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1197
+				) {
1198
+					// add to list of shortcodes to be registered
1199
+					EE_Register_Model_Extensions::deregister($addon_name);
1200
+				}
1201
+				if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1202
+					foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1203
+						EE_Register_Message_Type::deregister($message_type);
1204
+					}
1205
+				}
1206
+				// deregister capabilities for addon
1207
+				if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1208
+					|| ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1209
+				) {
1210
+					EE_Register_Capabilities::deregister($addon_name);
1211
+				}
1212
+				// deregister custom_post_types for addon
1213
+				if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1214
+					EE_Register_CPT::deregister($addon_name);
1215
+				}
1216
+				if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1217
+					EE_Register_Payment_Method::deregister($addon_name);
1218
+				}
1219
+				$addon = EE_Registry::instance()->getAddon($class_name);
1220
+				if ($addon instanceof EE_Addon) {
1221
+					remove_action(
1222
+						'deactivate_' . $addon->get_main_plugin_file_basename(),
1223
+						array($addon, 'deactivation')
1224
+					);
1225
+					remove_action(
1226
+						'AHEE__EE_System__perform_activations_upgrades_and_migrations',
1227
+						array($addon, 'initialize_db_if_no_migrations_required')
1228
+					);
1229
+					// remove `after_registration` call
1230
+					remove_action(
1231
+						'AHEE__EE_System__load_espresso_addons__complete',
1232
+						array($addon, 'after_registration'),
1233
+						999
1234
+					);
1235
+				}
1236
+				EE_Registry::instance()->removeAddon($class_name);
1237
+			} catch (OutOfBoundsException $addon_not_yet_registered_exception) {
1238
+				// the add-on was not yet registered in the registry,
1239
+				// so RegistryContainer::__get() throws this exception.
1240
+				// also no need to worry about this or log it,
1241
+				// it's ok to deregister an add-on before its registered in the registry
1242
+			} catch (Exception $e) {
1243
+				new ExceptionLogger($e);
1244
+			}
1245
+			unset(self::$_settings[ $addon_name ]);
1246
+			do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1247
+		}
1248
+	}
1249 1249
 }
Please login to merge, or discard this patch.
core/domain/DomainFactory.php 2 patches
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -23,62 +23,62 @@
 block discarded – undo
23 23
 class DomainFactory
24 24
 {
25 25
 
26
-    /**
27
-     * @param FullyQualifiedName $domain_fqcn   [required] Fully Qualified Class Name for the Domain class
28
-     * @param array $arguments                  [required] array of arguments to be passed to the Domain class
29
-     *                                          constructor. Must at least include the following two value objects:
30
-     *                                          array(
31
-     *                                              EventEspresso\core\domain\values\FilePath $plugin_file
32
-     *                                              EventEspresso\core\domain\values\Version $version
33
-     *                                          )
34
-     * @return DomainInterface
35
-     * @throws DomainException
36
-     * @throws InvalidArgumentException
37
-     * @throws InvalidDataTypeException
38
-     * @throws InvalidInterfaceException
39
-     */
40
-    public static function getShared(FullyQualifiedName $domain_fqcn, array $arguments)
41
-    {
42
-        if (! isset($arguments[0], $arguments[1])) {
43
-            throw new InvalidArgumentException(
44
-                esc_html__(
45
-                    'You need to pass at least two arguments, representing the addon plugin file and version, in order to generate a Domain class',
46
-                    'event_espresso'
47
-                )
48
-            );
49
-        }
50
-        /** @var DomainInterface $domain */
51
-        $domain = LoaderFactory::getLoader()->getShared($domain_fqcn, $arguments);
52
-        if (! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
53
-            throw new DomainException(
54
-                sprintf(
55
-                    esc_html__(
56
-                        'The requested Domain class "%1$s" could not be loaded.',
57
-                        'event_espresso'
58
-                    ),
59
-                    $domain_fqcn
60
-                )
61
-            );
62
-        }
63
-        return $domain;
64
-    }
26
+	/**
27
+	 * @param FullyQualifiedName $domain_fqcn   [required] Fully Qualified Class Name for the Domain class
28
+	 * @param array $arguments                  [required] array of arguments to be passed to the Domain class
29
+	 *                                          constructor. Must at least include the following two value objects:
30
+	 *                                          array(
31
+	 *                                              EventEspresso\core\domain\values\FilePath $plugin_file
32
+	 *                                              EventEspresso\core\domain\values\Version $version
33
+	 *                                          )
34
+	 * @return DomainInterface
35
+	 * @throws DomainException
36
+	 * @throws InvalidArgumentException
37
+	 * @throws InvalidDataTypeException
38
+	 * @throws InvalidInterfaceException
39
+	 */
40
+	public static function getShared(FullyQualifiedName $domain_fqcn, array $arguments)
41
+	{
42
+		if (! isset($arguments[0], $arguments[1])) {
43
+			throw new InvalidArgumentException(
44
+				esc_html__(
45
+					'You need to pass at least two arguments, representing the addon plugin file and version, in order to generate a Domain class',
46
+					'event_espresso'
47
+				)
48
+			);
49
+		}
50
+		/** @var DomainInterface $domain */
51
+		$domain = LoaderFactory::getLoader()->getShared($domain_fqcn, $arguments);
52
+		if (! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
53
+			throw new DomainException(
54
+				sprintf(
55
+					esc_html__(
56
+						'The requested Domain class "%1$s" could not be loaded.',
57
+						'event_espresso'
58
+					),
59
+					$domain_fqcn
60
+				)
61
+			);
62
+		}
63
+		return $domain;
64
+	}
65 65
 
66 66
 
67
-    /**
68
-     * @return Domain
69
-     * @throws DomainException
70
-     * @throws InvalidArgumentException
71
-     * @throws InvalidDataTypeException
72
-     * @throws InvalidFilePathException
73
-     * @throws InvalidInterfaceException
74
-     */
75
-    public static function getEventEspressoCoreDomain()
76
-    {
77
-        $domain = new Domain(
78
-            new FilePath(EVENT_ESPRESSO_MAIN_FILE),
79
-            Version::fromString(espresso_version())
80
-        );
81
-        LoaderFactory::getLoader()->share('EventEspresso\core\domain\Domain', $domain);
82
-        return $domain;
83
-    }
67
+	/**
68
+	 * @return Domain
69
+	 * @throws DomainException
70
+	 * @throws InvalidArgumentException
71
+	 * @throws InvalidDataTypeException
72
+	 * @throws InvalidFilePathException
73
+	 * @throws InvalidInterfaceException
74
+	 */
75
+	public static function getEventEspressoCoreDomain()
76
+	{
77
+		$domain = new Domain(
78
+			new FilePath(EVENT_ESPRESSO_MAIN_FILE),
79
+			Version::fromString(espresso_version())
80
+		);
81
+		LoaderFactory::getLoader()->share('EventEspresso\core\domain\Domain', $domain);
82
+		return $domain;
83
+	}
84 84
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -39,7 +39,7 @@  discard block
 block discarded – undo
39 39
      */
40 40
     public static function getShared(FullyQualifiedName $domain_fqcn, array $arguments)
41 41
     {
42
-        if (! isset($arguments[0], $arguments[1])) {
42
+        if ( ! isset($arguments[0], $arguments[1])) {
43 43
             throw new InvalidArgumentException(
44 44
                 esc_html__(
45 45
                     'You need to pass at least two arguments, representing the addon plugin file and version, in order to generate a Domain class',
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
         }
50 50
         /** @var DomainInterface $domain */
51 51
         $domain = LoaderFactory::getLoader()->getShared($domain_fqcn, $arguments);
52
-        if (! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
52
+        if ( ! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
53 53
             throw new DomainException(
54 54
                 sprintf(
55 55
                     esc_html__(
Please login to merge, or discard this patch.
core/helpers/EEH_Activation.helper.php 1 patch
Indentation   +1615 added lines, -1615 removed lines patch added patch discarded remove patch
@@ -15,233 +15,233 @@  discard block
 block discarded – undo
15 15
 class EEH_Activation implements ResettableInterface
16 16
 {
17 17
 
18
-    /**
19
-     * constant used to indicate a cron task is no longer in use
20
-     */
21
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
22
-
23
-    /**
24
-     * WP_User->ID
25
-     *
26
-     * @var int
27
-     */
28
-    private static $_default_creator_id;
29
-
30
-    /**
31
-     * indicates whether or not we've already verified core's default data during this request,
32
-     * because after migrations are done, any addons activated while in maintenance mode
33
-     * will want to setup their own default data, and they might hook into core's default data
34
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
35
-     * This prevents doing that for EVERY single addon.
36
-     *
37
-     * @var boolean
38
-     */
39
-    protected static $_initialized_db_content_already_in_this_request = false;
40
-
41
-    /**
42
-     * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
43
-     */
44
-    private static $table_analysis;
45
-
46
-    /**
47
-     * @var \EventEspresso\core\services\database\TableManager $table_manager
48
-     */
49
-    private static $table_manager;
50
-
51
-
52
-    /**
53
-     * @return \EventEspresso\core\services\database\TableAnalysis
54
-     */
55
-    public static function getTableAnalysis()
56
-    {
57
-        if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
58
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
59
-        }
60
-        return self::$table_analysis;
61
-    }
62
-
63
-
64
-    /**
65
-     * @return \EventEspresso\core\services\database\TableManager
66
-     */
67
-    public static function getTableManager()
68
-    {
69
-        if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
70
-            self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
71
-        }
72
-        return self::$table_manager;
73
-    }
74
-
75
-
76
-    /**
77
-     *    _ensure_table_name_has_prefix
78
-     *
79
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
80
-     * @access     public
81
-     * @static
82
-     * @param $table_name
83
-     * @return string
84
-     */
85
-    public static function ensure_table_name_has_prefix($table_name)
86
-    {
87
-        return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
88
-    }
89
-
90
-
91
-    /**
92
-     *    system_initialization
93
-     *    ensures the EE configuration settings are loaded with at least default options set
94
-     *    and that all critical EE pages have been generated with the appropriate shortcodes in place
95
-     *
96
-     * @access public
97
-     * @static
98
-     * @return void
99
-     */
100
-    public static function system_initialization()
101
-    {
102
-        EEH_Activation::reset_and_update_config();
103
-        // which is fired BEFORE activation of plugin anyways
104
-        EEH_Activation::verify_default_pages_exist();
105
-    }
106
-
107
-
108
-    /**
109
-     * Sets the database schema and creates folders. This should
110
-     * be called on plugin activation and reactivation
111
-     *
112
-     * @return boolean success, whether the database and folders are setup properly
113
-     * @throws \EE_Error
114
-     */
115
-    public static function initialize_db_and_folders()
116
-    {
117
-        return EEH_Activation::create_database_tables();
118
-    }
119
-
120
-
121
-    /**
122
-     * assuming we have an up-to-date database schema, this will populate it
123
-     * with default and initial data. This should be called
124
-     * upon activation of a new plugin, reactivation, and at the end
125
-     * of running migration scripts
126
-     *
127
-     * @throws \EE_Error
128
-     */
129
-    public static function initialize_db_content()
130
-    {
131
-        // let's avoid doing all this logic repeatedly, especially when addons are requesting it
132
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
133
-            return;
134
-        }
135
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
136
-
137
-        EEH_Activation::initialize_system_questions();
138
-        EEH_Activation::insert_default_status_codes();
139
-        EEH_Activation::generate_default_message_templates();
140
-        EEH_Activation::create_no_ticket_prices_array();
141
-        EEH_Activation::removeEmailConfirmFromAddressGroup();
142
-
143
-        EEH_Activation::validate_messages_system();
144
-        EEH_Activation::insert_default_payment_methods();
145
-        // in case we've
146
-        EEH_Activation::remove_cron_tasks();
147
-        EEH_Activation::create_cron_tasks();
148
-        // remove all TXN locks since that is being done via extra meta now
149
-        delete_option('ee_locked_transactions');
150
-        // also, check for CAF default db content
151
-        do_action('AHEE__EEH_Activation__initialize_db_content');
152
-        // also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
153
-        // which users really won't care about on initial activation
154
-        EE_Error::overwrite_success();
155
-    }
156
-
157
-
158
-    /**
159
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
160
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
161
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
162
-     * (null)
163
-     *
164
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
165
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
166
-     * @return array
167
-     * @throws \EE_Error
168
-     */
169
-    public static function get_cron_tasks($which_to_include)
170
-    {
171
-        $cron_tasks = apply_filters(
172
-            'FHEE__EEH_Activation__get_cron_tasks',
173
-            array(
174
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
175
-            //              'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
176
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
177
-                // there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
178
-                'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
179
-            )
180
-        );
181
-        if ($which_to_include === 'old') {
182
-            $cron_tasks = array_filter(
183
-                $cron_tasks,
184
-                function ($value) {
185
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
186
-                }
187
-            );
188
-        } elseif ($which_to_include === 'current') {
189
-            $cron_tasks = array_filter($cron_tasks);
190
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
191
-            throw new EE_Error(
192
-                sprintf(
193
-                    __(
194
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
195
-                        'event_espresso'
196
-                    ),
197
-                    $which_to_include
198
-                )
199
-            );
200
-        }
201
-        return $cron_tasks;
202
-    }
203
-
204
-
205
-    /**
206
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
207
-     *
208
-     * @throws \EE_Error
209
-     */
210
-    public static function create_cron_tasks()
211
-    {
212
-
213
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
214
-            if (! wp_next_scheduled($hook_name)) {
215
-                /**
216
-                 * This allows client code to define the initial start timestamp for this schedule.
217
-                 */
218
-                if (is_array($frequency)
219
-                    && count($frequency) === 2
220
-                    && isset($frequency[0], $frequency[1])
221
-                ) {
222
-                    $start_timestamp = $frequency[0];
223
-                    $frequency = $frequency[1];
224
-                } else {
225
-                    $start_timestamp = time();
226
-                }
227
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
228
-            }
229
-        }
230
-    }
231
-
232
-
233
-    /**
234
-     * Remove the currently-existing and now-removed cron tasks.
235
-     *
236
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
237
-     * @throws \EE_Error
238
-     */
239
-    public static function remove_cron_tasks($remove_all = true)
240
-    {
241
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
242
-        $crons                = _get_cron_array();
243
-        $crons                = is_array($crons) ? $crons : array();
244
-        /* reminder of what $crons look like:
18
+	/**
19
+	 * constant used to indicate a cron task is no longer in use
20
+	 */
21
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
22
+
23
+	/**
24
+	 * WP_User->ID
25
+	 *
26
+	 * @var int
27
+	 */
28
+	private static $_default_creator_id;
29
+
30
+	/**
31
+	 * indicates whether or not we've already verified core's default data during this request,
32
+	 * because after migrations are done, any addons activated while in maintenance mode
33
+	 * will want to setup their own default data, and they might hook into core's default data
34
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
35
+	 * This prevents doing that for EVERY single addon.
36
+	 *
37
+	 * @var boolean
38
+	 */
39
+	protected static $_initialized_db_content_already_in_this_request = false;
40
+
41
+	/**
42
+	 * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
43
+	 */
44
+	private static $table_analysis;
45
+
46
+	/**
47
+	 * @var \EventEspresso\core\services\database\TableManager $table_manager
48
+	 */
49
+	private static $table_manager;
50
+
51
+
52
+	/**
53
+	 * @return \EventEspresso\core\services\database\TableAnalysis
54
+	 */
55
+	public static function getTableAnalysis()
56
+	{
57
+		if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
58
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
59
+		}
60
+		return self::$table_analysis;
61
+	}
62
+
63
+
64
+	/**
65
+	 * @return \EventEspresso\core\services\database\TableManager
66
+	 */
67
+	public static function getTableManager()
68
+	{
69
+		if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
70
+			self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
71
+		}
72
+		return self::$table_manager;
73
+	}
74
+
75
+
76
+	/**
77
+	 *    _ensure_table_name_has_prefix
78
+	 *
79
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
80
+	 * @access     public
81
+	 * @static
82
+	 * @param $table_name
83
+	 * @return string
84
+	 */
85
+	public static function ensure_table_name_has_prefix($table_name)
86
+	{
87
+		return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
88
+	}
89
+
90
+
91
+	/**
92
+	 *    system_initialization
93
+	 *    ensures the EE configuration settings are loaded with at least default options set
94
+	 *    and that all critical EE pages have been generated with the appropriate shortcodes in place
95
+	 *
96
+	 * @access public
97
+	 * @static
98
+	 * @return void
99
+	 */
100
+	public static function system_initialization()
101
+	{
102
+		EEH_Activation::reset_and_update_config();
103
+		// which is fired BEFORE activation of plugin anyways
104
+		EEH_Activation::verify_default_pages_exist();
105
+	}
106
+
107
+
108
+	/**
109
+	 * Sets the database schema and creates folders. This should
110
+	 * be called on plugin activation and reactivation
111
+	 *
112
+	 * @return boolean success, whether the database and folders are setup properly
113
+	 * @throws \EE_Error
114
+	 */
115
+	public static function initialize_db_and_folders()
116
+	{
117
+		return EEH_Activation::create_database_tables();
118
+	}
119
+
120
+
121
+	/**
122
+	 * assuming we have an up-to-date database schema, this will populate it
123
+	 * with default and initial data. This should be called
124
+	 * upon activation of a new plugin, reactivation, and at the end
125
+	 * of running migration scripts
126
+	 *
127
+	 * @throws \EE_Error
128
+	 */
129
+	public static function initialize_db_content()
130
+	{
131
+		// let's avoid doing all this logic repeatedly, especially when addons are requesting it
132
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
133
+			return;
134
+		}
135
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
136
+
137
+		EEH_Activation::initialize_system_questions();
138
+		EEH_Activation::insert_default_status_codes();
139
+		EEH_Activation::generate_default_message_templates();
140
+		EEH_Activation::create_no_ticket_prices_array();
141
+		EEH_Activation::removeEmailConfirmFromAddressGroup();
142
+
143
+		EEH_Activation::validate_messages_system();
144
+		EEH_Activation::insert_default_payment_methods();
145
+		// in case we've
146
+		EEH_Activation::remove_cron_tasks();
147
+		EEH_Activation::create_cron_tasks();
148
+		// remove all TXN locks since that is being done via extra meta now
149
+		delete_option('ee_locked_transactions');
150
+		// also, check for CAF default db content
151
+		do_action('AHEE__EEH_Activation__initialize_db_content');
152
+		// also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
153
+		// which users really won't care about on initial activation
154
+		EE_Error::overwrite_success();
155
+	}
156
+
157
+
158
+	/**
159
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
160
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
161
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
162
+	 * (null)
163
+	 *
164
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
165
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
166
+	 * @return array
167
+	 * @throws \EE_Error
168
+	 */
169
+	public static function get_cron_tasks($which_to_include)
170
+	{
171
+		$cron_tasks = apply_filters(
172
+			'FHEE__EEH_Activation__get_cron_tasks',
173
+			array(
174
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
175
+			//              'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
176
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
177
+				// there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
178
+				'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
179
+			)
180
+		);
181
+		if ($which_to_include === 'old') {
182
+			$cron_tasks = array_filter(
183
+				$cron_tasks,
184
+				function ($value) {
185
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
186
+				}
187
+			);
188
+		} elseif ($which_to_include === 'current') {
189
+			$cron_tasks = array_filter($cron_tasks);
190
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
191
+			throw new EE_Error(
192
+				sprintf(
193
+					__(
194
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
195
+						'event_espresso'
196
+					),
197
+					$which_to_include
198
+				)
199
+			);
200
+		}
201
+		return $cron_tasks;
202
+	}
203
+
204
+
205
+	/**
206
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
207
+	 *
208
+	 * @throws \EE_Error
209
+	 */
210
+	public static function create_cron_tasks()
211
+	{
212
+
213
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
214
+			if (! wp_next_scheduled($hook_name)) {
215
+				/**
216
+				 * This allows client code to define the initial start timestamp for this schedule.
217
+				 */
218
+				if (is_array($frequency)
219
+					&& count($frequency) === 2
220
+					&& isset($frequency[0], $frequency[1])
221
+				) {
222
+					$start_timestamp = $frequency[0];
223
+					$frequency = $frequency[1];
224
+				} else {
225
+					$start_timestamp = time();
226
+				}
227
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
228
+			}
229
+		}
230
+	}
231
+
232
+
233
+	/**
234
+	 * Remove the currently-existing and now-removed cron tasks.
235
+	 *
236
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
237
+	 * @throws \EE_Error
238
+	 */
239
+	public static function remove_cron_tasks($remove_all = true)
240
+	{
241
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
242
+		$crons                = _get_cron_array();
243
+		$crons                = is_array($crons) ? $crons : array();
244
+		/* reminder of what $crons look like:
245 245
          * Top-level keys are timestamps, and their values are arrays.
246 246
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
247 247
          * and their values are arrays.
@@ -258,925 +258,925 @@  discard block
 block discarded – undo
258 258
          *                  ...
259 259
          *      ...
260 260
          */
261
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
262
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
263
-            if (is_array($hooks_to_fire_at_time)) {
264
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
265
-                    if (isset($ee_cron_tasks_to_remove[ $hook_name ])
266
-                        && is_array($ee_cron_tasks_to_remove[ $hook_name ])
267
-                    ) {
268
-                        unset($crons[ $timestamp ][ $hook_name ]);
269
-                    }
270
-                }
271
-                // also take care of any empty cron timestamps.
272
-                if (empty($hooks_to_fire_at_time)) {
273
-                    unset($crons[ $timestamp ]);
274
-                }
275
-            }
276
-        }
277
-        _set_cron_array($crons);
278
-    }
279
-
280
-
281
-    /**
282
-     *    CPT_initialization
283
-     *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
284
-     *
285
-     * @access public
286
-     * @static
287
-     * @return void
288
-     */
289
-    public static function CPT_initialization()
290
-    {
291
-        // register Custom Post Types
292
-        EE_Registry::instance()->load_core('Register_CPTs');
293
-        flush_rewrite_rules();
294
-    }
295
-
296
-
297
-
298
-    /**
299
-     *    reset_and_update_config
300
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
301
-     * If there is old calendar config data saved, then it will get converted on activation.
302
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
303
-     *
304
-     * @access public
305
-     * @static
306
-     * @return void
307
-     */
308
-    public static function reset_and_update_config()
309
-    {
310
-        do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
311
-        add_filter(
312
-            'FHEE__EE_Config___load_core_config__config_settings',
313
-            array('EEH_Activation', 'migrate_old_config_data'),
314
-            10,
315
-            3
316
-        );
317
-        // EE_Config::reset();
318
-        if (! EE_Config::logging_enabled()) {
319
-            delete_option(EE_Config::LOG_NAME);
320
-        }
321
-    }
322
-
323
-
324
-    /**
325
-     *    load_calendar_config
326
-     *
327
-     * @access    public
328
-     * @return    void
329
-     */
330
-    public static function load_calendar_config()
331
-    {
332
-        // grab array of all plugin folders and loop thru it
333
-        $plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
334
-        if (empty($plugins)) {
335
-            return;
336
-        }
337
-        foreach ($plugins as $plugin_path) {
338
-            // grab plugin folder name from path
339
-            $plugin = basename($plugin_path);
340
-            // drill down to Espresso plugins
341
-            // then to calendar related plugins
342
-            if (strpos($plugin, 'espresso') !== false
343
-                || strpos($plugin, 'Espresso') !== false
344
-                || strpos($plugin, 'ee4') !== false
345
-                || strpos($plugin, 'EE4') !== false
346
-                || strpos($plugin, 'calendar') !== false
347
-            ) {
348
-                // this is what we are looking for
349
-                $calendar_config = $plugin_path . '/EE_Calendar_Config.php';
350
-                // does it exist in this folder ?
351
-                if (is_readable($calendar_config)) {
352
-                    // YEAH! let's load it
353
-                    require_once($calendar_config);
354
-                }
355
-            }
356
-        }
357
-    }
358
-
359
-
360
-
361
-    /**
362
-     *    _migrate_old_config_data
363
-     *
364
-     * @access    public
365
-     * @param array|stdClass $settings
366
-     * @param string         $config
367
-     * @param \EE_Config     $EE_Config
368
-     * @return \stdClass
369
-     */
370
-    public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
371
-    {
372
-        $convert_from_array = array('addons');
373
-        // in case old settings were saved as an array
374
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
375
-            // convert existing settings to an object
376
-            $config_array = $settings;
377
-            $settings = new stdClass();
378
-            foreach ($config_array as $key => $value) {
379
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
380
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
381
-                } else {
382
-                    $settings->{$key} = $value;
383
-                }
384
-            }
385
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
386
-        }
387
-        return $settings;
388
-    }
389
-
390
-
391
-    /**
392
-     * deactivate_event_espresso
393
-     *
394
-     * @access public
395
-     * @static
396
-     * @return void
397
-     */
398
-    public static function deactivate_event_espresso()
399
-    {
400
-        // check permissions
401
-        if (current_user_can('activate_plugins')) {
402
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
403
-        }
404
-    }
405
-
406
-
407
-
408
-    /**
409
-     * verify_default_pages_exist
410
-     *
411
-     * @access public
412
-     * @static
413
-     * @return void
414
-     * @throws InvalidDataTypeException
415
-     */
416
-    public static function verify_default_pages_exist()
417
-    {
418
-        $critical_page_problem = false;
419
-        $critical_pages = array(
420
-            array(
421
-                'id'   => 'reg_page_id',
422
-                'name' => __('Registration Checkout', 'event_espresso'),
423
-                'post' => null,
424
-                'code' => 'ESPRESSO_CHECKOUT',
425
-            ),
426
-            array(
427
-                'id'   => 'txn_page_id',
428
-                'name' => __('Transactions', 'event_espresso'),
429
-                'post' => null,
430
-                'code' => 'ESPRESSO_TXN_PAGE',
431
-            ),
432
-            array(
433
-                'id'   => 'thank_you_page_id',
434
-                'name' => __('Thank You', 'event_espresso'),
435
-                'post' => null,
436
-                'code' => 'ESPRESSO_THANK_YOU',
437
-            ),
438
-            array(
439
-                'id'   => 'cancel_page_id',
440
-                'name' => __('Registration Cancelled', 'event_espresso'),
441
-                'post' => null,
442
-                'code' => 'ESPRESSO_CANCELLED',
443
-            ),
444
-        );
445
-        $EE_Core_Config = EE_Registry::instance()->CFG->core;
446
-        foreach ($critical_pages as $critical_page) {
447
-            // is critical page ID set in config ?
448
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
449
-                // attempt to find post by ID
450
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
451
-            }
452
-            // no dice?
453
-            if ($critical_page['post'] === null) {
454
-                // attempt to find post by title
455
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
456
-                // still nothing?
457
-                if ($critical_page['post'] === null) {
458
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
459
-                    // REALLY? Still nothing ??!?!?
460
-                    if ($critical_page['post'] === null) {
461
-                        $msg = __(
462
-                            'The Event Espresso critical page configuration settings could not be updated.',
463
-                            'event_espresso'
464
-                        );
465
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
466
-                        break;
467
-                    }
468
-                }
469
-            }
470
-            // check that Post ID matches critical page ID in config
471
-            if (isset($critical_page['post']->ID)
472
-                && $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
473
-            ) {
474
-                // update Config with post ID
475
-                $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
476
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
477
-                    $msg = __(
478
-                        'The Event Espresso critical page configuration settings could not be updated.',
479
-                        'event_espresso'
480
-                    );
481
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
482
-                }
483
-            }
484
-            $critical_page_problem =
485
-                ! isset($critical_page['post']->post_status)
486
-                || $critical_page['post']->post_status !== 'publish'
487
-                || strpos($critical_page['post']->post_content, $critical_page['code']) === false
488
-                    ? true
489
-                    : $critical_page_problem;
490
-        }
491
-        if ($critical_page_problem) {
492
-            new PersistentAdminNotice(
493
-                'critical_page_problem',
494
-                sprintf(
495
-                    esc_html__(
496
-                        'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
497
-                        'event_espresso'
498
-                    ),
499
-                    '<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
500
-                    . __('Event Espresso Critical Pages Settings', 'event_espresso')
501
-                    . '</a>'
502
-                )
503
-            );
504
-        }
505
-        if (EE_Error::has_notices()) {
506
-            EE_Error::get_notices(false, true, true);
507
-        }
508
-    }
509
-
510
-
511
-
512
-    /**
513
-     * Returns the first post which uses the specified shortcode
514
-     *
515
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
516
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
517
-     *                             "[ESPRESSO_THANK_YOU"
518
-     *                             (we don't search for the closing shortcode bracket because they might have added
519
-     *                             parameter to the shortcode
520
-     * @return WP_Post or NULl
521
-     */
522
-    public static function get_page_by_ee_shortcode($ee_shortcode)
523
-    {
524
-        global $wpdb;
525
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
526
-        $post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
527
-        if ($post_id) {
528
-            return get_post($post_id);
529
-        } else {
530
-            return null;
531
-        }
532
-    }
533
-
534
-
535
-    /**
536
-     *    This function generates a post for critical espresso pages
537
-     *
538
-     * @access public
539
-     * @static
540
-     * @param array $critical_page
541
-     * @return array
542
-     */
543
-    public static function create_critical_page($critical_page)
544
-    {
545
-
546
-        $post_args = array(
547
-            'post_title'     => $critical_page['name'],
548
-            'post_status'    => 'publish',
549
-            'post_type'      => 'page',
550
-            'comment_status' => 'closed',
551
-            'post_content'   => '[' . $critical_page['code'] . ']',
552
-        );
553
-
554
-        $post_id = wp_insert_post($post_args);
555
-        if (! $post_id) {
556
-            $msg = sprintf(
557
-                __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
558
-                $critical_page['name']
559
-            );
560
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
561
-            return $critical_page;
562
-        }
563
-        // get newly created post's details
564
-        if (! $critical_page['post'] = get_post($post_id)) {
565
-            $msg = sprintf(
566
-                __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
567
-                $critical_page['name']
568
-            );
569
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
570
-        }
571
-
572
-        return $critical_page;
573
-    }
574
-
575
-
576
-
577
-
578
-    /**
579
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
580
-     * The role being used to check is filterable.
581
-     *
582
-     * @since  4.6.0
583
-     * @global WPDB $wpdb
584
-     * @return mixed null|int WP_user ID or NULL
585
-     */
586
-    public static function get_default_creator_id()
587
-    {
588
-        global $wpdb;
589
-        if (! empty(self::$_default_creator_id)) {
590
-            return self::$_default_creator_id;
591
-        }/**/
592
-        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
593
-        // let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
594
-        $pre_filtered_id = apply_filters(
595
-            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
596
-            false,
597
-            $role_to_check
598
-        );
599
-        if ($pre_filtered_id !== false) {
600
-            return (int) $pre_filtered_id;
601
-        }
602
-        $capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
603
-        $query = $wpdb->prepare(
604
-            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
605
-            '%' . $role_to_check . '%'
606
-        );
607
-        $user_id = $wpdb->get_var($query);
608
-        $user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
609
-        if ($user_id && (int) $user_id) {
610
-            self::$_default_creator_id = (int) $user_id;
611
-            return self::$_default_creator_id;
612
-        } else {
613
-            return null;
614
-        }
615
-    }
616
-
617
-
618
-
619
-    /**
620
-     * used by EE and EE addons during plugin activation to create tables.
621
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
622
-     * but includes extra logic regarding activations.
623
-     *
624
-     * @access public
625
-     * @static
626
-     * @param string  $table_name              without the $wpdb->prefix
627
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
628
-     *                                         table query)
629
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
630
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
631
-     *                                         and new once this function is done (ie, you really do want to CREATE a
632
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
633
-     *                                         you just want to verify the table exists and matches this definition
634
-     *                                         (and if it HAS data in it you want to leave it be)
635
-     * @return void
636
-     * @throws EE_Error if there are database errors
637
-     */
638
-    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
639
-    {
640
-        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
641
-            return;
642
-        }
643
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
644
-        if (! function_exists('dbDelta')) {
645
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
646
-        }
647
-        $tableAnalysis = \EEH_Activation::getTableAnalysis();
648
-        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
649
-        // do we need to first delete an existing version of this table ?
650
-        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
651
-            // ok, delete the table... but ONLY if it's empty
652
-            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
653
-            // table is NOT empty, are you SURE you want to delete this table ???
654
-            if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
655
-                \EEH_Activation::getTableManager()->dropTable($wp_table_name);
656
-            } elseif (! $deleted_safely) {
657
-                // so we should be more cautious rather than just dropping tables so easily
658
-                error_log(
659
-                    sprintf(
660
-                        __(
661
-                            'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
662
-                            'event_espresso'
663
-                        ),
664
-                        $wp_table_name,
665
-                        '<br/>',
666
-                        'espresso_db_update'
667
-                    )
668
-                );
669
-            }
670
-        }
671
-        $engine = str_replace('ENGINE=', '', $engine);
672
-        \EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
673
-    }
674
-
675
-
676
-
677
-    /**
678
-     *    add_column_if_it_doesn't_exist
679
-     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
680
-     *
681
-     * @access     public
682
-     * @static
683
-     * @deprecated instead use TableManager::addColumn()
684
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
685
-     * @param string $column_name
686
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
687
-     *                            'VARCHAR(10)'
688
-     * @return bool|int
689
-     */
690
-    public static function add_column_if_it_doesnt_exist(
691
-        $table_name,
692
-        $column_name,
693
-        $column_info = 'INT UNSIGNED NOT NULL'
694
-    ) {
695
-        return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
696
-    }
697
-
698
-
699
-    /**
700
-     * get_fields_on_table
701
-     * Gets all the fields on the database table.
702
-     *
703
-     * @access     public
704
-     * @deprecated instead use TableManager::getTableColumns()
705
-     * @static
706
-     * @param string $table_name , without prefixed $wpdb->prefix
707
-     * @return array of database column names
708
-     */
709
-    public static function get_fields_on_table($table_name = null)
710
-    {
711
-        return \EEH_Activation::getTableManager()->getTableColumns($table_name);
712
-    }
713
-
714
-
715
-    /**
716
-     * db_table_is_empty
717
-     *
718
-     * @access     public\
719
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
720
-     * @static
721
-     * @param string $table_name
722
-     * @return bool
723
-     */
724
-    public static function db_table_is_empty($table_name)
725
-    {
726
-        return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
727
-    }
728
-
729
-
730
-    /**
731
-     * delete_db_table_if_empty
732
-     *
733
-     * @access public
734
-     * @static
735
-     * @param string $table_name
736
-     * @return bool | int
737
-     */
738
-    public static function delete_db_table_if_empty($table_name)
739
-    {
740
-        if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
741
-            return \EEH_Activation::getTableManager()->dropTable($table_name);
742
-        }
743
-        return false;
744
-    }
745
-
746
-
747
-    /**
748
-     * delete_unused_db_table
749
-     *
750
-     * @access     public
751
-     * @static
752
-     * @deprecated instead use TableManager::dropTable()
753
-     * @param string $table_name
754
-     * @return bool | int
755
-     */
756
-    public static function delete_unused_db_table($table_name)
757
-    {
758
-        return \EEH_Activation::getTableManager()->dropTable($table_name);
759
-    }
760
-
761
-
762
-    /**
763
-     * drop_index
764
-     *
765
-     * @access     public
766
-     * @static
767
-     * @deprecated instead use TableManager::dropIndex()
768
-     * @param string $table_name
769
-     * @param string $index_name
770
-     * @return bool | int
771
-     */
772
-    public static function drop_index($table_name, $index_name)
773
-    {
774
-        return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
775
-    }
776
-
777
-
778
-
779
-    /**
780
-     * create_database_tables
781
-     *
782
-     * @access public
783
-     * @static
784
-     * @throws EE_Error
785
-     * @return boolean success (whether database is setup properly or not)
786
-     */
787
-    public static function create_database_tables()
788
-    {
789
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
790
-        // find the migration script that sets the database to be compatible with the code
791
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
792
-        if ($dms_name) {
793
-            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
794
-            $current_data_migration_script->set_migrating(false);
795
-            $current_data_migration_script->schema_changes_before_migration();
796
-            $current_data_migration_script->schema_changes_after_migration();
797
-            if ($current_data_migration_script->get_errors()) {
798
-                if (WP_DEBUG) {
799
-                    foreach ($current_data_migration_script->get_errors() as $error) {
800
-                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
801
-                    }
802
-                } else {
803
-                    EE_Error::add_error(
804
-                        __(
805
-                            'There were errors creating the Event Espresso database tables and Event Espresso has been 
261
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
262
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
263
+			if (is_array($hooks_to_fire_at_time)) {
264
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
265
+					if (isset($ee_cron_tasks_to_remove[ $hook_name ])
266
+						&& is_array($ee_cron_tasks_to_remove[ $hook_name ])
267
+					) {
268
+						unset($crons[ $timestamp ][ $hook_name ]);
269
+					}
270
+				}
271
+				// also take care of any empty cron timestamps.
272
+				if (empty($hooks_to_fire_at_time)) {
273
+					unset($crons[ $timestamp ]);
274
+				}
275
+			}
276
+		}
277
+		_set_cron_array($crons);
278
+	}
279
+
280
+
281
+	/**
282
+	 *    CPT_initialization
283
+	 *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
284
+	 *
285
+	 * @access public
286
+	 * @static
287
+	 * @return void
288
+	 */
289
+	public static function CPT_initialization()
290
+	{
291
+		// register Custom Post Types
292
+		EE_Registry::instance()->load_core('Register_CPTs');
293
+		flush_rewrite_rules();
294
+	}
295
+
296
+
297
+
298
+	/**
299
+	 *    reset_and_update_config
300
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
301
+	 * If there is old calendar config data saved, then it will get converted on activation.
302
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
303
+	 *
304
+	 * @access public
305
+	 * @static
306
+	 * @return void
307
+	 */
308
+	public static function reset_and_update_config()
309
+	{
310
+		do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
311
+		add_filter(
312
+			'FHEE__EE_Config___load_core_config__config_settings',
313
+			array('EEH_Activation', 'migrate_old_config_data'),
314
+			10,
315
+			3
316
+		);
317
+		// EE_Config::reset();
318
+		if (! EE_Config::logging_enabled()) {
319
+			delete_option(EE_Config::LOG_NAME);
320
+		}
321
+	}
322
+
323
+
324
+	/**
325
+	 *    load_calendar_config
326
+	 *
327
+	 * @access    public
328
+	 * @return    void
329
+	 */
330
+	public static function load_calendar_config()
331
+	{
332
+		// grab array of all plugin folders and loop thru it
333
+		$plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
334
+		if (empty($plugins)) {
335
+			return;
336
+		}
337
+		foreach ($plugins as $plugin_path) {
338
+			// grab plugin folder name from path
339
+			$plugin = basename($plugin_path);
340
+			// drill down to Espresso plugins
341
+			// then to calendar related plugins
342
+			if (strpos($plugin, 'espresso') !== false
343
+				|| strpos($plugin, 'Espresso') !== false
344
+				|| strpos($plugin, 'ee4') !== false
345
+				|| strpos($plugin, 'EE4') !== false
346
+				|| strpos($plugin, 'calendar') !== false
347
+			) {
348
+				// this is what we are looking for
349
+				$calendar_config = $plugin_path . '/EE_Calendar_Config.php';
350
+				// does it exist in this folder ?
351
+				if (is_readable($calendar_config)) {
352
+					// YEAH! let's load it
353
+					require_once($calendar_config);
354
+				}
355
+			}
356
+		}
357
+	}
358
+
359
+
360
+
361
+	/**
362
+	 *    _migrate_old_config_data
363
+	 *
364
+	 * @access    public
365
+	 * @param array|stdClass $settings
366
+	 * @param string         $config
367
+	 * @param \EE_Config     $EE_Config
368
+	 * @return \stdClass
369
+	 */
370
+	public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
371
+	{
372
+		$convert_from_array = array('addons');
373
+		// in case old settings were saved as an array
374
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
375
+			// convert existing settings to an object
376
+			$config_array = $settings;
377
+			$settings = new stdClass();
378
+			foreach ($config_array as $key => $value) {
379
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
380
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
381
+				} else {
382
+					$settings->{$key} = $value;
383
+				}
384
+			}
385
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
386
+		}
387
+		return $settings;
388
+	}
389
+
390
+
391
+	/**
392
+	 * deactivate_event_espresso
393
+	 *
394
+	 * @access public
395
+	 * @static
396
+	 * @return void
397
+	 */
398
+	public static function deactivate_event_espresso()
399
+	{
400
+		// check permissions
401
+		if (current_user_can('activate_plugins')) {
402
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
403
+		}
404
+	}
405
+
406
+
407
+
408
+	/**
409
+	 * verify_default_pages_exist
410
+	 *
411
+	 * @access public
412
+	 * @static
413
+	 * @return void
414
+	 * @throws InvalidDataTypeException
415
+	 */
416
+	public static function verify_default_pages_exist()
417
+	{
418
+		$critical_page_problem = false;
419
+		$critical_pages = array(
420
+			array(
421
+				'id'   => 'reg_page_id',
422
+				'name' => __('Registration Checkout', 'event_espresso'),
423
+				'post' => null,
424
+				'code' => 'ESPRESSO_CHECKOUT',
425
+			),
426
+			array(
427
+				'id'   => 'txn_page_id',
428
+				'name' => __('Transactions', 'event_espresso'),
429
+				'post' => null,
430
+				'code' => 'ESPRESSO_TXN_PAGE',
431
+			),
432
+			array(
433
+				'id'   => 'thank_you_page_id',
434
+				'name' => __('Thank You', 'event_espresso'),
435
+				'post' => null,
436
+				'code' => 'ESPRESSO_THANK_YOU',
437
+			),
438
+			array(
439
+				'id'   => 'cancel_page_id',
440
+				'name' => __('Registration Cancelled', 'event_espresso'),
441
+				'post' => null,
442
+				'code' => 'ESPRESSO_CANCELLED',
443
+			),
444
+		);
445
+		$EE_Core_Config = EE_Registry::instance()->CFG->core;
446
+		foreach ($critical_pages as $critical_page) {
447
+			// is critical page ID set in config ?
448
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
449
+				// attempt to find post by ID
450
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
451
+			}
452
+			// no dice?
453
+			if ($critical_page['post'] === null) {
454
+				// attempt to find post by title
455
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
456
+				// still nothing?
457
+				if ($critical_page['post'] === null) {
458
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
459
+					// REALLY? Still nothing ??!?!?
460
+					if ($critical_page['post'] === null) {
461
+						$msg = __(
462
+							'The Event Espresso critical page configuration settings could not be updated.',
463
+							'event_espresso'
464
+						);
465
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
466
+						break;
467
+					}
468
+				}
469
+			}
470
+			// check that Post ID matches critical page ID in config
471
+			if (isset($critical_page['post']->ID)
472
+				&& $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
473
+			) {
474
+				// update Config with post ID
475
+				$EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
476
+				if (! EE_Config::instance()->update_espresso_config(false, false)) {
477
+					$msg = __(
478
+						'The Event Espresso critical page configuration settings could not be updated.',
479
+						'event_espresso'
480
+					);
481
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
482
+				}
483
+			}
484
+			$critical_page_problem =
485
+				! isset($critical_page['post']->post_status)
486
+				|| $critical_page['post']->post_status !== 'publish'
487
+				|| strpos($critical_page['post']->post_content, $critical_page['code']) === false
488
+					? true
489
+					: $critical_page_problem;
490
+		}
491
+		if ($critical_page_problem) {
492
+			new PersistentAdminNotice(
493
+				'critical_page_problem',
494
+				sprintf(
495
+					esc_html__(
496
+						'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
497
+						'event_espresso'
498
+					),
499
+					'<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
500
+					. __('Event Espresso Critical Pages Settings', 'event_espresso')
501
+					. '</a>'
502
+				)
503
+			);
504
+		}
505
+		if (EE_Error::has_notices()) {
506
+			EE_Error::get_notices(false, true, true);
507
+		}
508
+	}
509
+
510
+
511
+
512
+	/**
513
+	 * Returns the first post which uses the specified shortcode
514
+	 *
515
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
516
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
517
+	 *                             "[ESPRESSO_THANK_YOU"
518
+	 *                             (we don't search for the closing shortcode bracket because they might have added
519
+	 *                             parameter to the shortcode
520
+	 * @return WP_Post or NULl
521
+	 */
522
+	public static function get_page_by_ee_shortcode($ee_shortcode)
523
+	{
524
+		global $wpdb;
525
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
526
+		$post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
527
+		if ($post_id) {
528
+			return get_post($post_id);
529
+		} else {
530
+			return null;
531
+		}
532
+	}
533
+
534
+
535
+	/**
536
+	 *    This function generates a post for critical espresso pages
537
+	 *
538
+	 * @access public
539
+	 * @static
540
+	 * @param array $critical_page
541
+	 * @return array
542
+	 */
543
+	public static function create_critical_page($critical_page)
544
+	{
545
+
546
+		$post_args = array(
547
+			'post_title'     => $critical_page['name'],
548
+			'post_status'    => 'publish',
549
+			'post_type'      => 'page',
550
+			'comment_status' => 'closed',
551
+			'post_content'   => '[' . $critical_page['code'] . ']',
552
+		);
553
+
554
+		$post_id = wp_insert_post($post_args);
555
+		if (! $post_id) {
556
+			$msg = sprintf(
557
+				__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
558
+				$critical_page['name']
559
+			);
560
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
561
+			return $critical_page;
562
+		}
563
+		// get newly created post's details
564
+		if (! $critical_page['post'] = get_post($post_id)) {
565
+			$msg = sprintf(
566
+				__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
567
+				$critical_page['name']
568
+			);
569
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
570
+		}
571
+
572
+		return $critical_page;
573
+	}
574
+
575
+
576
+
577
+
578
+	/**
579
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
580
+	 * The role being used to check is filterable.
581
+	 *
582
+	 * @since  4.6.0
583
+	 * @global WPDB $wpdb
584
+	 * @return mixed null|int WP_user ID or NULL
585
+	 */
586
+	public static function get_default_creator_id()
587
+	{
588
+		global $wpdb;
589
+		if (! empty(self::$_default_creator_id)) {
590
+			return self::$_default_creator_id;
591
+		}/**/
592
+		$role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
593
+		// let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
594
+		$pre_filtered_id = apply_filters(
595
+			'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
596
+			false,
597
+			$role_to_check
598
+		);
599
+		if ($pre_filtered_id !== false) {
600
+			return (int) $pre_filtered_id;
601
+		}
602
+		$capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
603
+		$query = $wpdb->prepare(
604
+			"SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
605
+			'%' . $role_to_check . '%'
606
+		);
607
+		$user_id = $wpdb->get_var($query);
608
+		$user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
609
+		if ($user_id && (int) $user_id) {
610
+			self::$_default_creator_id = (int) $user_id;
611
+			return self::$_default_creator_id;
612
+		} else {
613
+			return null;
614
+		}
615
+	}
616
+
617
+
618
+
619
+	/**
620
+	 * used by EE and EE addons during plugin activation to create tables.
621
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
622
+	 * but includes extra logic regarding activations.
623
+	 *
624
+	 * @access public
625
+	 * @static
626
+	 * @param string  $table_name              without the $wpdb->prefix
627
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
628
+	 *                                         table query)
629
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
630
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
631
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
632
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
633
+	 *                                         you just want to verify the table exists and matches this definition
634
+	 *                                         (and if it HAS data in it you want to leave it be)
635
+	 * @return void
636
+	 * @throws EE_Error if there are database errors
637
+	 */
638
+	public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
639
+	{
640
+		if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
641
+			return;
642
+		}
643
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
644
+		if (! function_exists('dbDelta')) {
645
+			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
646
+		}
647
+		$tableAnalysis = \EEH_Activation::getTableAnalysis();
648
+		$wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
649
+		// do we need to first delete an existing version of this table ?
650
+		if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
651
+			// ok, delete the table... but ONLY if it's empty
652
+			$deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
653
+			// table is NOT empty, are you SURE you want to delete this table ???
654
+			if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
655
+				\EEH_Activation::getTableManager()->dropTable($wp_table_name);
656
+			} elseif (! $deleted_safely) {
657
+				// so we should be more cautious rather than just dropping tables so easily
658
+				error_log(
659
+					sprintf(
660
+						__(
661
+							'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
662
+							'event_espresso'
663
+						),
664
+						$wp_table_name,
665
+						'<br/>',
666
+						'espresso_db_update'
667
+					)
668
+				);
669
+			}
670
+		}
671
+		$engine = str_replace('ENGINE=', '', $engine);
672
+		\EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
673
+	}
674
+
675
+
676
+
677
+	/**
678
+	 *    add_column_if_it_doesn't_exist
679
+	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
680
+	 *
681
+	 * @access     public
682
+	 * @static
683
+	 * @deprecated instead use TableManager::addColumn()
684
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
685
+	 * @param string $column_name
686
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
687
+	 *                            'VARCHAR(10)'
688
+	 * @return bool|int
689
+	 */
690
+	public static function add_column_if_it_doesnt_exist(
691
+		$table_name,
692
+		$column_name,
693
+		$column_info = 'INT UNSIGNED NOT NULL'
694
+	) {
695
+		return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
696
+	}
697
+
698
+
699
+	/**
700
+	 * get_fields_on_table
701
+	 * Gets all the fields on the database table.
702
+	 *
703
+	 * @access     public
704
+	 * @deprecated instead use TableManager::getTableColumns()
705
+	 * @static
706
+	 * @param string $table_name , without prefixed $wpdb->prefix
707
+	 * @return array of database column names
708
+	 */
709
+	public static function get_fields_on_table($table_name = null)
710
+	{
711
+		return \EEH_Activation::getTableManager()->getTableColumns($table_name);
712
+	}
713
+
714
+
715
+	/**
716
+	 * db_table_is_empty
717
+	 *
718
+	 * @access     public\
719
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
720
+	 * @static
721
+	 * @param string $table_name
722
+	 * @return bool
723
+	 */
724
+	public static function db_table_is_empty($table_name)
725
+	{
726
+		return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
727
+	}
728
+
729
+
730
+	/**
731
+	 * delete_db_table_if_empty
732
+	 *
733
+	 * @access public
734
+	 * @static
735
+	 * @param string $table_name
736
+	 * @return bool | int
737
+	 */
738
+	public static function delete_db_table_if_empty($table_name)
739
+	{
740
+		if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
741
+			return \EEH_Activation::getTableManager()->dropTable($table_name);
742
+		}
743
+		return false;
744
+	}
745
+
746
+
747
+	/**
748
+	 * delete_unused_db_table
749
+	 *
750
+	 * @access     public
751
+	 * @static
752
+	 * @deprecated instead use TableManager::dropTable()
753
+	 * @param string $table_name
754
+	 * @return bool | int
755
+	 */
756
+	public static function delete_unused_db_table($table_name)
757
+	{
758
+		return \EEH_Activation::getTableManager()->dropTable($table_name);
759
+	}
760
+
761
+
762
+	/**
763
+	 * drop_index
764
+	 *
765
+	 * @access     public
766
+	 * @static
767
+	 * @deprecated instead use TableManager::dropIndex()
768
+	 * @param string $table_name
769
+	 * @param string $index_name
770
+	 * @return bool | int
771
+	 */
772
+	public static function drop_index($table_name, $index_name)
773
+	{
774
+		return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
775
+	}
776
+
777
+
778
+
779
+	/**
780
+	 * create_database_tables
781
+	 *
782
+	 * @access public
783
+	 * @static
784
+	 * @throws EE_Error
785
+	 * @return boolean success (whether database is setup properly or not)
786
+	 */
787
+	public static function create_database_tables()
788
+	{
789
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
790
+		// find the migration script that sets the database to be compatible with the code
791
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
792
+		if ($dms_name) {
793
+			$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
794
+			$current_data_migration_script->set_migrating(false);
795
+			$current_data_migration_script->schema_changes_before_migration();
796
+			$current_data_migration_script->schema_changes_after_migration();
797
+			if ($current_data_migration_script->get_errors()) {
798
+				if (WP_DEBUG) {
799
+					foreach ($current_data_migration_script->get_errors() as $error) {
800
+						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
801
+					}
802
+				} else {
803
+					EE_Error::add_error(
804
+						__(
805
+							'There were errors creating the Event Espresso database tables and Event Espresso has been 
806 806
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
807
-                            'event_espresso'
808
-                        )
809
-                    );
810
-                }
811
-                return false;
812
-            }
813
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
814
-        } else {
815
-            EE_Error::add_error(
816
-                __(
817
-                    'Could not determine most up-to-date data migration script from which to pull database schema
807
+							'event_espresso'
808
+						)
809
+					);
810
+				}
811
+				return false;
812
+			}
813
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
814
+		} else {
815
+			EE_Error::add_error(
816
+				__(
817
+					'Could not determine most up-to-date data migration script from which to pull database schema
818 818
                      structure. So database is probably not setup properly',
819
-                    'event_espresso'
820
-                ),
821
-                __FILE__,
822
-                __FUNCTION__,
823
-                __LINE__
824
-            );
825
-            return false;
826
-        }
827
-        return true;
828
-    }
829
-
830
-
831
-
832
-    /**
833
-     * initialize_system_questions
834
-     *
835
-     * @access public
836
-     * @static
837
-     * @return void
838
-     */
839
-    public static function initialize_system_questions()
840
-    {
841
-        // QUESTION GROUPS
842
-        global $wpdb;
843
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
844
-        $SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
845
-        // what we have
846
-        $question_groups = $wpdb->get_col($SQL);
847
-        // check the response
848
-        $question_groups = is_array($question_groups) ? $question_groups : array();
849
-        // what we should have
850
-        $QSG_systems = array(1, 2);
851
-        // loop thru what we should have and compare to what we have
852
-        foreach ($QSG_systems as $QSG_system) {
853
-            // reset values array
854
-            $QSG_values = array();
855
-            // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
856
-            if (! in_array("$QSG_system", $question_groups)) {
857
-                // add it
858
-                switch ($QSG_system) {
859
-                    case 1:
860
-                        $QSG_values = array(
861
-                            'QSG_name'            => __('Personal Information', 'event_espresso'),
862
-                            'QSG_identifier'      => 'personal-information-' . time(),
863
-                            'QSG_desc'            => '',
864
-                            'QSG_order'           => 1,
865
-                            'QSG_show_group_name' => 1,
866
-                            'QSG_show_group_desc' => 1,
867
-                            'QSG_system'          => EEM_Question_Group::system_personal,
868
-                            'QSG_deleted'         => 0,
869
-                        );
870
-                        break;
871
-                    case 2:
872
-                        $QSG_values = array(
873
-                            'QSG_name'            => __('Address Information', 'event_espresso'),
874
-                            'QSG_identifier'      => 'address-information-' . time(),
875
-                            'QSG_desc'            => '',
876
-                            'QSG_order'           => 2,
877
-                            'QSG_show_group_name' => 1,
878
-                            'QSG_show_group_desc' => 1,
879
-                            'QSG_system'          => EEM_Question_Group::system_address,
880
-                            'QSG_deleted'         => 0,
881
-                        );
882
-                        break;
883
-                }
884
-                // make sure we have some values before inserting them
885
-                if (! empty($QSG_values)) {
886
-                    // insert system question
887
-                    $wpdb->insert(
888
-                        $table_name,
889
-                        $QSG_values,
890
-                        array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
891
-                    );
892
-                    $QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
893
-                }
894
-            }
895
-        }
896
-        // QUESTIONS
897
-        global $wpdb;
898
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
899
-        $SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
900
-        // what we have
901
-        $questions = $wpdb->get_col($SQL);
902
-        // all system questions
903
-        $personal_system_group_questions = ['fname', 'lname', 'email'];
904
-        $address_system_group_questions = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
905
-        $system_questions_not_in_group = ['email_confirm'];
906
-        // merge all of the system questions we should have
907
-        $QST_systems = array_merge(
908
-            $personal_system_group_questions,
909
-            $address_system_group_questions,
910
-            $system_questions_not_in_group
911
-        );
912
-        $order_for_group_1 = 1;
913
-        $order_for_group_2 = 1;
914
-        // loop thru what we should have and compare to what we have
915
-        foreach ($QST_systems as $QST_system) {
916
-            // reset values array
917
-            $QST_values = array();
918
-            // if we don't have what we should have
919
-            if (! in_array($QST_system, $questions)) {
920
-                // add it
921
-                switch ($QST_system) {
922
-                    case 'fname':
923
-                        $QST_values = array(
924
-                            'QST_display_text'  => __('First Name', 'event_espresso'),
925
-                            'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
926
-                            'QST_system'        => 'fname',
927
-                            'QST_type'          => 'TEXT',
928
-                            'QST_required'      => 1,
929
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
930
-                            'QST_order'         => 1,
931
-                            'QST_admin_only'    => 0,
932
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
933
-                            'QST_wp_user'       => self::get_default_creator_id(),
934
-                            'QST_deleted'       => 0,
935
-                        );
936
-                        break;
937
-                    case 'lname':
938
-                        $QST_values = array(
939
-                            'QST_display_text'  => __('Last Name', 'event_espresso'),
940
-                            'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
941
-                            'QST_system'        => 'lname',
942
-                            'QST_type'          => 'TEXT',
943
-                            'QST_required'      => 1,
944
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
945
-                            'QST_order'         => 2,
946
-                            'QST_admin_only'    => 0,
947
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
948
-                            'QST_wp_user'       => self::get_default_creator_id(),
949
-                            'QST_deleted'       => 0,
950
-                        );
951
-                        break;
952
-                    case 'email':
953
-                        $QST_values = array(
954
-                            'QST_display_text'  => __('Email Address', 'event_espresso'),
955
-                            'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
956
-                            'QST_system'        => 'email',
957
-                            'QST_type'          => 'EMAIL',
958
-                            'QST_required'      => 1,
959
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
960
-                            'QST_order'         => 3,
961
-                            'QST_admin_only'    => 0,
962
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
963
-                            'QST_wp_user'       => self::get_default_creator_id(),
964
-                            'QST_deleted'       => 0,
965
-                        );
966
-                        break;
967
-                    case 'email_confirm':
968
-                        $QST_values = array(
969
-                            'QST_display_text'  => __('Confirm Email Address', 'event_espresso'),
970
-                            'QST_admin_label'   => __('Confirm Email Address - System Question', 'event_espresso'),
971
-                            'QST_system'        => 'email_confirm',
972
-                            'QST_type'          => 'EMAIL_CONFIRM',
973
-                            'QST_required'      => 1,
974
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
975
-                            'QST_order'         => 4,
976
-                            'QST_admin_only'    => 0,
977
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
978
-                            'QST_wp_user'       => self::get_default_creator_id(),
979
-                            'QST_deleted'       => 0,
980
-                        );
981
-                        break;
982
-                    case 'address':
983
-                        $QST_values = array(
984
-                            'QST_display_text'  => __('Address', 'event_espresso'),
985
-                            'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
986
-                            'QST_system'        => 'address',
987
-                            'QST_type'          => 'TEXT',
988
-                            'QST_required'      => 0,
989
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
990
-                            'QST_order'         => 5,
991
-                            'QST_admin_only'    => 0,
992
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
993
-                            'QST_wp_user'       => self::get_default_creator_id(),
994
-                            'QST_deleted'       => 0,
995
-                        );
996
-                        break;
997
-                    case 'address2':
998
-                        $QST_values = array(
999
-                            'QST_display_text'  => __('Address2', 'event_espresso'),
1000
-                            'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1001
-                            'QST_system'        => 'address2',
1002
-                            'QST_type'          => 'TEXT',
1003
-                            'QST_required'      => 0,
1004
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1005
-                            'QST_order'         => 6,
1006
-                            'QST_admin_only'    => 0,
1007
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1008
-                            'QST_wp_user'       => self::get_default_creator_id(),
1009
-                            'QST_deleted'       => 0,
1010
-                        );
1011
-                        break;
1012
-                    case 'city':
1013
-                        $QST_values = array(
1014
-                            'QST_display_text'  => __('City', 'event_espresso'),
1015
-                            'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1016
-                            'QST_system'        => 'city',
1017
-                            'QST_type'          => 'TEXT',
1018
-                            'QST_required'      => 0,
1019
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1020
-                            'QST_order'         => 7,
1021
-                            'QST_admin_only'    => 0,
1022
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1023
-                            'QST_wp_user'       => self::get_default_creator_id(),
1024
-                            'QST_deleted'       => 0,
1025
-                        );
1026
-                        break;
1027
-                    case 'country':
1028
-                        $QST_values = array(
1029
-                            'QST_display_text'  => __('Country', 'event_espresso'),
1030
-                            'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1031
-                            'QST_system'        => 'country',
1032
-                            'QST_type'          => 'COUNTRY',
1033
-                            'QST_required'      => 0,
1034
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1035
-                            'QST_order'         => 8,
1036
-                            'QST_admin_only'    => 0,
1037
-                            'QST_wp_user'       => self::get_default_creator_id(),
1038
-                            'QST_deleted'       => 0,
1039
-                        );
1040
-                        break;
1041
-                    case 'state':
1042
-                        $QST_values = array(
1043
-                            'QST_display_text'  => __('State/Province', 'event_espresso'),
1044
-                            'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1045
-                            'QST_system'        => 'state',
1046
-                            'QST_type'          => 'STATE',
1047
-                            'QST_required'      => 0,
1048
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1049
-                            'QST_order'         => 9,
1050
-                            'QST_admin_only'    => 0,
1051
-                            'QST_wp_user'       => self::get_default_creator_id(),
1052
-                            'QST_deleted'       => 0,
1053
-                        );
1054
-                        break;
1055
-                    case 'zip':
1056
-                        $QST_values = array(
1057
-                            'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1058
-                            'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1059
-                            'QST_system'        => 'zip',
1060
-                            'QST_type'          => 'TEXT',
1061
-                            'QST_required'      => 0,
1062
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1063
-                            'QST_order'         => 10,
1064
-                            'QST_admin_only'    => 0,
1065
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1066
-                            'QST_wp_user'       => self::get_default_creator_id(),
1067
-                            'QST_deleted'       => 0,
1068
-                        );
1069
-                        break;
1070
-                    case 'phone':
1071
-                        $QST_values = array(
1072
-                            'QST_display_text'  => __('Phone Number', 'event_espresso'),
1073
-                            'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1074
-                            'QST_system'        => 'phone',
1075
-                            'QST_type'          => 'TEXT',
1076
-                            'QST_required'      => 0,
1077
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1078
-                            'QST_order'         => 11,
1079
-                            'QST_admin_only'    => 0,
1080
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1081
-                            'QST_wp_user'       => self::get_default_creator_id(),
1082
-                            'QST_deleted'       => 0,
1083
-                        );
1084
-                        break;
1085
-                }
1086
-                if (! empty($QST_values)) {
1087
-                    // insert system question
1088
-                    $wpdb->insert(
1089
-                        $table_name,
1090
-                        $QST_values,
1091
-                        array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1092
-                    );
1093
-                    $QST_ID = $wpdb->insert_id;
1094
-
1095
-                    // QUESTION GROUP QUESTIONS
1096
-                    if (in_array($QST_system, $personal_system_group_questions)) {
1097
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1098
-                    } elseif (in_array($QST_system, $address_system_group_questions)) {
1099
-                        $system_question_we_want = EEM_Question_Group::system_address;
1100
-                    } else {
1101
-                        // QST_system should not be assigned to any group
1102
-                        continue;
1103
-                    }
1104
-                    if (isset($QSG_IDs[ $system_question_we_want ])) {
1105
-                        $QSG_ID = $QSG_IDs[ $system_question_we_want ];
1106
-                    } else {
1107
-                        $id_col = EEM_Question_Group::instance()
1108
-                                                    ->get_col(array(array('QSG_system' => $system_question_we_want)));
1109
-                        if (is_array($id_col)) {
1110
-                            $QSG_ID = reset($id_col);
1111
-                        } else {
1112
-                            // ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1113
-                            EE_Log::instance()->log(
1114
-                                __FILE__,
1115
-                                __FUNCTION__,
1116
-                                sprintf(
1117
-                                    __(
1118
-                                        'Could not associate question %1$s to a question group because no system question
819
+					'event_espresso'
820
+				),
821
+				__FILE__,
822
+				__FUNCTION__,
823
+				__LINE__
824
+			);
825
+			return false;
826
+		}
827
+		return true;
828
+	}
829
+
830
+
831
+
832
+	/**
833
+	 * initialize_system_questions
834
+	 *
835
+	 * @access public
836
+	 * @static
837
+	 * @return void
838
+	 */
839
+	public static function initialize_system_questions()
840
+	{
841
+		// QUESTION GROUPS
842
+		global $wpdb;
843
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
844
+		$SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
845
+		// what we have
846
+		$question_groups = $wpdb->get_col($SQL);
847
+		// check the response
848
+		$question_groups = is_array($question_groups) ? $question_groups : array();
849
+		// what we should have
850
+		$QSG_systems = array(1, 2);
851
+		// loop thru what we should have and compare to what we have
852
+		foreach ($QSG_systems as $QSG_system) {
853
+			// reset values array
854
+			$QSG_values = array();
855
+			// if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
856
+			if (! in_array("$QSG_system", $question_groups)) {
857
+				// add it
858
+				switch ($QSG_system) {
859
+					case 1:
860
+						$QSG_values = array(
861
+							'QSG_name'            => __('Personal Information', 'event_espresso'),
862
+							'QSG_identifier'      => 'personal-information-' . time(),
863
+							'QSG_desc'            => '',
864
+							'QSG_order'           => 1,
865
+							'QSG_show_group_name' => 1,
866
+							'QSG_show_group_desc' => 1,
867
+							'QSG_system'          => EEM_Question_Group::system_personal,
868
+							'QSG_deleted'         => 0,
869
+						);
870
+						break;
871
+					case 2:
872
+						$QSG_values = array(
873
+							'QSG_name'            => __('Address Information', 'event_espresso'),
874
+							'QSG_identifier'      => 'address-information-' . time(),
875
+							'QSG_desc'            => '',
876
+							'QSG_order'           => 2,
877
+							'QSG_show_group_name' => 1,
878
+							'QSG_show_group_desc' => 1,
879
+							'QSG_system'          => EEM_Question_Group::system_address,
880
+							'QSG_deleted'         => 0,
881
+						);
882
+						break;
883
+				}
884
+				// make sure we have some values before inserting them
885
+				if (! empty($QSG_values)) {
886
+					// insert system question
887
+					$wpdb->insert(
888
+						$table_name,
889
+						$QSG_values,
890
+						array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
891
+					);
892
+					$QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
893
+				}
894
+			}
895
+		}
896
+		// QUESTIONS
897
+		global $wpdb;
898
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
899
+		$SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
900
+		// what we have
901
+		$questions = $wpdb->get_col($SQL);
902
+		// all system questions
903
+		$personal_system_group_questions = ['fname', 'lname', 'email'];
904
+		$address_system_group_questions = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
905
+		$system_questions_not_in_group = ['email_confirm'];
906
+		// merge all of the system questions we should have
907
+		$QST_systems = array_merge(
908
+			$personal_system_group_questions,
909
+			$address_system_group_questions,
910
+			$system_questions_not_in_group
911
+		);
912
+		$order_for_group_1 = 1;
913
+		$order_for_group_2 = 1;
914
+		// loop thru what we should have and compare to what we have
915
+		foreach ($QST_systems as $QST_system) {
916
+			// reset values array
917
+			$QST_values = array();
918
+			// if we don't have what we should have
919
+			if (! in_array($QST_system, $questions)) {
920
+				// add it
921
+				switch ($QST_system) {
922
+					case 'fname':
923
+						$QST_values = array(
924
+							'QST_display_text'  => __('First Name', 'event_espresso'),
925
+							'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
926
+							'QST_system'        => 'fname',
927
+							'QST_type'          => 'TEXT',
928
+							'QST_required'      => 1,
929
+							'QST_required_text' => __('This field is required', 'event_espresso'),
930
+							'QST_order'         => 1,
931
+							'QST_admin_only'    => 0,
932
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
933
+							'QST_wp_user'       => self::get_default_creator_id(),
934
+							'QST_deleted'       => 0,
935
+						);
936
+						break;
937
+					case 'lname':
938
+						$QST_values = array(
939
+							'QST_display_text'  => __('Last Name', 'event_espresso'),
940
+							'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
941
+							'QST_system'        => 'lname',
942
+							'QST_type'          => 'TEXT',
943
+							'QST_required'      => 1,
944
+							'QST_required_text' => __('This field is required', 'event_espresso'),
945
+							'QST_order'         => 2,
946
+							'QST_admin_only'    => 0,
947
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
948
+							'QST_wp_user'       => self::get_default_creator_id(),
949
+							'QST_deleted'       => 0,
950
+						);
951
+						break;
952
+					case 'email':
953
+						$QST_values = array(
954
+							'QST_display_text'  => __('Email Address', 'event_espresso'),
955
+							'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
956
+							'QST_system'        => 'email',
957
+							'QST_type'          => 'EMAIL',
958
+							'QST_required'      => 1,
959
+							'QST_required_text' => __('This field is required', 'event_espresso'),
960
+							'QST_order'         => 3,
961
+							'QST_admin_only'    => 0,
962
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
963
+							'QST_wp_user'       => self::get_default_creator_id(),
964
+							'QST_deleted'       => 0,
965
+						);
966
+						break;
967
+					case 'email_confirm':
968
+						$QST_values = array(
969
+							'QST_display_text'  => __('Confirm Email Address', 'event_espresso'),
970
+							'QST_admin_label'   => __('Confirm Email Address - System Question', 'event_espresso'),
971
+							'QST_system'        => 'email_confirm',
972
+							'QST_type'          => 'EMAIL_CONFIRM',
973
+							'QST_required'      => 1,
974
+							'QST_required_text' => __('This field is required', 'event_espresso'),
975
+							'QST_order'         => 4,
976
+							'QST_admin_only'    => 0,
977
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
978
+							'QST_wp_user'       => self::get_default_creator_id(),
979
+							'QST_deleted'       => 0,
980
+						);
981
+						break;
982
+					case 'address':
983
+						$QST_values = array(
984
+							'QST_display_text'  => __('Address', 'event_espresso'),
985
+							'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
986
+							'QST_system'        => 'address',
987
+							'QST_type'          => 'TEXT',
988
+							'QST_required'      => 0,
989
+							'QST_required_text' => __('This field is required', 'event_espresso'),
990
+							'QST_order'         => 5,
991
+							'QST_admin_only'    => 0,
992
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
993
+							'QST_wp_user'       => self::get_default_creator_id(),
994
+							'QST_deleted'       => 0,
995
+						);
996
+						break;
997
+					case 'address2':
998
+						$QST_values = array(
999
+							'QST_display_text'  => __('Address2', 'event_espresso'),
1000
+							'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1001
+							'QST_system'        => 'address2',
1002
+							'QST_type'          => 'TEXT',
1003
+							'QST_required'      => 0,
1004
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1005
+							'QST_order'         => 6,
1006
+							'QST_admin_only'    => 0,
1007
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1008
+							'QST_wp_user'       => self::get_default_creator_id(),
1009
+							'QST_deleted'       => 0,
1010
+						);
1011
+						break;
1012
+					case 'city':
1013
+						$QST_values = array(
1014
+							'QST_display_text'  => __('City', 'event_espresso'),
1015
+							'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1016
+							'QST_system'        => 'city',
1017
+							'QST_type'          => 'TEXT',
1018
+							'QST_required'      => 0,
1019
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1020
+							'QST_order'         => 7,
1021
+							'QST_admin_only'    => 0,
1022
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1023
+							'QST_wp_user'       => self::get_default_creator_id(),
1024
+							'QST_deleted'       => 0,
1025
+						);
1026
+						break;
1027
+					case 'country':
1028
+						$QST_values = array(
1029
+							'QST_display_text'  => __('Country', 'event_espresso'),
1030
+							'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1031
+							'QST_system'        => 'country',
1032
+							'QST_type'          => 'COUNTRY',
1033
+							'QST_required'      => 0,
1034
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1035
+							'QST_order'         => 8,
1036
+							'QST_admin_only'    => 0,
1037
+							'QST_wp_user'       => self::get_default_creator_id(),
1038
+							'QST_deleted'       => 0,
1039
+						);
1040
+						break;
1041
+					case 'state':
1042
+						$QST_values = array(
1043
+							'QST_display_text'  => __('State/Province', 'event_espresso'),
1044
+							'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1045
+							'QST_system'        => 'state',
1046
+							'QST_type'          => 'STATE',
1047
+							'QST_required'      => 0,
1048
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1049
+							'QST_order'         => 9,
1050
+							'QST_admin_only'    => 0,
1051
+							'QST_wp_user'       => self::get_default_creator_id(),
1052
+							'QST_deleted'       => 0,
1053
+						);
1054
+						break;
1055
+					case 'zip':
1056
+						$QST_values = array(
1057
+							'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1058
+							'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1059
+							'QST_system'        => 'zip',
1060
+							'QST_type'          => 'TEXT',
1061
+							'QST_required'      => 0,
1062
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1063
+							'QST_order'         => 10,
1064
+							'QST_admin_only'    => 0,
1065
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1066
+							'QST_wp_user'       => self::get_default_creator_id(),
1067
+							'QST_deleted'       => 0,
1068
+						);
1069
+						break;
1070
+					case 'phone':
1071
+						$QST_values = array(
1072
+							'QST_display_text'  => __('Phone Number', 'event_espresso'),
1073
+							'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1074
+							'QST_system'        => 'phone',
1075
+							'QST_type'          => 'TEXT',
1076
+							'QST_required'      => 0,
1077
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1078
+							'QST_order'         => 11,
1079
+							'QST_admin_only'    => 0,
1080
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1081
+							'QST_wp_user'       => self::get_default_creator_id(),
1082
+							'QST_deleted'       => 0,
1083
+						);
1084
+						break;
1085
+				}
1086
+				if (! empty($QST_values)) {
1087
+					// insert system question
1088
+					$wpdb->insert(
1089
+						$table_name,
1090
+						$QST_values,
1091
+						array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1092
+					);
1093
+					$QST_ID = $wpdb->insert_id;
1094
+
1095
+					// QUESTION GROUP QUESTIONS
1096
+					if (in_array($QST_system, $personal_system_group_questions)) {
1097
+						$system_question_we_want = EEM_Question_Group::system_personal;
1098
+					} elseif (in_array($QST_system, $address_system_group_questions)) {
1099
+						$system_question_we_want = EEM_Question_Group::system_address;
1100
+					} else {
1101
+						// QST_system should not be assigned to any group
1102
+						continue;
1103
+					}
1104
+					if (isset($QSG_IDs[ $system_question_we_want ])) {
1105
+						$QSG_ID = $QSG_IDs[ $system_question_we_want ];
1106
+					} else {
1107
+						$id_col = EEM_Question_Group::instance()
1108
+													->get_col(array(array('QSG_system' => $system_question_we_want)));
1109
+						if (is_array($id_col)) {
1110
+							$QSG_ID = reset($id_col);
1111
+						} else {
1112
+							// ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1113
+							EE_Log::instance()->log(
1114
+								__FILE__,
1115
+								__FUNCTION__,
1116
+								sprintf(
1117
+									__(
1118
+										'Could not associate question %1$s to a question group because no system question
1119 1119
                                          group existed',
1120
-                                        'event_espresso'
1121
-                                    ),
1122
-                                    $QST_ID
1123
-                                ),
1124
-                                'error'
1125
-                            );
1126
-                            continue;
1127
-                        }
1128
-                    }
1129
-                    // add system questions to groups
1130
-                    $wpdb->insert(
1131
-                        \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1132
-                        array(
1133
-                            'QSG_ID'    => $QSG_ID,
1134
-                            'QST_ID'    => $QST_ID,
1135
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1136
-                        ),
1137
-                        array('%d', '%d', '%d')
1138
-                    );
1139
-                }
1140
-            }
1141
-        }
1142
-    }
1143
-
1144
-
1145
-    /**
1146
-     * Makes sure the default payment method (Invoice) is active.
1147
-     * This used to be done automatically as part of constructing the old gateways config
1148
-     *
1149
-     * @throws \EE_Error
1150
-     */
1151
-    public static function insert_default_payment_methods()
1152
-    {
1153
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1154
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1155
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1156
-        } else {
1157
-            EEM_Payment_Method::instance()->verify_button_urls();
1158
-        }
1159
-    }
1160
-
1161
-    /**
1162
-     * insert_default_status_codes
1163
-     *
1164
-     * @access public
1165
-     * @static
1166
-     * @return void
1167
-     */
1168
-    public static function insert_default_status_codes()
1169
-    {
1170
-
1171
-        global $wpdb;
1172
-
1173
-        if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1174
-            $table_name = EEM_Status::instance()->table();
1175
-
1176
-            $SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1177
-            $wpdb->query($SQL);
1178
-
1179
-            $SQL = "INSERT INTO $table_name
1120
+										'event_espresso'
1121
+									),
1122
+									$QST_ID
1123
+								),
1124
+								'error'
1125
+							);
1126
+							continue;
1127
+						}
1128
+					}
1129
+					// add system questions to groups
1130
+					$wpdb->insert(
1131
+						\EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1132
+						array(
1133
+							'QSG_ID'    => $QSG_ID,
1134
+							'QST_ID'    => $QST_ID,
1135
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1136
+						),
1137
+						array('%d', '%d', '%d')
1138
+					);
1139
+				}
1140
+			}
1141
+		}
1142
+	}
1143
+
1144
+
1145
+	/**
1146
+	 * Makes sure the default payment method (Invoice) is active.
1147
+	 * This used to be done automatically as part of constructing the old gateways config
1148
+	 *
1149
+	 * @throws \EE_Error
1150
+	 */
1151
+	public static function insert_default_payment_methods()
1152
+	{
1153
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1154
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1155
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1156
+		} else {
1157
+			EEM_Payment_Method::instance()->verify_button_urls();
1158
+		}
1159
+	}
1160
+
1161
+	/**
1162
+	 * insert_default_status_codes
1163
+	 *
1164
+	 * @access public
1165
+	 * @static
1166
+	 * @return void
1167
+	 */
1168
+	public static function insert_default_status_codes()
1169
+	{
1170
+
1171
+		global $wpdb;
1172
+
1173
+		if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1174
+			$table_name = EEM_Status::instance()->table();
1175
+
1176
+			$SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1177
+			$wpdb->query($SQL);
1178
+
1179
+			$SQL = "INSERT INTO $table_name
1180 1180
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1181 1181
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1182 1182
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1216,479 +1216,479 @@  discard block
 block discarded – undo
1216 1216
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1217 1217
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1218 1218
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1219
-            $wpdb->query($SQL);
1220
-        }
1221
-    }
1222
-
1223
-
1224
-    /**
1225
-     * generate_default_message_templates
1226
-     *
1227
-     * @static
1228
-     * @throws EE_Error
1229
-     * @return bool     true means new templates were created.
1230
-     *                  false means no templates were created.
1231
-     *                  This is NOT an error flag. To check for errors you will want
1232
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1233
-     */
1234
-    public static function generate_default_message_templates()
1235
-    {
1236
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1237
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1238
-        /*
1219
+			$wpdb->query($SQL);
1220
+		}
1221
+	}
1222
+
1223
+
1224
+	/**
1225
+	 * generate_default_message_templates
1226
+	 *
1227
+	 * @static
1228
+	 * @throws EE_Error
1229
+	 * @return bool     true means new templates were created.
1230
+	 *                  false means no templates were created.
1231
+	 *                  This is NOT an error flag. To check for errors you will want
1232
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1233
+	 */
1234
+	public static function generate_default_message_templates()
1235
+	{
1236
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1237
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1238
+		/*
1239 1239
          * This first method is taking care of ensuring any default messengers
1240 1240
          * that should be made active and have templates generated are done.
1241 1241
          */
1242
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1243
-            $message_resource_manager
1244
-        );
1245
-        /**
1246
-         * This method is verifying there are no NEW default message types
1247
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1248
-         */
1249
-        $new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1250
-            $message_resource_manager
1251
-        );
1252
-        // after all is done, let's persist these changes to the db.
1253
-        $message_resource_manager->update_has_activated_messengers_option();
1254
-        $message_resource_manager->update_active_messengers_option();
1255
-        // will return true if either of these are true.  Otherwise will return false.
1256
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1257
-    }
1258
-
1259
-
1260
-
1261
-    /**
1262
-     * @param \EE_Message_Resource_Manager $message_resource_manager
1263
-     * @return array|bool
1264
-     * @throws \EE_Error
1265
-     */
1266
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1267
-        EE_Message_Resource_Manager $message_resource_manager
1268
-    ) {
1269
-        /** @type EE_messenger[] $active_messengers */
1270
-        $active_messengers = $message_resource_manager->active_messengers();
1271
-        $installed_message_types = $message_resource_manager->installed_message_types();
1272
-        $templates_created = false;
1273
-        foreach ($active_messengers as $active_messenger) {
1274
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1275
-            $default_message_type_names_to_activate = array();
1276
-            // looping through each default message type reported by the messenger
1277
-            // and setup the actual message types to activate.
1278
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1279
-                // if already active or has already been activated before we skip
1280
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1281
-                // we also skip if the message type is not installed.
1282
-                if ($message_resource_manager->has_message_type_been_activated_for_messenger(
1283
-                    $default_message_type_name_for_messenger,
1284
-                    $active_messenger->name
1285
-                )
1286
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1287
-                        $active_messenger->name,
1288
-                        $default_message_type_name_for_messenger
1289
-                    )
1290
-                    || ! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1291
-                ) {
1292
-                    continue;
1293
-                }
1294
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1295
-            }
1296
-            // let's activate!
1297
-            $message_resource_manager->ensure_message_types_are_active(
1298
-                $default_message_type_names_to_activate,
1299
-                $active_messenger->name,
1300
-                false
1301
-            );
1302
-            // activate the templates for these message types
1303
-            if (! empty($default_message_type_names_to_activate)) {
1304
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1305
-                    $active_messenger->name,
1306
-                    $default_message_type_names_for_messenger,
1307
-                    '',
1308
-                    true
1309
-                );
1310
-            }
1311
-        }
1312
-        return $templates_created;
1313
-    }
1314
-
1315
-
1316
-
1317
-    /**
1318
-     * This will activate and generate default messengers and default message types for those messengers.
1319
-     *
1320
-     * @param EE_message_Resource_Manager $message_resource_manager
1321
-     * @return array|bool  True means there were default messengers and message type templates generated.
1322
-     *                     False means that there were no templates generated
1323
-     *                     (which could simply mean there are no default message types for a messenger).
1324
-     * @throws EE_Error
1325
-     */
1326
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1327
-        EE_Message_Resource_Manager $message_resource_manager
1328
-    ) {
1329
-        /** @type EE_messenger[] $messengers_to_generate */
1330
-        $messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1331
-        $installed_message_types = $message_resource_manager->installed_message_types();
1332
-        $templates_generated = false;
1333
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1334
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1335
-            // verify the default message types match an installed message type.
1336
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1337
-                if (! isset($installed_message_types[ $name ])
1338
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1339
-                        $name,
1340
-                        $messenger_to_generate->name
1341
-                    )
1342
-                ) {
1343
-                    unset($default_message_type_names_for_messenger[ $key ]);
1344
-                }
1345
-            }
1346
-            // in previous iterations, the active_messengers option in the db
1347
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1348
-            // This comment is left here just in case we discover that we _do_ need to update before
1349
-            // passing off to create templates (after the refactor is done).
1350
-            // @todo remove this comment when determined not necessary.
1351
-            $message_resource_manager->activate_messenger(
1352
-                $messenger_to_generate,
1353
-                $default_message_type_names_for_messenger,
1354
-                false
1355
-            );
1356
-            // create any templates needing created (or will reactivate templates already generated as necessary).
1357
-            if (! empty($default_message_type_names_for_messenger)) {
1358
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1359
-                    $messenger_to_generate->name,
1360
-                    $default_message_type_names_for_messenger,
1361
-                    '',
1362
-                    true
1363
-                );
1364
-            }
1365
-        }
1366
-        return $templates_generated;
1367
-    }
1368
-
1369
-
1370
-    /**
1371
-     * This returns the default messengers to generate templates for on activation of EE.
1372
-     * It considers:
1373
-     * - whether a messenger is already active in the db.
1374
-     * - whether a messenger has been made active at any time in the past.
1375
-     *
1376
-     * @static
1377
-     * @param  EE_Message_Resource_Manager $message_resource_manager
1378
-     * @return EE_messenger[]
1379
-     */
1380
-    protected static function _get_default_messengers_to_generate_on_activation(
1381
-        EE_Message_Resource_Manager $message_resource_manager
1382
-    ) {
1383
-        $active_messengers    = $message_resource_manager->active_messengers();
1384
-        $installed_messengers = $message_resource_manager->installed_messengers();
1385
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1386
-
1387
-        $messengers_to_generate = array();
1388
-        foreach ($installed_messengers as $installed_messenger) {
1389
-            // if installed messenger is a messenger that should be activated on install
1390
-            // and is not already active
1391
-            // and has never been activated
1392
-            if (! $installed_messenger->activate_on_install
1393
-                || isset($active_messengers[ $installed_messenger->name ])
1394
-                || isset($has_activated[ $installed_messenger->name ])
1395
-            ) {
1396
-                continue;
1397
-            }
1398
-            $messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1399
-        }
1400
-        return $messengers_to_generate;
1401
-    }
1402
-
1403
-
1404
-    /**
1405
-     * This simply validates active message types to ensure they actually match installed
1406
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1407
-     * rows are set inactive.
1408
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1409
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1410
-     * are still handled in here.
1411
-     *
1412
-     * @since 4.3.1
1413
-     * @return void
1414
-     */
1415
-    public static function validate_messages_system()
1416
-    {
1417
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1418
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1419
-        $message_resource_manager->validate_active_message_types_are_installed();
1420
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1421
-    }
1422
-
1423
-
1424
-    /**
1425
-     * create_no_ticket_prices_array
1426
-     *
1427
-     * @access public
1428
-     * @static
1429
-     * @return void
1430
-     */
1431
-    public static function create_no_ticket_prices_array()
1432
-    {
1433
-        // this creates an array for tracking events that have no active ticket prices created
1434
-        // this allows us to warn admins of the situation so that it can be corrected
1435
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1436
-        if (! $espresso_no_ticket_prices) {
1437
-            add_option('ee_no_ticket_prices', array(), '', false);
1438
-        }
1439
-    }
1440
-
1441
-
1442
-    /**
1443
-     * plugin_deactivation
1444
-     *
1445
-     * @access public
1446
-     * @static
1447
-     * @return void
1448
-     */
1449
-    public static function plugin_deactivation()
1450
-    {
1451
-    }
1452
-
1453
-
1454
-    /**
1455
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1456
-     * (like post meta or term relations)
1457
-     *
1458
-     * @global wpdb $wpdb
1459
-     * @throws \EE_Error
1460
-     */
1461
-    public static function delete_all_espresso_cpt_data()
1462
-    {
1463
-        global $wpdb;
1464
-        // get all the CPT post_types
1465
-        $ee_post_types = array();
1466
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1467
-            if (method_exists($model_name, 'instance')) {
1468
-                $model_obj = call_user_func(array($model_name, 'instance'));
1469
-                if ($model_obj instanceof EEM_CPT_Base) {
1470
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1471
-                }
1472
-            }
1473
-        }
1474
-        // get all our CPTs
1475
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1476
-        $cpt_ids = $wpdb->get_col($query);
1477
-        // delete each post meta and term relations too
1478
-        foreach ($cpt_ids as $post_id) {
1479
-            wp_delete_post($post_id, true);
1480
-        }
1481
-    }
1482
-
1483
-    /**
1484
-     * Deletes all EE custom tables
1485
-     *
1486
-     * @return array
1487
-     */
1488
-    public static function drop_espresso_tables()
1489
-    {
1490
-        $tables = array();
1491
-        // load registry
1492
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1493
-            if (method_exists($model_name, 'instance')) {
1494
-                $model_obj = call_user_func(array($model_name, 'instance'));
1495
-                if ($model_obj instanceof EEM_Base) {
1496
-                    foreach ($model_obj->get_tables() as $table) {
1497
-                        if (strpos($table->get_table_name(), 'esp_')
1498
-                            &&
1499
-                            (
1500
-                                is_main_site()// main site? nuke them all
1501
-                                || ! $table->is_global()// not main site,but not global either. nuke it
1502
-                            )
1503
-                        ) {
1504
-                            $tables[ $table->get_table_name() ] = $table->get_table_name();
1505
-                        }
1506
-                    }
1507
-                }
1508
-            }
1509
-        }
1510
-
1511
-        // there are some tables whose models were removed.
1512
-        // they should be removed when removing all EE core's data
1513
-        $tables_without_models = array(
1514
-            'esp_promotion',
1515
-            'esp_promotion_applied',
1516
-            'esp_promotion_object',
1517
-            'esp_promotion_rule',
1518
-            'esp_rule',
1519
-        );
1520
-        foreach ($tables_without_models as $table) {
1521
-            $tables[ $table ] = $table;
1522
-        }
1523
-        return \EEH_Activation::getTableManager()->dropTables($tables);
1524
-    }
1525
-
1526
-
1527
-
1528
-    /**
1529
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1530
-     * each table name provided has a wpdb prefix attached, and that it exists.
1531
-     * Returns the list actually deleted
1532
-     *
1533
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1534
-     * @global WPDB $wpdb
1535
-     * @param array $table_names
1536
-     * @return array of table names which we deleted
1537
-     */
1538
-    public static function drop_tables($table_names)
1539
-    {
1540
-        return \EEH_Activation::getTableManager()->dropTables($table_names);
1541
-    }
1542
-
1543
-
1544
-
1545
-    /**
1546
-     * plugin_uninstall
1547
-     *
1548
-     * @access public
1549
-     * @static
1550
-     * @param bool $remove_all
1551
-     * @return void
1552
-     */
1553
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1554
-    {
1555
-        global $wpdb;
1556
-        self::drop_espresso_tables();
1557
-        $wp_options_to_delete = array(
1558
-            'ee_no_ticket_prices'                => true,
1559
-            'ee_active_messengers'               => true,
1560
-            'ee_has_activated_messenger'         => true,
1561
-            RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1562
-            'ee_config'                          => false,
1563
-            'ee_data_migration_current_db_state' => true,
1564
-            'ee_data_migration_mapping_'         => false,
1565
-            'ee_data_migration_script_'          => false,
1566
-            'ee_data_migrations'                 => true,
1567
-            'ee_dms_map'                         => false,
1568
-            'ee_notices'                         => true,
1569
-            'lang_file_check_'                   => false,
1570
-            'ee_maintenance_mode'                => true,
1571
-            'ee_ueip_optin'                      => true,
1572
-            'ee_ueip_has_notified'               => true,
1573
-            'ee_plugin_activation_errors'        => true,
1574
-            'ee_id_mapping_from'                 => false,
1575
-            'espresso_persistent_admin_notices'  => true,
1576
-            'ee_encryption_key'                  => true,
1577
-            'pue_force_upgrade_'                 => false,
1578
-            'pue_json_error_'                    => false,
1579
-            'pue_install_key_'                   => false,
1580
-            'pue_verification_error_'            => false,
1581
-            'pu_dismissed_upgrade_'              => false,
1582
-            'external_updates-'                  => false,
1583
-            'ee_extra_data'                      => true,
1584
-            'ee_ssn_'                            => false,
1585
-            'ee_rss_'                            => false,
1586
-            'ee_rte_n_tx_'                       => false,
1587
-            'ee_pers_admin_notices'              => true,
1588
-            'ee_job_parameters_'                 => false,
1589
-            'ee_upload_directories_incomplete'   => true,
1590
-            'ee_verified_db_collations'          => true,
1591
-        );
1592
-        if (is_main_site()) {
1593
-            $wp_options_to_delete['ee_network_config'] = true;
1594
-        }
1595
-        $undeleted_options = array();
1596
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1597
-            if ($no_wildcard) {
1598
-                if (! delete_option($option_name)) {
1599
-                    $undeleted_options[] = $option_name;
1600
-                }
1601
-            } else {
1602
-                $option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1603
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1604
-                    if (! delete_option($option_name_from_wildcard)) {
1605
-                        $undeleted_options[] = $option_name_from_wildcard;
1606
-                    }
1607
-                }
1608
-            }
1609
-        }
1610
-        // also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1611
-        remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1612
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1613
-            $db_update_sans_ee4 = array();
1614
-            foreach ($espresso_db_update as $version => $times_activated) {
1615
-                if ((string) $version[0] === '3') {// if its NON EE4
1616
-                    $db_update_sans_ee4[ $version ] = $times_activated;
1617
-                }
1618
-            }
1619
-            update_option('espresso_db_update', $db_update_sans_ee4);
1620
-        }
1621
-        $errors = '';
1622
-        if (! empty($undeleted_options)) {
1623
-            $errors .= sprintf(
1624
-                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1625
-                '<br/>',
1626
-                implode(',<br/>', $undeleted_options)
1627
-            );
1628
-        }
1629
-        if (! empty($errors)) {
1630
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1631
-        }
1632
-    }
1633
-
1634
-    /**
1635
-     * Gets the mysql error code from the last used query by wpdb
1636
-     *
1637
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1638
-     */
1639
-    public static function last_wpdb_error_code()
1640
-    {
1641
-        // phpcs:disable PHPCompatibility.PHP.RemovedExtensions.mysql_DeprecatedRemoved
1642
-        global $wpdb;
1643
-        if ($wpdb->use_mysqli) {
1644
-            return mysqli_errno($wpdb->dbh);
1645
-        } else {
1646
-            return mysql_errno($wpdb->dbh);
1647
-        }
1648
-        // phpcs:enable
1649
-    }
1650
-
1651
-    /**
1652
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1653
-     *
1654
-     * @global wpdb  $wpdb
1655
-     * @deprecated instead use TableAnalysis::tableExists()
1656
-     * @param string $table_name with or without $wpdb->prefix
1657
-     * @return boolean
1658
-     */
1659
-    public static function table_exists($table_name)
1660
-    {
1661
-        return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1662
-    }
1663
-
1664
-    /**
1665
-     * Resets the cache on EEH_Activation
1666
-     */
1667
-    public static function reset()
1668
-    {
1669
-        self::$_default_creator_id                             = null;
1670
-        self::$_initialized_db_content_already_in_this_request = false;
1671
-    }
1672
-
1673
-    /**
1674
-     * Removes 'email_confirm' from the Address info question group on activation
1675
-     * @return void
1676
-     */
1677
-    public static function removeEmailConfirmFromAddressGroup()
1678
-    {
1679
-
1680
-        // Pull the email_confirm question ID.
1681
-        $email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1682
-            EEM_Attendee::system_question_email_confirm
1683
-        );
1684
-        // Remove the email_confirm question group from the address group questions.
1685
-        EEM_Question_Group_Question::instance()->delete(
1686
-            array(
1687
-                array(
1688
-                    'QST_ID' => $email_confirm_question_id,
1689
-                    'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1690
-                ),
1691
-            )
1692
-        );
1693
-    }
1242
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1243
+			$message_resource_manager
1244
+		);
1245
+		/**
1246
+		 * This method is verifying there are no NEW default message types
1247
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1248
+		 */
1249
+		$new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1250
+			$message_resource_manager
1251
+		);
1252
+		// after all is done, let's persist these changes to the db.
1253
+		$message_resource_manager->update_has_activated_messengers_option();
1254
+		$message_resource_manager->update_active_messengers_option();
1255
+		// will return true if either of these are true.  Otherwise will return false.
1256
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1257
+	}
1258
+
1259
+
1260
+
1261
+	/**
1262
+	 * @param \EE_Message_Resource_Manager $message_resource_manager
1263
+	 * @return array|bool
1264
+	 * @throws \EE_Error
1265
+	 */
1266
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1267
+		EE_Message_Resource_Manager $message_resource_manager
1268
+	) {
1269
+		/** @type EE_messenger[] $active_messengers */
1270
+		$active_messengers = $message_resource_manager->active_messengers();
1271
+		$installed_message_types = $message_resource_manager->installed_message_types();
1272
+		$templates_created = false;
1273
+		foreach ($active_messengers as $active_messenger) {
1274
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1275
+			$default_message_type_names_to_activate = array();
1276
+			// looping through each default message type reported by the messenger
1277
+			// and setup the actual message types to activate.
1278
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1279
+				// if already active or has already been activated before we skip
1280
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1281
+				// we also skip if the message type is not installed.
1282
+				if ($message_resource_manager->has_message_type_been_activated_for_messenger(
1283
+					$default_message_type_name_for_messenger,
1284
+					$active_messenger->name
1285
+				)
1286
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1287
+						$active_messenger->name,
1288
+						$default_message_type_name_for_messenger
1289
+					)
1290
+					|| ! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1291
+				) {
1292
+					continue;
1293
+				}
1294
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1295
+			}
1296
+			// let's activate!
1297
+			$message_resource_manager->ensure_message_types_are_active(
1298
+				$default_message_type_names_to_activate,
1299
+				$active_messenger->name,
1300
+				false
1301
+			);
1302
+			// activate the templates for these message types
1303
+			if (! empty($default_message_type_names_to_activate)) {
1304
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1305
+					$active_messenger->name,
1306
+					$default_message_type_names_for_messenger,
1307
+					'',
1308
+					true
1309
+				);
1310
+			}
1311
+		}
1312
+		return $templates_created;
1313
+	}
1314
+
1315
+
1316
+
1317
+	/**
1318
+	 * This will activate and generate default messengers and default message types for those messengers.
1319
+	 *
1320
+	 * @param EE_message_Resource_Manager $message_resource_manager
1321
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1322
+	 *                     False means that there were no templates generated
1323
+	 *                     (which could simply mean there are no default message types for a messenger).
1324
+	 * @throws EE_Error
1325
+	 */
1326
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1327
+		EE_Message_Resource_Manager $message_resource_manager
1328
+	) {
1329
+		/** @type EE_messenger[] $messengers_to_generate */
1330
+		$messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1331
+		$installed_message_types = $message_resource_manager->installed_message_types();
1332
+		$templates_generated = false;
1333
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1334
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1335
+			// verify the default message types match an installed message type.
1336
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1337
+				if (! isset($installed_message_types[ $name ])
1338
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1339
+						$name,
1340
+						$messenger_to_generate->name
1341
+					)
1342
+				) {
1343
+					unset($default_message_type_names_for_messenger[ $key ]);
1344
+				}
1345
+			}
1346
+			// in previous iterations, the active_messengers option in the db
1347
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1348
+			// This comment is left here just in case we discover that we _do_ need to update before
1349
+			// passing off to create templates (after the refactor is done).
1350
+			// @todo remove this comment when determined not necessary.
1351
+			$message_resource_manager->activate_messenger(
1352
+				$messenger_to_generate,
1353
+				$default_message_type_names_for_messenger,
1354
+				false
1355
+			);
1356
+			// create any templates needing created (or will reactivate templates already generated as necessary).
1357
+			if (! empty($default_message_type_names_for_messenger)) {
1358
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1359
+					$messenger_to_generate->name,
1360
+					$default_message_type_names_for_messenger,
1361
+					'',
1362
+					true
1363
+				);
1364
+			}
1365
+		}
1366
+		return $templates_generated;
1367
+	}
1368
+
1369
+
1370
+	/**
1371
+	 * This returns the default messengers to generate templates for on activation of EE.
1372
+	 * It considers:
1373
+	 * - whether a messenger is already active in the db.
1374
+	 * - whether a messenger has been made active at any time in the past.
1375
+	 *
1376
+	 * @static
1377
+	 * @param  EE_Message_Resource_Manager $message_resource_manager
1378
+	 * @return EE_messenger[]
1379
+	 */
1380
+	protected static function _get_default_messengers_to_generate_on_activation(
1381
+		EE_Message_Resource_Manager $message_resource_manager
1382
+	) {
1383
+		$active_messengers    = $message_resource_manager->active_messengers();
1384
+		$installed_messengers = $message_resource_manager->installed_messengers();
1385
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1386
+
1387
+		$messengers_to_generate = array();
1388
+		foreach ($installed_messengers as $installed_messenger) {
1389
+			// if installed messenger is a messenger that should be activated on install
1390
+			// and is not already active
1391
+			// and has never been activated
1392
+			if (! $installed_messenger->activate_on_install
1393
+				|| isset($active_messengers[ $installed_messenger->name ])
1394
+				|| isset($has_activated[ $installed_messenger->name ])
1395
+			) {
1396
+				continue;
1397
+			}
1398
+			$messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1399
+		}
1400
+		return $messengers_to_generate;
1401
+	}
1402
+
1403
+
1404
+	/**
1405
+	 * This simply validates active message types to ensure they actually match installed
1406
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1407
+	 * rows are set inactive.
1408
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1409
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1410
+	 * are still handled in here.
1411
+	 *
1412
+	 * @since 4.3.1
1413
+	 * @return void
1414
+	 */
1415
+	public static function validate_messages_system()
1416
+	{
1417
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1418
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1419
+		$message_resource_manager->validate_active_message_types_are_installed();
1420
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1421
+	}
1422
+
1423
+
1424
+	/**
1425
+	 * create_no_ticket_prices_array
1426
+	 *
1427
+	 * @access public
1428
+	 * @static
1429
+	 * @return void
1430
+	 */
1431
+	public static function create_no_ticket_prices_array()
1432
+	{
1433
+		// this creates an array for tracking events that have no active ticket prices created
1434
+		// this allows us to warn admins of the situation so that it can be corrected
1435
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1436
+		if (! $espresso_no_ticket_prices) {
1437
+			add_option('ee_no_ticket_prices', array(), '', false);
1438
+		}
1439
+	}
1440
+
1441
+
1442
+	/**
1443
+	 * plugin_deactivation
1444
+	 *
1445
+	 * @access public
1446
+	 * @static
1447
+	 * @return void
1448
+	 */
1449
+	public static function plugin_deactivation()
1450
+	{
1451
+	}
1452
+
1453
+
1454
+	/**
1455
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1456
+	 * (like post meta or term relations)
1457
+	 *
1458
+	 * @global wpdb $wpdb
1459
+	 * @throws \EE_Error
1460
+	 */
1461
+	public static function delete_all_espresso_cpt_data()
1462
+	{
1463
+		global $wpdb;
1464
+		// get all the CPT post_types
1465
+		$ee_post_types = array();
1466
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1467
+			if (method_exists($model_name, 'instance')) {
1468
+				$model_obj = call_user_func(array($model_name, 'instance'));
1469
+				if ($model_obj instanceof EEM_CPT_Base) {
1470
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1471
+				}
1472
+			}
1473
+		}
1474
+		// get all our CPTs
1475
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1476
+		$cpt_ids = $wpdb->get_col($query);
1477
+		// delete each post meta and term relations too
1478
+		foreach ($cpt_ids as $post_id) {
1479
+			wp_delete_post($post_id, true);
1480
+		}
1481
+	}
1482
+
1483
+	/**
1484
+	 * Deletes all EE custom tables
1485
+	 *
1486
+	 * @return array
1487
+	 */
1488
+	public static function drop_espresso_tables()
1489
+	{
1490
+		$tables = array();
1491
+		// load registry
1492
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1493
+			if (method_exists($model_name, 'instance')) {
1494
+				$model_obj = call_user_func(array($model_name, 'instance'));
1495
+				if ($model_obj instanceof EEM_Base) {
1496
+					foreach ($model_obj->get_tables() as $table) {
1497
+						if (strpos($table->get_table_name(), 'esp_')
1498
+							&&
1499
+							(
1500
+								is_main_site()// main site? nuke them all
1501
+								|| ! $table->is_global()// not main site,but not global either. nuke it
1502
+							)
1503
+						) {
1504
+							$tables[ $table->get_table_name() ] = $table->get_table_name();
1505
+						}
1506
+					}
1507
+				}
1508
+			}
1509
+		}
1510
+
1511
+		// there are some tables whose models were removed.
1512
+		// they should be removed when removing all EE core's data
1513
+		$tables_without_models = array(
1514
+			'esp_promotion',
1515
+			'esp_promotion_applied',
1516
+			'esp_promotion_object',
1517
+			'esp_promotion_rule',
1518
+			'esp_rule',
1519
+		);
1520
+		foreach ($tables_without_models as $table) {
1521
+			$tables[ $table ] = $table;
1522
+		}
1523
+		return \EEH_Activation::getTableManager()->dropTables($tables);
1524
+	}
1525
+
1526
+
1527
+
1528
+	/**
1529
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1530
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1531
+	 * Returns the list actually deleted
1532
+	 *
1533
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1534
+	 * @global WPDB $wpdb
1535
+	 * @param array $table_names
1536
+	 * @return array of table names which we deleted
1537
+	 */
1538
+	public static function drop_tables($table_names)
1539
+	{
1540
+		return \EEH_Activation::getTableManager()->dropTables($table_names);
1541
+	}
1542
+
1543
+
1544
+
1545
+	/**
1546
+	 * plugin_uninstall
1547
+	 *
1548
+	 * @access public
1549
+	 * @static
1550
+	 * @param bool $remove_all
1551
+	 * @return void
1552
+	 */
1553
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1554
+	{
1555
+		global $wpdb;
1556
+		self::drop_espresso_tables();
1557
+		$wp_options_to_delete = array(
1558
+			'ee_no_ticket_prices'                => true,
1559
+			'ee_active_messengers'               => true,
1560
+			'ee_has_activated_messenger'         => true,
1561
+			RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1562
+			'ee_config'                          => false,
1563
+			'ee_data_migration_current_db_state' => true,
1564
+			'ee_data_migration_mapping_'         => false,
1565
+			'ee_data_migration_script_'          => false,
1566
+			'ee_data_migrations'                 => true,
1567
+			'ee_dms_map'                         => false,
1568
+			'ee_notices'                         => true,
1569
+			'lang_file_check_'                   => false,
1570
+			'ee_maintenance_mode'                => true,
1571
+			'ee_ueip_optin'                      => true,
1572
+			'ee_ueip_has_notified'               => true,
1573
+			'ee_plugin_activation_errors'        => true,
1574
+			'ee_id_mapping_from'                 => false,
1575
+			'espresso_persistent_admin_notices'  => true,
1576
+			'ee_encryption_key'                  => true,
1577
+			'pue_force_upgrade_'                 => false,
1578
+			'pue_json_error_'                    => false,
1579
+			'pue_install_key_'                   => false,
1580
+			'pue_verification_error_'            => false,
1581
+			'pu_dismissed_upgrade_'              => false,
1582
+			'external_updates-'                  => false,
1583
+			'ee_extra_data'                      => true,
1584
+			'ee_ssn_'                            => false,
1585
+			'ee_rss_'                            => false,
1586
+			'ee_rte_n_tx_'                       => false,
1587
+			'ee_pers_admin_notices'              => true,
1588
+			'ee_job_parameters_'                 => false,
1589
+			'ee_upload_directories_incomplete'   => true,
1590
+			'ee_verified_db_collations'          => true,
1591
+		);
1592
+		if (is_main_site()) {
1593
+			$wp_options_to_delete['ee_network_config'] = true;
1594
+		}
1595
+		$undeleted_options = array();
1596
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1597
+			if ($no_wildcard) {
1598
+				if (! delete_option($option_name)) {
1599
+					$undeleted_options[] = $option_name;
1600
+				}
1601
+			} else {
1602
+				$option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1603
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1604
+					if (! delete_option($option_name_from_wildcard)) {
1605
+						$undeleted_options[] = $option_name_from_wildcard;
1606
+					}
1607
+				}
1608
+			}
1609
+		}
1610
+		// also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1611
+		remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1612
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1613
+			$db_update_sans_ee4 = array();
1614
+			foreach ($espresso_db_update as $version => $times_activated) {
1615
+				if ((string) $version[0] === '3') {// if its NON EE4
1616
+					$db_update_sans_ee4[ $version ] = $times_activated;
1617
+				}
1618
+			}
1619
+			update_option('espresso_db_update', $db_update_sans_ee4);
1620
+		}
1621
+		$errors = '';
1622
+		if (! empty($undeleted_options)) {
1623
+			$errors .= sprintf(
1624
+				__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1625
+				'<br/>',
1626
+				implode(',<br/>', $undeleted_options)
1627
+			);
1628
+		}
1629
+		if (! empty($errors)) {
1630
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1631
+		}
1632
+	}
1633
+
1634
+	/**
1635
+	 * Gets the mysql error code from the last used query by wpdb
1636
+	 *
1637
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1638
+	 */
1639
+	public static function last_wpdb_error_code()
1640
+	{
1641
+		// phpcs:disable PHPCompatibility.PHP.RemovedExtensions.mysql_DeprecatedRemoved
1642
+		global $wpdb;
1643
+		if ($wpdb->use_mysqli) {
1644
+			return mysqli_errno($wpdb->dbh);
1645
+		} else {
1646
+			return mysql_errno($wpdb->dbh);
1647
+		}
1648
+		// phpcs:enable
1649
+	}
1650
+
1651
+	/**
1652
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1653
+	 *
1654
+	 * @global wpdb  $wpdb
1655
+	 * @deprecated instead use TableAnalysis::tableExists()
1656
+	 * @param string $table_name with or without $wpdb->prefix
1657
+	 * @return boolean
1658
+	 */
1659
+	public static function table_exists($table_name)
1660
+	{
1661
+		return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1662
+	}
1663
+
1664
+	/**
1665
+	 * Resets the cache on EEH_Activation
1666
+	 */
1667
+	public static function reset()
1668
+	{
1669
+		self::$_default_creator_id                             = null;
1670
+		self::$_initialized_db_content_already_in_this_request = false;
1671
+	}
1672
+
1673
+	/**
1674
+	 * Removes 'email_confirm' from the Address info question group on activation
1675
+	 * @return void
1676
+	 */
1677
+	public static function removeEmailConfirmFromAddressGroup()
1678
+	{
1679
+
1680
+		// Pull the email_confirm question ID.
1681
+		$email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1682
+			EEM_Attendee::system_question_email_confirm
1683
+		);
1684
+		// Remove the email_confirm question group from the address group questions.
1685
+		EEM_Question_Group_Question::instance()->delete(
1686
+			array(
1687
+				array(
1688
+					'QST_ID' => $email_confirm_question_id,
1689
+					'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1690
+				),
1691
+			)
1692
+		);
1693
+	}
1694 1694
 }
Please login to merge, or discard this patch.
core/EE_Addon.core.php 2 patches
Indentation   +843 added lines, -843 removed lines patch added patch discarded remove patch
@@ -19,797 +19,797 @@  discard block
 block discarded – undo
19 19
 {
20 20
 
21 21
 
22
-    /**
23
-     * prefix to be added onto an addon's plugin slug to make a wp option name
24
-     * which will be used to store the plugin's activation history
25
-     */
26
-    const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
-
28
-    /**
29
-     * @var $_version
30
-     * @type string
31
-     */
32
-    protected $_version = '';
33
-
34
-    /**
35
-     * @var $_min_core_version
36
-     * @type string
37
-     */
38
-    protected $_min_core_version = '';
39
-
40
-    /**
41
-     * derived from plugin 'main_file_path using plugin_basename()
42
-     *
43
-     * @type string $_plugin_basename
44
-     */
45
-    protected $_plugin_basename = '';
46
-
47
-    /**
48
-     * A non-internationalized name to identify this addon for use in URLs, etc
49
-     *
50
-     * @type string $_plugin_slug
51
-     */
52
-    protected $_plugin_slug = '';
53
-
54
-    /**
55
-     * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
-     *
57
-     * @type string _addon_name
58
-     */
59
-    protected $_addon_name = '';
60
-
61
-    /**
62
-     * one of the EE_System::req_type_* constants
63
-     *
64
-     * @type int $_req_type
65
-     */
66
-    protected $_req_type;
67
-
68
-    /**
69
-     * page slug to be used when generating the "Settings" link on the WP plugin page
70
-     *
71
-     * @type string $_plugin_action_slug
72
-     */
73
-    protected $_plugin_action_slug = '';
74
-
75
-    /**
76
-     * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
-     * that can be used for adding upgrading/marketing info
78
-     *
79
-     * @type array $_plugins_page_row
80
-     */
81
-    protected $_plugins_page_row = array();
82
-
83
-
84
-    /**
85
-     *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
-     *
87
-     * @type string
88
-     */
89
-    protected $_main_plugin_file;
90
-
91
-    /**
92
-     *    This is the slug used to identify this add-on within the plugin update engine.
93
-     *
94
-     * @type string
95
-     */
96
-    protected $pue_slug;
97
-
98
-
99
-    /**
100
-     * @var EE_Dependency_Map $dependency_map
101
-     */
102
-    private $dependency_map;
103
-
104
-
105
-    /**
106
-     * @var DomainInterface $domain
107
-     */
108
-    private $domain;
109
-
110
-
111
-    /**
112
-     * @param EE_Dependency_Map $dependency_map [optional]
113
-     * @param DomainInterface   $domain         [optional]
114
-     */
115
-    public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
-    {
117
-        if ($dependency_map instanceof EE_Dependency_Map) {
118
-            $this->setDependencyMap($dependency_map);
119
-        }
120
-        if ($domain instanceof DomainInterface) {
121
-            $this->setDomain($domain);
122
-        }
123
-        add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init'));
124
-    }
125
-
126
-
127
-    /**
128
-     * @param EE_Dependency_Map $dependency_map
129
-     */
130
-    public function setDependencyMap($dependency_map)
131
-    {
132
-        $this->dependency_map = $dependency_map;
133
-    }
134
-
135
-
136
-    /**
137
-     * @return EE_Dependency_Map
138
-     */
139
-    public function dependencyMap()
140
-    {
141
-        return $this->dependency_map;
142
-    }
143
-
144
-
145
-    /**
146
-     * @param DomainInterface $domain
147
-     */
148
-    public function setDomain(DomainInterface $domain)
149
-    {
150
-        $this->domain = $domain;
151
-    }
152
-
153
-    /**
154
-     * @return DomainInterface
155
-     */
156
-    public function domain()
157
-    {
158
-        return $this->domain;
159
-    }
160
-
161
-
162
-    /**
163
-     * @param mixed $version
164
-     */
165
-    public function set_version($version = null)
166
-    {
167
-        $this->_version = $version;
168
-    }
169
-
170
-
171
-    /**
172
-     * get__version
173
-     *
174
-     * @return string
175
-     */
176
-    public function version()
177
-    {
178
-        return $this->_version;
179
-    }
180
-
181
-
182
-    /**
183
-     * @param mixed $min_core_version
184
-     */
185
-    public function set_min_core_version($min_core_version = null)
186
-    {
187
-        $this->_min_core_version = $min_core_version;
188
-    }
189
-
190
-
191
-    /**
192
-     * get__min_core_version
193
-     *
194
-     * @return string
195
-     */
196
-    public function min_core_version()
197
-    {
198
-        return $this->_min_core_version;
199
-    }
200
-
201
-
202
-    /**
203
-     * Sets addon_name
204
-     *
205
-     * @param string $addon_name
206
-     * @return boolean
207
-     */
208
-    public function set_name($addon_name)
209
-    {
210
-        return $this->_addon_name = $addon_name;
211
-    }
212
-
213
-
214
-    /**
215
-     * Gets addon_name
216
-     *
217
-     * @return string
218
-     */
219
-    public function name()
220
-    {
221
-        return $this->_addon_name;
222
-    }
223
-
224
-
225
-    /**
226
-     * @return string
227
-     */
228
-    public function plugin_basename()
229
-    {
230
-
231
-        return $this->_plugin_basename;
232
-    }
233
-
234
-
235
-    /**
236
-     * @param string $plugin_basename
237
-     */
238
-    public function set_plugin_basename($plugin_basename)
239
-    {
240
-
241
-        $this->_plugin_basename = $plugin_basename;
242
-    }
243
-
244
-
245
-    /**
246
-     * @return string
247
-     */
248
-    public function plugin_slug()
249
-    {
250
-
251
-        return $this->_plugin_slug;
252
-    }
253
-
254
-
255
-    /**
256
-     * @param string $plugin_slug
257
-     */
258
-    public function set_plugin_slug($plugin_slug)
259
-    {
260
-
261
-        $this->_plugin_slug = $plugin_slug;
262
-    }
263
-
264
-
265
-    /**
266
-     * @return string
267
-     */
268
-    public function plugin_action_slug()
269
-    {
270
-
271
-        return $this->_plugin_action_slug;
272
-    }
273
-
274
-
275
-    /**
276
-     * @param string $plugin_action_slug
277
-     */
278
-    public function set_plugin_action_slug($plugin_action_slug)
279
-    {
280
-
281
-        $this->_plugin_action_slug = $plugin_action_slug;
282
-    }
283
-
284
-
285
-    /**
286
-     * @return array
287
-     */
288
-    public function get_plugins_page_row()
289
-    {
290
-
291
-        return $this->_plugins_page_row;
292
-    }
293
-
294
-
295
-    /**
296
-     * @param array $plugins_page_row
297
-     */
298
-    public function set_plugins_page_row($plugins_page_row = array())
299
-    {
300
-        // sigh.... check for example content that I stupidly merged to master and remove it if found
301
-        if (! is_array($plugins_page_row)
302
-            && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303
-        ) {
304
-            $plugins_page_row = array();
305
-        }
306
-        $this->_plugins_page_row = (array) $plugins_page_row;
307
-    }
308
-
309
-
310
-    /**
311
-     * Called when EE core detects this addon has been activated for the first time.
312
-     * If the site isn't in maintenance mode, should setup the addon's database
313
-     *
314
-     * @return void
315
-     */
316
-    public function new_install()
317
-    {
318
-        $classname = get_class($this);
319
-        do_action("AHEE__{$classname}__new_install");
320
-        do_action('AHEE__EE_Addon__new_install', $this);
321
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
322
-        add_action(
323
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
324
-            array($this, 'initialize_db_if_no_migrations_required')
325
-        );
326
-    }
327
-
328
-
329
-    /**
330
-     * Called when EE core detects this addon has been reactivated. When this happens,
331
-     * it's good to just check that your data is still intact
332
-     *
333
-     * @return void
334
-     */
335
-    public function reactivation()
336
-    {
337
-        $classname = get_class($this);
338
-        do_action("AHEE__{$classname}__reactivation");
339
-        do_action('AHEE__EE_Addon__reactivation', $this);
340
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
341
-        add_action(
342
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
343
-            array($this, 'initialize_db_if_no_migrations_required')
344
-        );
345
-    }
346
-
347
-
348
-    /**
349
-     * Called when the registered deactivation hook for this addon fires.
350
-     *
351
-     * @throws EE_Error
352
-     */
353
-    public function deactivation()
354
-    {
355
-        $classname = get_class($this);
356
-        do_action("AHEE__{$classname}__deactivation");
357
-        do_action('AHEE__EE_Addon__deactivation', $this);
358
-        // check if the site no longer needs to be in maintenance mode
359
-        EE_Register_Addon::deregister($this->name());
360
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
361
-    }
362
-
363
-
364
-    /**
365
-     * Takes care of double-checking that we're not in maintenance mode, and then
366
-     * initializing this addon's necessary initial data. This is called by default on new activations
367
-     * and reactivations.
368
-     *
369
-     * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
370
-     *                               This is a resource-intensive job so we prefer to only do it when necessary
371
-     * @return void
372
-     * @throws \EE_Error
373
-     * @throws InvalidInterfaceException
374
-     * @throws InvalidDataTypeException
375
-     * @throws InvalidArgumentException
376
-     */
377
-    public function initialize_db_if_no_migrations_required($verify_schema = true)
378
-    {
379
-        if ($verify_schema === '') {
380
-            // wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
381
-            // (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
382
-            // calls them with an argument of an empty string (ie ""), which evaluates to false
383
-            // so we need to treat the empty string as if nothing had been passed, and should instead use the default
384
-            $verify_schema = true;
385
-        }
386
-        if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
387
-            if ($verify_schema) {
388
-                $this->initialize_db();
389
-            }
390
-            $this->initialize_default_data();
391
-            // @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
392
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to(
393
-                array(
394
-                    'slug'    => $this->name(),
395
-                    'version' => $this->version(),
396
-                )
397
-            );
398
-            /* make sure core's data is a-ok
22
+	/**
23
+	 * prefix to be added onto an addon's plugin slug to make a wp option name
24
+	 * which will be used to store the plugin's activation history
25
+	 */
26
+	const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
+
28
+	/**
29
+	 * @var $_version
30
+	 * @type string
31
+	 */
32
+	protected $_version = '';
33
+
34
+	/**
35
+	 * @var $_min_core_version
36
+	 * @type string
37
+	 */
38
+	protected $_min_core_version = '';
39
+
40
+	/**
41
+	 * derived from plugin 'main_file_path using plugin_basename()
42
+	 *
43
+	 * @type string $_plugin_basename
44
+	 */
45
+	protected $_plugin_basename = '';
46
+
47
+	/**
48
+	 * A non-internationalized name to identify this addon for use in URLs, etc
49
+	 *
50
+	 * @type string $_plugin_slug
51
+	 */
52
+	protected $_plugin_slug = '';
53
+
54
+	/**
55
+	 * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
+	 *
57
+	 * @type string _addon_name
58
+	 */
59
+	protected $_addon_name = '';
60
+
61
+	/**
62
+	 * one of the EE_System::req_type_* constants
63
+	 *
64
+	 * @type int $_req_type
65
+	 */
66
+	protected $_req_type;
67
+
68
+	/**
69
+	 * page slug to be used when generating the "Settings" link on the WP plugin page
70
+	 *
71
+	 * @type string $_plugin_action_slug
72
+	 */
73
+	protected $_plugin_action_slug = '';
74
+
75
+	/**
76
+	 * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
+	 * that can be used for adding upgrading/marketing info
78
+	 *
79
+	 * @type array $_plugins_page_row
80
+	 */
81
+	protected $_plugins_page_row = array();
82
+
83
+
84
+	/**
85
+	 *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
+	 *
87
+	 * @type string
88
+	 */
89
+	protected $_main_plugin_file;
90
+
91
+	/**
92
+	 *    This is the slug used to identify this add-on within the plugin update engine.
93
+	 *
94
+	 * @type string
95
+	 */
96
+	protected $pue_slug;
97
+
98
+
99
+	/**
100
+	 * @var EE_Dependency_Map $dependency_map
101
+	 */
102
+	private $dependency_map;
103
+
104
+
105
+	/**
106
+	 * @var DomainInterface $domain
107
+	 */
108
+	private $domain;
109
+
110
+
111
+	/**
112
+	 * @param EE_Dependency_Map $dependency_map [optional]
113
+	 * @param DomainInterface   $domain         [optional]
114
+	 */
115
+	public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
+	{
117
+		if ($dependency_map instanceof EE_Dependency_Map) {
118
+			$this->setDependencyMap($dependency_map);
119
+		}
120
+		if ($domain instanceof DomainInterface) {
121
+			$this->setDomain($domain);
122
+		}
123
+		add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init'));
124
+	}
125
+
126
+
127
+	/**
128
+	 * @param EE_Dependency_Map $dependency_map
129
+	 */
130
+	public function setDependencyMap($dependency_map)
131
+	{
132
+		$this->dependency_map = $dependency_map;
133
+	}
134
+
135
+
136
+	/**
137
+	 * @return EE_Dependency_Map
138
+	 */
139
+	public function dependencyMap()
140
+	{
141
+		return $this->dependency_map;
142
+	}
143
+
144
+
145
+	/**
146
+	 * @param DomainInterface $domain
147
+	 */
148
+	public function setDomain(DomainInterface $domain)
149
+	{
150
+		$this->domain = $domain;
151
+	}
152
+
153
+	/**
154
+	 * @return DomainInterface
155
+	 */
156
+	public function domain()
157
+	{
158
+		return $this->domain;
159
+	}
160
+
161
+
162
+	/**
163
+	 * @param mixed $version
164
+	 */
165
+	public function set_version($version = null)
166
+	{
167
+		$this->_version = $version;
168
+	}
169
+
170
+
171
+	/**
172
+	 * get__version
173
+	 *
174
+	 * @return string
175
+	 */
176
+	public function version()
177
+	{
178
+		return $this->_version;
179
+	}
180
+
181
+
182
+	/**
183
+	 * @param mixed $min_core_version
184
+	 */
185
+	public function set_min_core_version($min_core_version = null)
186
+	{
187
+		$this->_min_core_version = $min_core_version;
188
+	}
189
+
190
+
191
+	/**
192
+	 * get__min_core_version
193
+	 *
194
+	 * @return string
195
+	 */
196
+	public function min_core_version()
197
+	{
198
+		return $this->_min_core_version;
199
+	}
200
+
201
+
202
+	/**
203
+	 * Sets addon_name
204
+	 *
205
+	 * @param string $addon_name
206
+	 * @return boolean
207
+	 */
208
+	public function set_name($addon_name)
209
+	{
210
+		return $this->_addon_name = $addon_name;
211
+	}
212
+
213
+
214
+	/**
215
+	 * Gets addon_name
216
+	 *
217
+	 * @return string
218
+	 */
219
+	public function name()
220
+	{
221
+		return $this->_addon_name;
222
+	}
223
+
224
+
225
+	/**
226
+	 * @return string
227
+	 */
228
+	public function plugin_basename()
229
+	{
230
+
231
+		return $this->_plugin_basename;
232
+	}
233
+
234
+
235
+	/**
236
+	 * @param string $plugin_basename
237
+	 */
238
+	public function set_plugin_basename($plugin_basename)
239
+	{
240
+
241
+		$this->_plugin_basename = $plugin_basename;
242
+	}
243
+
244
+
245
+	/**
246
+	 * @return string
247
+	 */
248
+	public function plugin_slug()
249
+	{
250
+
251
+		return $this->_plugin_slug;
252
+	}
253
+
254
+
255
+	/**
256
+	 * @param string $plugin_slug
257
+	 */
258
+	public function set_plugin_slug($plugin_slug)
259
+	{
260
+
261
+		$this->_plugin_slug = $plugin_slug;
262
+	}
263
+
264
+
265
+	/**
266
+	 * @return string
267
+	 */
268
+	public function plugin_action_slug()
269
+	{
270
+
271
+		return $this->_plugin_action_slug;
272
+	}
273
+
274
+
275
+	/**
276
+	 * @param string $plugin_action_slug
277
+	 */
278
+	public function set_plugin_action_slug($plugin_action_slug)
279
+	{
280
+
281
+		$this->_plugin_action_slug = $plugin_action_slug;
282
+	}
283
+
284
+
285
+	/**
286
+	 * @return array
287
+	 */
288
+	public function get_plugins_page_row()
289
+	{
290
+
291
+		return $this->_plugins_page_row;
292
+	}
293
+
294
+
295
+	/**
296
+	 * @param array $plugins_page_row
297
+	 */
298
+	public function set_plugins_page_row($plugins_page_row = array())
299
+	{
300
+		// sigh.... check for example content that I stupidly merged to master and remove it if found
301
+		if (! is_array($plugins_page_row)
302
+			&& strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303
+		) {
304
+			$plugins_page_row = array();
305
+		}
306
+		$this->_plugins_page_row = (array) $plugins_page_row;
307
+	}
308
+
309
+
310
+	/**
311
+	 * Called when EE core detects this addon has been activated for the first time.
312
+	 * If the site isn't in maintenance mode, should setup the addon's database
313
+	 *
314
+	 * @return void
315
+	 */
316
+	public function new_install()
317
+	{
318
+		$classname = get_class($this);
319
+		do_action("AHEE__{$classname}__new_install");
320
+		do_action('AHEE__EE_Addon__new_install', $this);
321
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
322
+		add_action(
323
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
324
+			array($this, 'initialize_db_if_no_migrations_required')
325
+		);
326
+	}
327
+
328
+
329
+	/**
330
+	 * Called when EE core detects this addon has been reactivated. When this happens,
331
+	 * it's good to just check that your data is still intact
332
+	 *
333
+	 * @return void
334
+	 */
335
+	public function reactivation()
336
+	{
337
+		$classname = get_class($this);
338
+		do_action("AHEE__{$classname}__reactivation");
339
+		do_action('AHEE__EE_Addon__reactivation', $this);
340
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
341
+		add_action(
342
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
343
+			array($this, 'initialize_db_if_no_migrations_required')
344
+		);
345
+	}
346
+
347
+
348
+	/**
349
+	 * Called when the registered deactivation hook for this addon fires.
350
+	 *
351
+	 * @throws EE_Error
352
+	 */
353
+	public function deactivation()
354
+	{
355
+		$classname = get_class($this);
356
+		do_action("AHEE__{$classname}__deactivation");
357
+		do_action('AHEE__EE_Addon__deactivation', $this);
358
+		// check if the site no longer needs to be in maintenance mode
359
+		EE_Register_Addon::deregister($this->name());
360
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
361
+	}
362
+
363
+
364
+	/**
365
+	 * Takes care of double-checking that we're not in maintenance mode, and then
366
+	 * initializing this addon's necessary initial data. This is called by default on new activations
367
+	 * and reactivations.
368
+	 *
369
+	 * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
370
+	 *                               This is a resource-intensive job so we prefer to only do it when necessary
371
+	 * @return void
372
+	 * @throws \EE_Error
373
+	 * @throws InvalidInterfaceException
374
+	 * @throws InvalidDataTypeException
375
+	 * @throws InvalidArgumentException
376
+	 */
377
+	public function initialize_db_if_no_migrations_required($verify_schema = true)
378
+	{
379
+		if ($verify_schema === '') {
380
+			// wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
381
+			// (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
382
+			// calls them with an argument of an empty string (ie ""), which evaluates to false
383
+			// so we need to treat the empty string as if nothing had been passed, and should instead use the default
384
+			$verify_schema = true;
385
+		}
386
+		if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
387
+			if ($verify_schema) {
388
+				$this->initialize_db();
389
+			}
390
+			$this->initialize_default_data();
391
+			// @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
392
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to(
393
+				array(
394
+					'slug'    => $this->name(),
395
+					'version' => $this->version(),
396
+				)
397
+			);
398
+			/* make sure core's data is a-ok
399 399
              * (at the time of writing, we especially want to verify all the caps are present
400 400
              * because payment method type capabilities are added dynamically, and it's
401 401
              * possible this addon added a payment method. But it's also possible
402 402
              * other data needs to be verified)
403 403
              */
404
-            EEH_Activation::initialize_db_content();
405
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
406
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
407
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
408
-            );
409
-            $rewrite_rules->flushRewriteRules();
410
-            // in case there are lots of addons being activated at once, let's force garbage collection
411
-            // to help avoid memory limit errors
412
-            // EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
413
-            gc_collect_cycles();
414
-        } else {
415
-            // ask the data migration manager to init this addon's data
416
-            // when migrations are finished because we can't do it now
417
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
418
-        }
419
-    }
420
-
421
-
422
-    /**
423
-     * Used to setup this addon's database tables, but not necessarily any default
424
-     * data in them. The default is to actually use the most up-to-date data migration script
425
-     * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
426
-     * methods to setup the db.
427
-     */
428
-    public function initialize_db()
429
-    {
430
-        // find the migration script that sets the database to be compatible with the code
431
-        $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
432
-        if ($current_dms_name) {
433
-            $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
434
-            $current_data_migration_script->set_migrating(false);
435
-            $current_data_migration_script->schema_changes_before_migration();
436
-            $current_data_migration_script->schema_changes_after_migration();
437
-            if ($current_data_migration_script->get_errors()) {
438
-                foreach ($current_data_migration_script->get_errors() as $error) {
439
-                    EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
440
-                }
441
-            }
442
-        }
443
-        // if not DMS was found that should be ok. This addon just doesn't require any database changes
444
-        EE_Data_Migration_Manager::instance()->update_current_database_state_to(
445
-            array(
446
-                'slug'    => $this->name(),
447
-                'version' => $this->version(),
448
-            )
449
-        );
450
-    }
451
-
452
-
453
-    /**
454
-     * If you want to setup default data for the addon, override this method, and call
455
-     * parent::initialize_default_data() from within it. This is normally called
456
-     * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
457
-     * and should verify default data is present (but this is also called
458
-     * on reactivations and just after migrations, so please verify you actually want
459
-     * to ADD default data, because it may already be present).
460
-     * However, please call this parent (currently it just fires a hook which other
461
-     * addons may be depending on)
462
-     */
463
-    public function initialize_default_data()
464
-    {
465
-        /**
466
-         * Called when an addon is ensuring its default data is set (possibly called
467
-         * on a reactivation, so first check for the absence of other data before setting
468
-         * default data)
469
-         *
470
-         * @param EE_Addon $addon the addon that called this
471
-         */
472
-        do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
473
-        // override to insert default data. It is safe to use the models here
474
-        // because the site should not be in maintenance mode
475
-    }
476
-
477
-
478
-    /**
479
-     * EE Core detected that this addon has been upgraded. We should check if there
480
-     * are any new migration scripts, and if so put the site into maintenance mode until
481
-     * they're ran
482
-     *
483
-     * @return void
484
-     */
485
-    public function upgrade()
486
-    {
487
-        $classname = get_class($this);
488
-        do_action("AHEE__{$classname}__upgrade");
489
-        do_action('AHEE__EE_Addon__upgrade', $this);
490
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
491
-        // also it's possible there is new default data that needs to be added
492
-        add_action(
493
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
494
-            array($this, 'initialize_db_if_no_migrations_required')
495
-        );
496
-    }
497
-
498
-
499
-    /**
500
-     * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
501
-     */
502
-    public function downgrade()
503
-    {
504
-        $classname = get_class($this);
505
-        do_action("AHEE__{$classname}__downgrade");
506
-        do_action('AHEE__EE_Addon__downgrade', $this);
507
-        // it's possible there's old default data that needs to be double-checked
508
-        add_action(
509
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
510
-            array($this, 'initialize_db_if_no_migrations_required')
511
-        );
512
-    }
513
-
514
-
515
-    /**
516
-     * set_db_update_option_name
517
-     * Until we do something better, we'll just check for migration scripts upon
518
-     * plugin activation only. In the future, we'll want to do it on plugin updates too
519
-     *
520
-     * @return bool
521
-     */
522
-    public function set_db_update_option_name()
523
-    {
524
-        EE_Error::doing_it_wrong(
525
-            __FUNCTION__,
526
-            esc_html__(
527
-                'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
528
-                'event_espresso'
529
-            ),
530
-            '4.3.0.alpha.016'
531
-        );
532
-        // let's just handle this on the next request, ok? right now we're just not really ready
533
-        return $this->set_activation_indicator_option();
534
-    }
535
-
536
-
537
-    /**
538
-     * Returns the name of the activation indicator option
539
-     * (an option which is set temporarily to indicate that this addon was just activated)
540
-     *
541
-     * @deprecated since version 4.3.0.alpha.016
542
-     * @return string
543
-     */
544
-    public function get_db_update_option_name()
545
-    {
546
-        EE_Error::doing_it_wrong(
547
-            __FUNCTION__,
548
-            esc_html__(
549
-                'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
550
-                'event_espresso'
551
-            ),
552
-            '4.3.0.alpha.016'
553
-        );
554
-        return $this->get_activation_indicator_option_name();
555
-    }
556
-
557
-
558
-    /**
559
-     * When the addon is activated, this should be called to set a wordpress option that
560
-     * indicates it was activated. This is especially useful for detecting reactivations.
561
-     *
562
-     * @return bool
563
-     */
564
-    public function set_activation_indicator_option()
565
-    {
566
-        // let's just handle this on the next request, ok? right now we're just not really ready
567
-        return update_option($this->get_activation_indicator_option_name(), true);
568
-    }
569
-
570
-
571
-    /**
572
-     * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
573
-     *
574
-     * @return string
575
-     */
576
-    public function get_activation_indicator_option_name()
577
-    {
578
-        return 'ee_activation_' . $this->name();
579
-    }
580
-
581
-
582
-    /**
583
-     * Used by EE_System to set the request type of this addon. Should not be used by addon developers
584
-     *
585
-     * @param int $req_type
586
-     */
587
-    public function set_req_type($req_type)
588
-    {
589
-        $this->_req_type = $req_type;
590
-    }
591
-
592
-
593
-    /**
594
-     * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
595
-     * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
596
-     * EE_System when it is checking for new install or upgrades of addons
597
-     */
598
-    public function detect_req_type()
599
-    {
600
-        if ($this->_req_type === null) {
601
-            $this->detect_activation_or_upgrade();
602
-        }
603
-        return $this->_req_type;
604
-    }
605
-
606
-
607
-    /**
608
-     * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
609
-     * Should only be called once per request
610
-     *
611
-     * @return void
612
-     */
613
-    public function detect_activation_or_upgrade()
614
-    {
615
-        $activation_history_for_addon = $this->get_activation_history();
616
-        $request_type = EE_System::detect_req_type_given_activation_history(
617
-            $activation_history_for_addon,
618
-            $this->get_activation_indicator_option_name(),
619
-            $this->version()
620
-        );
621
-        $this->set_req_type($request_type);
622
-        $classname = get_class($this);
623
-        switch ($request_type) {
624
-            case EE_System::req_type_new_activation:
625
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
626
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
627
-                $this->new_install();
628
-                $this->update_list_of_installed_versions($activation_history_for_addon);
629
-                break;
630
-            case EE_System::req_type_reactivation:
631
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
632
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
633
-                $this->reactivation();
634
-                $this->update_list_of_installed_versions($activation_history_for_addon);
635
-                break;
636
-            case EE_System::req_type_upgrade:
637
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
638
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
639
-                $this->upgrade();
640
-                $this->update_list_of_installed_versions($activation_history_for_addon);
641
-                break;
642
-            case EE_System::req_type_downgrade:
643
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
644
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
645
-                $this->downgrade();
646
-                $this->update_list_of_installed_versions($activation_history_for_addon);
647
-                break;
648
-            case EE_System::req_type_normal:
649
-            default:
650
-                break;
651
-        }
652
-
653
-        do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
654
-    }
655
-
656
-    /**
657
-     * Updates the version history for this addon
658
-     *
659
-     * @param array  $version_history
660
-     * @param string $current_version_to_add
661
-     * @return boolean success
662
-     */
663
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
664
-    {
665
-        if (! $version_history) {
666
-            $version_history = $this->get_activation_history();
667
-        }
668
-        if ($current_version_to_add === null) {
669
-            $current_version_to_add = $this->version();
670
-        }
671
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
672
-        // resave
673
-        return update_option($this->get_activation_history_option_name(), $version_history);
674
-    }
675
-
676
-    /**
677
-     * Gets the name of the wp option that stores the activation history
678
-     * of this addon
679
-     *
680
-     * @return string
681
-     */
682
-    public function get_activation_history_option_name()
683
-    {
684
-        return self::ee_addon_version_history_option_prefix . $this->name();
685
-    }
686
-
687
-
688
-    /**
689
-     * Gets the wp option which stores the activation history for this addon
690
-     *
691
-     * @return array
692
-     */
693
-    public function get_activation_history()
694
-    {
695
-        return get_option($this->get_activation_history_option_name(), null);
696
-    }
697
-
698
-
699
-    /**
700
-     * @param string $config_section
701
-     */
702
-    public function set_config_section($config_section = '')
703
-    {
704
-        $this->_config_section = ! empty($config_section) ? $config_section : 'addons';
705
-    }
706
-
707
-    /**
708
-     * Sets the filepath to the main plugin file
709
-     *
710
-     * @param string $filepath
711
-     */
712
-    public function set_main_plugin_file($filepath)
713
-    {
714
-        $this->_main_plugin_file = $filepath;
715
-    }
716
-
717
-    /**
718
-     * gets the filepath to teh main file
719
-     *
720
-     * @return string
721
-     */
722
-    public function get_main_plugin_file()
723
-    {
724
-        return $this->_main_plugin_file;
725
-    }
726
-
727
-    /**
728
-     * Gets the filename (no path) of the main file (the main file loaded
729
-     * by WP)
730
-     *
731
-     * @return string
732
-     */
733
-    public function get_main_plugin_file_basename()
734
-    {
735
-        return plugin_basename($this->get_main_plugin_file());
736
-    }
737
-
738
-    /**
739
-     * Gets the folder name which contains the main plugin file
740
-     *
741
-     * @return string
742
-     */
743
-    public function get_main_plugin_file_dirname()
744
-    {
745
-        return dirname($this->get_main_plugin_file());
746
-    }
747
-
748
-
749
-    /**
750
-     * sets hooks used in the admin
751
-     *
752
-     * @return void
753
-     */
754
-    public function admin_init()
755
-    {
756
-        // is admin and not in M-Mode ?
757
-        if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
758
-            add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
759
-            add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
760
-        }
761
-    }
762
-
763
-
764
-    /**
765
-     * plugin_actions
766
-     * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
767
-     *
768
-     * @param $links
769
-     * @param $file
770
-     * @return array
771
-     */
772
-    public function plugin_action_links($links, $file)
773
-    {
774
-        if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
775
-            // before other links
776
-            array_unshift(
777
-                $links,
778
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
779
-                . esc_html__('Settings', 'event_espresso')
780
-                . '</a>'
781
-            );
782
-        }
783
-        return $links;
784
-    }
785
-
786
-
787
-    /**
788
-     * after_plugin_row
789
-     * Add additional content to the plugins page plugin row
790
-     * Inserts another row
791
-     *
792
-     * @param $plugin_file
793
-     * @param $plugin_data
794
-     * @param $status
795
-     * @return void
796
-     */
797
-    public function after_plugin_row($plugin_file, $plugin_data, $status)
798
-    {
799
-        $after_plugin_row = '';
800
-        $plugins_page_row = $this->get_plugins_page_row();
801
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
802
-            $class = $status ? 'active' : 'inactive';
803
-            $link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
804
-            $link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
805
-            $description = isset($plugins_page_row['description'])
806
-                ? $plugins_page_row['description']
807
-                : '';
808
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
810
-                $after_plugin_row .= '<th class="check-column" scope="row"></th>';
811
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
812
-                $after_plugin_row .= '<style>
404
+			EEH_Activation::initialize_db_content();
405
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
406
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
407
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
408
+			);
409
+			$rewrite_rules->flushRewriteRules();
410
+			// in case there are lots of addons being activated at once, let's force garbage collection
411
+			// to help avoid memory limit errors
412
+			// EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
413
+			gc_collect_cycles();
414
+		} else {
415
+			// ask the data migration manager to init this addon's data
416
+			// when migrations are finished because we can't do it now
417
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
418
+		}
419
+	}
420
+
421
+
422
+	/**
423
+	 * Used to setup this addon's database tables, but not necessarily any default
424
+	 * data in them. The default is to actually use the most up-to-date data migration script
425
+	 * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
426
+	 * methods to setup the db.
427
+	 */
428
+	public function initialize_db()
429
+	{
430
+		// find the migration script that sets the database to be compatible with the code
431
+		$current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
432
+		if ($current_dms_name) {
433
+			$current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
434
+			$current_data_migration_script->set_migrating(false);
435
+			$current_data_migration_script->schema_changes_before_migration();
436
+			$current_data_migration_script->schema_changes_after_migration();
437
+			if ($current_data_migration_script->get_errors()) {
438
+				foreach ($current_data_migration_script->get_errors() as $error) {
439
+					EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
440
+				}
441
+			}
442
+		}
443
+		// if not DMS was found that should be ok. This addon just doesn't require any database changes
444
+		EE_Data_Migration_Manager::instance()->update_current_database_state_to(
445
+			array(
446
+				'slug'    => $this->name(),
447
+				'version' => $this->version(),
448
+			)
449
+		);
450
+	}
451
+
452
+
453
+	/**
454
+	 * If you want to setup default data for the addon, override this method, and call
455
+	 * parent::initialize_default_data() from within it. This is normally called
456
+	 * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
457
+	 * and should verify default data is present (but this is also called
458
+	 * on reactivations and just after migrations, so please verify you actually want
459
+	 * to ADD default data, because it may already be present).
460
+	 * However, please call this parent (currently it just fires a hook which other
461
+	 * addons may be depending on)
462
+	 */
463
+	public function initialize_default_data()
464
+	{
465
+		/**
466
+		 * Called when an addon is ensuring its default data is set (possibly called
467
+		 * on a reactivation, so first check for the absence of other data before setting
468
+		 * default data)
469
+		 *
470
+		 * @param EE_Addon $addon the addon that called this
471
+		 */
472
+		do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
473
+		// override to insert default data. It is safe to use the models here
474
+		// because the site should not be in maintenance mode
475
+	}
476
+
477
+
478
+	/**
479
+	 * EE Core detected that this addon has been upgraded. We should check if there
480
+	 * are any new migration scripts, and if so put the site into maintenance mode until
481
+	 * they're ran
482
+	 *
483
+	 * @return void
484
+	 */
485
+	public function upgrade()
486
+	{
487
+		$classname = get_class($this);
488
+		do_action("AHEE__{$classname}__upgrade");
489
+		do_action('AHEE__EE_Addon__upgrade', $this);
490
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
491
+		// also it's possible there is new default data that needs to be added
492
+		add_action(
493
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
494
+			array($this, 'initialize_db_if_no_migrations_required')
495
+		);
496
+	}
497
+
498
+
499
+	/**
500
+	 * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
501
+	 */
502
+	public function downgrade()
503
+	{
504
+		$classname = get_class($this);
505
+		do_action("AHEE__{$classname}__downgrade");
506
+		do_action('AHEE__EE_Addon__downgrade', $this);
507
+		// it's possible there's old default data that needs to be double-checked
508
+		add_action(
509
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
510
+			array($this, 'initialize_db_if_no_migrations_required')
511
+		);
512
+	}
513
+
514
+
515
+	/**
516
+	 * set_db_update_option_name
517
+	 * Until we do something better, we'll just check for migration scripts upon
518
+	 * plugin activation only. In the future, we'll want to do it on plugin updates too
519
+	 *
520
+	 * @return bool
521
+	 */
522
+	public function set_db_update_option_name()
523
+	{
524
+		EE_Error::doing_it_wrong(
525
+			__FUNCTION__,
526
+			esc_html__(
527
+				'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
528
+				'event_espresso'
529
+			),
530
+			'4.3.0.alpha.016'
531
+		);
532
+		// let's just handle this on the next request, ok? right now we're just not really ready
533
+		return $this->set_activation_indicator_option();
534
+	}
535
+
536
+
537
+	/**
538
+	 * Returns the name of the activation indicator option
539
+	 * (an option which is set temporarily to indicate that this addon was just activated)
540
+	 *
541
+	 * @deprecated since version 4.3.0.alpha.016
542
+	 * @return string
543
+	 */
544
+	public function get_db_update_option_name()
545
+	{
546
+		EE_Error::doing_it_wrong(
547
+			__FUNCTION__,
548
+			esc_html__(
549
+				'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
550
+				'event_espresso'
551
+			),
552
+			'4.3.0.alpha.016'
553
+		);
554
+		return $this->get_activation_indicator_option_name();
555
+	}
556
+
557
+
558
+	/**
559
+	 * When the addon is activated, this should be called to set a wordpress option that
560
+	 * indicates it was activated. This is especially useful for detecting reactivations.
561
+	 *
562
+	 * @return bool
563
+	 */
564
+	public function set_activation_indicator_option()
565
+	{
566
+		// let's just handle this on the next request, ok? right now we're just not really ready
567
+		return update_option($this->get_activation_indicator_option_name(), true);
568
+	}
569
+
570
+
571
+	/**
572
+	 * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
573
+	 *
574
+	 * @return string
575
+	 */
576
+	public function get_activation_indicator_option_name()
577
+	{
578
+		return 'ee_activation_' . $this->name();
579
+	}
580
+
581
+
582
+	/**
583
+	 * Used by EE_System to set the request type of this addon. Should not be used by addon developers
584
+	 *
585
+	 * @param int $req_type
586
+	 */
587
+	public function set_req_type($req_type)
588
+	{
589
+		$this->_req_type = $req_type;
590
+	}
591
+
592
+
593
+	/**
594
+	 * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
595
+	 * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
596
+	 * EE_System when it is checking for new install or upgrades of addons
597
+	 */
598
+	public function detect_req_type()
599
+	{
600
+		if ($this->_req_type === null) {
601
+			$this->detect_activation_or_upgrade();
602
+		}
603
+		return $this->_req_type;
604
+	}
605
+
606
+
607
+	/**
608
+	 * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
609
+	 * Should only be called once per request
610
+	 *
611
+	 * @return void
612
+	 */
613
+	public function detect_activation_or_upgrade()
614
+	{
615
+		$activation_history_for_addon = $this->get_activation_history();
616
+		$request_type = EE_System::detect_req_type_given_activation_history(
617
+			$activation_history_for_addon,
618
+			$this->get_activation_indicator_option_name(),
619
+			$this->version()
620
+		);
621
+		$this->set_req_type($request_type);
622
+		$classname = get_class($this);
623
+		switch ($request_type) {
624
+			case EE_System::req_type_new_activation:
625
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
626
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
627
+				$this->new_install();
628
+				$this->update_list_of_installed_versions($activation_history_for_addon);
629
+				break;
630
+			case EE_System::req_type_reactivation:
631
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
632
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
633
+				$this->reactivation();
634
+				$this->update_list_of_installed_versions($activation_history_for_addon);
635
+				break;
636
+			case EE_System::req_type_upgrade:
637
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
638
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
639
+				$this->upgrade();
640
+				$this->update_list_of_installed_versions($activation_history_for_addon);
641
+				break;
642
+			case EE_System::req_type_downgrade:
643
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
644
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
645
+				$this->downgrade();
646
+				$this->update_list_of_installed_versions($activation_history_for_addon);
647
+				break;
648
+			case EE_System::req_type_normal:
649
+			default:
650
+				break;
651
+		}
652
+
653
+		do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
654
+	}
655
+
656
+	/**
657
+	 * Updates the version history for this addon
658
+	 *
659
+	 * @param array  $version_history
660
+	 * @param string $current_version_to_add
661
+	 * @return boolean success
662
+	 */
663
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
664
+	{
665
+		if (! $version_history) {
666
+			$version_history = $this->get_activation_history();
667
+		}
668
+		if ($current_version_to_add === null) {
669
+			$current_version_to_add = $this->version();
670
+		}
671
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
672
+		// resave
673
+		return update_option($this->get_activation_history_option_name(), $version_history);
674
+	}
675
+
676
+	/**
677
+	 * Gets the name of the wp option that stores the activation history
678
+	 * of this addon
679
+	 *
680
+	 * @return string
681
+	 */
682
+	public function get_activation_history_option_name()
683
+	{
684
+		return self::ee_addon_version_history_option_prefix . $this->name();
685
+	}
686
+
687
+
688
+	/**
689
+	 * Gets the wp option which stores the activation history for this addon
690
+	 *
691
+	 * @return array
692
+	 */
693
+	public function get_activation_history()
694
+	{
695
+		return get_option($this->get_activation_history_option_name(), null);
696
+	}
697
+
698
+
699
+	/**
700
+	 * @param string $config_section
701
+	 */
702
+	public function set_config_section($config_section = '')
703
+	{
704
+		$this->_config_section = ! empty($config_section) ? $config_section : 'addons';
705
+	}
706
+
707
+	/**
708
+	 * Sets the filepath to the main plugin file
709
+	 *
710
+	 * @param string $filepath
711
+	 */
712
+	public function set_main_plugin_file($filepath)
713
+	{
714
+		$this->_main_plugin_file = $filepath;
715
+	}
716
+
717
+	/**
718
+	 * gets the filepath to teh main file
719
+	 *
720
+	 * @return string
721
+	 */
722
+	public function get_main_plugin_file()
723
+	{
724
+		return $this->_main_plugin_file;
725
+	}
726
+
727
+	/**
728
+	 * Gets the filename (no path) of the main file (the main file loaded
729
+	 * by WP)
730
+	 *
731
+	 * @return string
732
+	 */
733
+	public function get_main_plugin_file_basename()
734
+	{
735
+		return plugin_basename($this->get_main_plugin_file());
736
+	}
737
+
738
+	/**
739
+	 * Gets the folder name which contains the main plugin file
740
+	 *
741
+	 * @return string
742
+	 */
743
+	public function get_main_plugin_file_dirname()
744
+	{
745
+		return dirname($this->get_main_plugin_file());
746
+	}
747
+
748
+
749
+	/**
750
+	 * sets hooks used in the admin
751
+	 *
752
+	 * @return void
753
+	 */
754
+	public function admin_init()
755
+	{
756
+		// is admin and not in M-Mode ?
757
+		if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
758
+			add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
759
+			add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
760
+		}
761
+	}
762
+
763
+
764
+	/**
765
+	 * plugin_actions
766
+	 * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
767
+	 *
768
+	 * @param $links
769
+	 * @param $file
770
+	 * @return array
771
+	 */
772
+	public function plugin_action_links($links, $file)
773
+	{
774
+		if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
775
+			// before other links
776
+			array_unshift(
777
+				$links,
778
+				'<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
779
+				. esc_html__('Settings', 'event_espresso')
780
+				. '</a>'
781
+			);
782
+		}
783
+		return $links;
784
+	}
785
+
786
+
787
+	/**
788
+	 * after_plugin_row
789
+	 * Add additional content to the plugins page plugin row
790
+	 * Inserts another row
791
+	 *
792
+	 * @param $plugin_file
793
+	 * @param $plugin_data
794
+	 * @param $status
795
+	 * @return void
796
+	 */
797
+	public function after_plugin_row($plugin_file, $plugin_data, $status)
798
+	{
799
+		$after_plugin_row = '';
800
+		$plugins_page_row = $this->get_plugins_page_row();
801
+		if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
802
+			$class = $status ? 'active' : 'inactive';
803
+			$link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
804
+			$link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
805
+			$description = isset($plugins_page_row['description'])
806
+				? $plugins_page_row['description']
807
+				: '';
808
+			if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
+				$after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
810
+				$after_plugin_row .= '<th class="check-column" scope="row"></th>';
811
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
812
+				$after_plugin_row .= '<style>
813 813
 .ee-button,
814 814
 .ee-button:active,
815 815
 .ee-button:visited {
@@ -846,64 +846,64 @@  discard block
 block discarded – undo
846 846
 }
847 847
 .ee-button:active { top:0; }
848 848
 </style>';
849
-                $after_plugin_row .= '
849
+				$after_plugin_row .= '
850 850
 <p class="ee-addon-upsell-info-dv">
851 851
 	<a class="ee-button" href="' . $link_url . '">'
852
-                                     . $link_text
853
-                                     . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
854
-                                     . '</a>
852
+									 . $link_text
853
+									 . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
854
+									 . '</a>
855 855
 </p>';
856
-                $after_plugin_row .= '</td>';
857
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
858
-                $after_plugin_row .= $description;
859
-                $after_plugin_row .= '</td>';
860
-                $after_plugin_row .= '</tr>';
861
-            } else {
862
-                $after_plugin_row .= $description;
863
-            }
864
-        }
865
-
866
-        echo $after_plugin_row;
867
-    }
868
-
869
-
870
-    /**
871
-     * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
872
-     * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
873
-     * for back compat reasons.
874
-     *
875
-     * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
876
-     *
877
-     * It is recommended, if client code is `de-registering` an add-on, then do it on the
878
-     * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
879
-     * callback does not get run/set in that request.
880
-     *
881
-     * Also, keep in mind that if a registered add-on happens to be deactivated via
882
-     * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
883
-     * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
884
-     * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
885
-     * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
886
-     * to call `parent::deactivation`.
887
-     *
888
-     * @since 4.9.26
889
-     */
890
-    public function after_registration()
891
-    {
892
-        // cricket chirp... cricket chirp...
893
-    }
894
-
895
-    /**
896
-     * @return string
897
-     */
898
-    public function getPueSlug()
899
-    {
900
-        return $this->pue_slug;
901
-    }
902
-    /**
903
-     * @param string $pue_slug
904
-     */
905
-    public function setPueSlug($pue_slug)
906
-    {
907
-        $this->pue_slug = $pue_slug;
908
-    }
856
+				$after_plugin_row .= '</td>';
857
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
858
+				$after_plugin_row .= $description;
859
+				$after_plugin_row .= '</td>';
860
+				$after_plugin_row .= '</tr>';
861
+			} else {
862
+				$after_plugin_row .= $description;
863
+			}
864
+		}
865
+
866
+		echo $after_plugin_row;
867
+	}
868
+
869
+
870
+	/**
871
+	 * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
872
+	 * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
873
+	 * for back compat reasons.
874
+	 *
875
+	 * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
876
+	 *
877
+	 * It is recommended, if client code is `de-registering` an add-on, then do it on the
878
+	 * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
879
+	 * callback does not get run/set in that request.
880
+	 *
881
+	 * Also, keep in mind that if a registered add-on happens to be deactivated via
882
+	 * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
883
+	 * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
884
+	 * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
885
+	 * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
886
+	 * to call `parent::deactivation`.
887
+	 *
888
+	 * @since 4.9.26
889
+	 */
890
+	public function after_registration()
891
+	{
892
+		// cricket chirp... cricket chirp...
893
+	}
894
+
895
+	/**
896
+	 * @return string
897
+	 */
898
+	public function getPueSlug()
899
+	{
900
+		return $this->pue_slug;
901
+	}
902
+	/**
903
+	 * @param string $pue_slug
904
+	 */
905
+	public function setPueSlug($pue_slug)
906
+	{
907
+		$this->pue_slug = $pue_slug;
908
+	}
909 909
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
     public function set_plugins_page_row($plugins_page_row = array())
299 299
     {
300 300
         // sigh.... check for example content that I stupidly merged to master and remove it if found
301
-        if (! is_array($plugins_page_row)
301
+        if ( ! is_array($plugins_page_row)
302 302
             && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303 303
         ) {
304 304
             $plugins_page_row = array();
@@ -575,7 +575,7 @@  discard block
 block discarded – undo
575 575
      */
576 576
     public function get_activation_indicator_option_name()
577 577
     {
578
-        return 'ee_activation_' . $this->name();
578
+        return 'ee_activation_'.$this->name();
579 579
     }
580 580
 
581 581
 
@@ -662,13 +662,13 @@  discard block
 block discarded – undo
662 662
      */
663 663
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
664 664
     {
665
-        if (! $version_history) {
665
+        if ( ! $version_history) {
666 666
             $version_history = $this->get_activation_history();
667 667
         }
668 668
         if ($current_version_to_add === null) {
669 669
             $current_version_to_add = $this->version();
670 670
         }
671
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
671
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
672 672
         // resave
673 673
         return update_option($this->get_activation_history_option_name(), $version_history);
674 674
     }
@@ -681,7 +681,7 @@  discard block
 block discarded – undo
681 681
      */
682 682
     public function get_activation_history_option_name()
683 683
     {
684
-        return self::ee_addon_version_history_option_prefix . $this->name();
684
+        return self::ee_addon_version_history_option_prefix.$this->name();
685 685
     }
686 686
 
687 687
 
@@ -756,7 +756,7 @@  discard block
 block discarded – undo
756 756
         // is admin and not in M-Mode ?
757 757
         if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
758 758
             add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
759
-            add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
759
+            add_filter('after_plugin_row_'.$this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
760 760
         }
761 761
     }
762 762
 
@@ -775,7 +775,7 @@  discard block
 block discarded – undo
775 775
             // before other links
776 776
             array_unshift(
777 777
                 $links,
778
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
778
+                '<a href="admin.php?page='.$this->plugin_action_slug().'">'
779 779
                 . esc_html__('Settings', 'event_espresso')
780 780
                 . '</a>'
781 781
             );
@@ -798,15 +798,15 @@  discard block
 block discarded – undo
798 798
     {
799 799
         $after_plugin_row = '';
800 800
         $plugins_page_row = $this->get_plugins_page_row();
801
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
801
+        if ( ! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
802 802
             $class = $status ? 'active' : 'inactive';
803 803
             $link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
804 804
             $link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
805 805
             $description = isset($plugins_page_row['description'])
806 806
                 ? $plugins_page_row['description']
807 807
                 : '';
808
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
808
+            if ( ! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
+                $after_plugin_row .= '<tr id="'.sanitize_title($plugin_file).'-ee-addon" class="'.$class.'">';
810 810
                 $after_plugin_row .= '<th class="check-column" scope="row"></th>';
811 811
                 $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
812 812
                 $after_plugin_row .= '<style>
@@ -848,7 +848,7 @@  discard block
 block discarded – undo
848 848
 </style>';
849 849
                 $after_plugin_row .= '
850 850
 <p class="ee-addon-upsell-info-dv">
851
-	<a class="ee-button" href="' . $link_url . '">'
851
+	<a class="ee-button" href="' . $link_url.'">'
852 852
                                      . $link_text
853 853
                                      . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
854 854
                                      . '</a>
Please login to merge, or discard this patch.