Completed
Branch BUG-10569-fix-meta-cap-grants (526031)
by
unknown
23:23 queued 11:51
created
admin/extend/registration_form/Extend_Registration_Form_Admin_Page.core.php 1 patch
Indentation   +1088 added lines, -1088 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 /**
@@ -25,1093 +25,1093 @@  discard block
 block discarded – undo
25 25
 {
26 26
 
27 27
 
28
-    /**
29
-     * @Constructor
30
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
31
-     * @access public
32
-     */
33
-    public function __construct($routing = true)
34
-    {
35
-        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form' . DS);
36
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets' . DS);
37
-        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
38
-        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates' . DS);
39
-        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
40
-        parent::__construct($routing);
41
-    }
42
-
43
-
44
-    protected function _extend_page_config()
45
-    {
46
-        $this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
47
-        $qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
48
-        $qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID']) ? $this->_req_data['QSG_ID'] : 0;
49
-
50
-        $new_page_routes    = array(
51
-            'question_groups'    => array(
52
-                'func'       => '_question_groups_overview_list_table',
53
-                'capability' => 'ee_read_question_groups',
54
-            ),
55
-            'add_question'       => array(
56
-                'func'       => '_edit_question',
57
-                'capability' => 'ee_edit_questions',
58
-            ),
59
-            'insert_question'    => array(
60
-                'func'       => '_insert_or_update_question',
61
-                'args'       => array('new_question' => true),
62
-                'capability' => 'ee_edit_questions',
63
-                'noheader'   => true,
64
-            ),
65
-            'duplicate_question' => array(
66
-                'func'       => '_duplicate_question',
67
-                'capability' => 'ee_edit_questions',
68
-                'noheader'   => true,
69
-            ),
70
-            'trash_question'     => array(
71
-                'func'       => '_trash_question',
72
-                'capability' => 'ee_delete_question',
73
-                'obj_id'     => $qst_id,
74
-                'noheader'   => true,
75
-            ),
76
-
77
-            'restore_question' => array(
78
-                'func'       => '_trash_or_restore_questions',
79
-                'capability' => 'ee_delete_question',
80
-                'obj_id'     => $qst_id,
81
-                'args'       => array('trash' => false),
82
-                'noheader'   => true,
83
-            ),
84
-
85
-            'delete_question' => array(
86
-                'func'       => '_delete_question',
87
-                'capability' => 'ee_delete_question',
88
-                'obj_id'     => $qst_id,
89
-                'noheader'   => true,
90
-            ),
91
-
92
-            'trash_questions' => array(
93
-                'func'       => '_trash_or_restore_questions',
94
-                'capability' => 'ee_delete_questions',
95
-                'args'       => array('trash' => true),
96
-                'noheader'   => true,
97
-            ),
98
-
99
-            'restore_questions' => array(
100
-                'func'       => '_trash_or_restore_questions',
101
-                'capability' => 'ee_delete_questions',
102
-                'args'       => array('trash' => false),
103
-                'noheader'   => true,
104
-            ),
105
-
106
-            'delete_questions' => array(
107
-                'func'       => '_delete_questions',
108
-                'args'       => array(),
109
-                'capability' => 'ee_delete_questions',
110
-                'noheader'   => true,
111
-            ),
112
-
113
-            'add_question_group' => array(
114
-                'func'       => '_edit_question_group',
115
-                'capability' => 'ee_edit_question_groups',
116
-            ),
117
-
118
-            'edit_question_group' => array(
119
-                'func'       => '_edit_question_group',
120
-                'capability' => 'ee_edit_question_group',
121
-                'obj_id'     => $qsg_id,
122
-                'args'       => array('edit'),
123
-            ),
124
-
125
-            'delete_question_groups' => array(
126
-                'func'       => '_delete_question_groups',
127
-                'capability' => 'ee_delete_question_groups',
128
-                'noheader'   => true,
129
-            ),
130
-
131
-            'delete_question_group' => array(
132
-                'func'       => '_delete_question_groups',
133
-                'capability' => 'ee_delete_question_group',
134
-                'obj_id'     => $qsg_id,
135
-                'noheader'   => true,
136
-            ),
137
-
138
-            'trash_question_group' => array(
139
-                'func'       => '_trash_or_restore_question_groups',
140
-                'args'       => array('trash' => true),
141
-                'capability' => 'ee_delete_question_group',
142
-                'obj_id'     => $qsg_id,
143
-                'noheader'   => true,
144
-            ),
145
-
146
-            'restore_question_group' => array(
147
-                'func'       => '_trash_or_restore_question_groups',
148
-                'args'       => array('trash' => false),
149
-                'capability' => 'ee_delete_question_group',
150
-                'obj_id'     => $qsg_id,
151
-                'noheader'   => true,
152
-            ),
153
-
154
-            'insert_question_group' => array(
155
-                'func'       => '_insert_or_update_question_group',
156
-                'args'       => array('new_question_group' => true),
157
-                'capability' => 'ee_edit_question_groups',
158
-                'noheader'   => true,
159
-            ),
160
-
161
-            'update_question_group' => array(
162
-                'func'       => '_insert_or_update_question_group',
163
-                'args'       => array('new_question_group' => false),
164
-                'capability' => 'ee_edit_question_group',
165
-                'obj_id'     => $qsg_id,
166
-                'noheader'   => true,
167
-            ),
168
-
169
-            'trash_question_groups' => array(
170
-                'func'       => '_trash_or_restore_question_groups',
171
-                'args'       => array('trash' => true),
172
-                'capability' => 'ee_delete_question_groups',
173
-                'noheader'   => array('trash' => false),
174
-            ),
175
-
176
-            'restore_question_groups' => array(
177
-                'func'       => '_trash_or_restore_question_groups',
178
-                'args'       => array('trash' => false),
179
-                'capability' => 'ee_delete_question_groups',
180
-                'noheader'   => true,
181
-            ),
182
-
183
-
184
-            'espresso_update_question_group_order' => array(
185
-                'func'       => 'update_question_group_order',
186
-                'capability' => 'ee_edit_question_groups',
187
-                'noheader'   => true,
188
-            ),
189
-
190
-            'view_reg_form_settings' => array(
191
-                'func'       => '_reg_form_settings',
192
-                'capability' => 'manage_options',
193
-            ),
194
-
195
-            'update_reg_form_settings' => array(
196
-                'func'       => '_update_reg_form_settings',
197
-                'capability' => 'manage_options',
198
-                'noheader'   => true,
199
-            ),
200
-        );
201
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
202
-
203
-        $new_page_config    = array(
204
-
205
-            'question_groups' => array(
206
-                'nav'           => array(
207
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
208
-                    'order' => 20,
209
-                ),
210
-                'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
211
-                'help_tabs'     => array(
212
-                    'registration_form_question_groups_help_tab'                           => array(
213
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
214
-                        'filename' => 'registration_form_question_groups',
215
-                    ),
216
-                    'registration_form_question_groups_table_column_headings_help_tab'     => array(
217
-                        'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
218
-                        'filename' => 'registration_form_question_groups_table_column_headings',
219
-                    ),
220
-                    'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
221
-                        'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
222
-                        'filename' => 'registration_form_question_groups_views_bulk_actions_search',
223
-                    ),
224
-                ),
225
-                'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
226
-                'metaboxes'     => $this->_default_espresso_metaboxes,
227
-                'require_nonce' => false,
228
-                'qtips'         => array(
229
-                    'EE_Registration_Form_Tips',
230
-                ),
231
-            ),
232
-
233
-            'add_question' => array(
234
-                'nav'           => array(
235
-                    'label'      => esc_html__('Add Question', 'event_espresso'),
236
-                    'order'      => 5,
237
-                    'persistent' => false,
238
-                ),
239
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
240
-                'help_tabs'     => array(
241
-                    'registration_form_add_question_help_tab' => array(
242
-                        'title'    => esc_html__('Add Question', 'event_espresso'),
243
-                        'filename' => 'registration_form_add_question',
244
-                    ),
245
-                ),
246
-                'help_tour'     => array('Registration_Form_Add_Question_Help_Tour'),
247
-                'require_nonce' => false,
248
-            ),
249
-
250
-            'add_question_group' => array(
251
-                'nav'           => array(
252
-                    'label'      => esc_html__('Add Question Group', 'event_espresso'),
253
-                    'order'      => 5,
254
-                    'persistent' => false,
255
-                ),
256
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
257
-                'help_tabs'     => array(
258
-                    'registration_form_add_question_group_help_tab' => array(
259
-                        'title'    => esc_html__('Add Question Group', 'event_espresso'),
260
-                        'filename' => 'registration_form_add_question_group',
261
-                    ),
262
-                ),
263
-                'help_tour'     => array('Registration_Form_Add_Question_Group_Help_Tour'),
264
-                'require_nonce' => false,
265
-            ),
266
-
267
-            'edit_question_group' => array(
268
-                'nav'           => array(
269
-                    'label'      => esc_html__('Edit Question Group', 'event_espresso'),
270
-                    'order'      => 5,
271
-                    'persistent' => false,
272
-                    'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(array('question_group_id' => $this->_req_data['question_group_id']),
273
-                        $this->_current_page_view_url) : $this->_admin_base_url,
274
-                ),
275
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
276
-                'help_tabs'     => array(
277
-                    'registration_form_edit_question_group_help_tab' => array(
278
-                        'title'    => esc_html__('Edit Question Group', 'event_espresso'),
279
-                        'filename' => 'registration_form_edit_question_group',
280
-                    ),
281
-                ),
282
-                'help_tour'     => array('Registration_Form_Edit_Question_Group_Help_Tour'),
283
-                'require_nonce' => false,
284
-            ),
285
-
286
-            'view_reg_form_settings' => array(
287
-                'nav'           => array(
288
-                    'label' => esc_html__('Reg Form Settings', 'event_espresso'),
289
-                    'order' => 40,
290
-                ),
291
-                'labels'        => array(
292
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
293
-                ),
294
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
295
-                'help_tabs'     => array(
296
-                    'registration_form_reg_form_settings_help_tab' => array(
297
-                        'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
298
-                        'filename' => 'registration_form_reg_form_settings',
299
-                    ),
300
-                ),
301
-                'help_tour'     => array('Registration_Form_Settings_Help_Tour'),
302
-                'require_nonce' => false,
303
-            ),
304
-
305
-        );
306
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
307
-
308
-        //change the list table we're going to use so it's the NEW list table!
309
-        $this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
310
-
311
-
312
-        //additional labels
313
-        $new_labels               = array(
314
-            'add_question'          => esc_html__('Add New Question', 'event_espresso'),
315
-            'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
316
-            'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
317
-            'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
318
-            'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
319
-        );
320
-        $this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
321
-
322
-    }
323
-
324
-
325
-    protected function _ajax_hooks()
326
-    {
327
-        add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
328
-    }
329
-
330
-
331
-    public function load_scripts_styles_question_groups()
332
-    {
333
-        wp_enqueue_script('espresso_ajax_table_sorting');
334
-    }
335
-
336
-
337
-    public function load_scripts_styles_add_question_group()
338
-    {
339
-        $this->load_scripts_styles_forms();
340
-        $this->load_sortable_question_script();
341
-    }
342
-
343
-    public function load_scripts_styles_edit_question_group()
344
-    {
345
-        $this->load_scripts_styles_forms();
346
-        $this->load_sortable_question_script();
347
-    }
348
-
349
-
350
-    /**
351
-     * registers and enqueues script for questions
352
-     *
353
-     * @return void
354
-     */
355
-    public function load_sortable_question_script()
356
-    {
357
-        wp_register_script('ee-question-sortable', REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
358
-            array('jquery-ui-sortable'), EVENT_ESPRESSO_VERSION, true);
359
-        wp_enqueue_script('ee-question-sortable');
360
-    }
361
-
362
-
363
-    protected function _set_list_table_views_default()
364
-    {
365
-        $this->_views = array(
366
-            'all' => array(
367
-                'slug'        => 'all',
368
-                'label'       => esc_html__('View All Questions', 'event_espresso'),
369
-                'count'       => 0,
370
-                'bulk_action' => array(
371
-                    'trash_questions' => esc_html__('Trash', 'event_espresso'),
372
-                ),
373
-            ),
374
-        );
375
-
376
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
377
-            'espresso_registration_form_trash_questions')
378
-        ) {
379
-            $this->_views['trash'] = array(
380
-                'slug'        => 'trash',
381
-                'label'       => esc_html__('Trash', 'event_espresso'),
382
-                'count'       => 0,
383
-                'bulk_action' => array(
384
-                    'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
385
-                    'restore_questions' => esc_html__('Restore', 'event_espresso'),
386
-                ),
387
-            );
388
-        }
389
-    }
390
-
391
-
392
-    protected function _set_list_table_views_question_groups()
393
-    {
394
-        $this->_views = array(
395
-            'all' => array(
396
-                'slug'        => 'all',
397
-                'label'       => esc_html__('All', 'event_espresso'),
398
-                'count'       => 0,
399
-                'bulk_action' => array(
400
-                    'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
401
-                ),
402
-            ),
403
-        );
404
-
405
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_question_groups',
406
-            'espresso_registration_form_trash_question_groups')
407
-        ) {
408
-            $this->_views['trash'] = array(
409
-                'slug'        => 'trash',
410
-                'label'       => esc_html__('Trash', 'event_espresso'),
411
-                'count'       => 0,
412
-                'bulk_action' => array(
413
-                    'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
414
-                    'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
415
-                ),
416
-            );
417
-        }
418
-    }
419
-
420
-
421
-    protected function _questions_overview_list_table()
422
-    {
423
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
424
-                'add_question',
425
-                'add_question',
426
-                array(),
427
-                'add-new-h2'
428
-            );
429
-        parent::_questions_overview_list_table();
430
-    }
431
-
432
-
433
-    protected function _question_groups_overview_list_table()
434
-    {
435
-        $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
436
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
437
-                'add_question_group',
438
-                'add_question_group',
439
-                array(),
440
-                'add-new-h2'
441
-            );
442
-        $this->display_admin_list_table_page_with_sidebar();
443
-    }
444
-
445
-
446
-    protected function _delete_question()
447
-    {
448
-        $success = $this->_delete_items($this->_question_model);
449
-        $this->_redirect_after_action(
450
-            $success,
451
-            $this->_question_model->item_name($success),
452
-            'deleted',
453
-            array('action' => 'default', 'status' => 'all')
454
-        );
455
-    }
456
-
457
-
458
-    protected function _delete_questions()
459
-    {
460
-        $success = $this->_delete_items($this->_question_model);
461
-        $this->_redirect_after_action(
462
-            $success,
463
-            $this->_question_model->item_name($success),
464
-            'deleted permanently',
465
-            array('action' => 'default', 'status' => 'trash')
466
-        );
467
-    }
468
-
469
-
470
-    /**
471
-     * Performs the deletion of a single or multiple questions or question groups.
472
-     *
473
-     * @param EEM_Soft_Delete_Base $model
474
-     * @return int number of items deleted permanently
475
-     */
476
-    private function _delete_items(EEM_Soft_Delete_Base $model)
477
-    {
478
-        $success = 0;
479
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
480
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
481
-            // if array has more than one element than success message should be plural
482
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
483
-            // cycle thru bulk action checkboxes
484
-            while (list($ID, $value) = each($this->_req_data['checkbox'])) {
485
-                if (! $this->_delete_item($ID, $model)) {
486
-                    $success = 0;
487
-                }
488
-            }
489
-
490
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
491
-            $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
492
-
493
-        } elseif (! empty($this->_req_data['QST_ID'])) {
494
-            $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
495
-        } else {
496
-            EE_Error::add_error(sprintf(esc_html__("No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
497
-                "event_espresso")), __FILE__, __FUNCTION__, __LINE__);
498
-        }
499
-        return $success;
500
-    }
501
-
502
-    /**
503
-     * Deletes the specified question (and its associated question options) or question group
504
-     *
505
-     * @param int                  $id
506
-     * @param EEM_Soft_Delete_Base $model
507
-     * @return boolean
508
-     */
509
-    protected function _delete_item($id, $model)
510
-    {
511
-        if ($model instanceof EEM_Question) {
512
-            EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
513
-        }
514
-        return $model->delete_permanently_by_ID(absint($id));
515
-    }
516
-
517
-
518
-    /******************************    QUESTION GROUPS    ******************************/
519
-
520
-
521
-    protected function _edit_question_group($type = 'add')
522
-    {
523
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
524
-        $ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID']) ? absint($this->_req_data['QSG_ID']) : false;
525
-
526
-        switch ($this->_req_action) {
527
-            case 'add_question_group' :
528
-                $this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
529
-                break;
530
-            case 'edit_question_group' :
531
-                $this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
532
-                break;
533
-            default :
534
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
535
-        }
536
-        // add ID to title if editing
537
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
538
-        if ($ID) {
539
-            /** @var EE_Question_Group $questionGroup */
540
-            $questionGroup            = $this->_question_group_model->get_one_by_ID($ID);
541
-            $additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
542
-            $this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
543
-        } else {
544
-            /** @var EE_Question_Group $questionGroup */
545
-            $questionGroup = EEM_Question_Group::instance()->create_default_object();
546
-            $questionGroup->set_order_to_latest();
547
-            $this->_set_add_edit_form_tags('insert_question_group');
548
-        }
549
-        $this->_template_args['values']         = $this->_yes_no_values;
550
-        $this->_template_args['all_questions']  = $questionGroup->questions_in_and_not_in_group();
551
-        $this->_template_args['QSG_ID']         = $ID ? $ID : true;
552
-        $this->_template_args['question_group'] = $questionGroup;
553
-
554
-        $redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
555
-        $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
556
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
557
-            $this->_template_args, true);
558
-
559
-        // the details template wrapper
560
-        $this->display_admin_page_with_sidebar();
561
-    }
562
-
563
-
564
-    protected function _delete_question_groups()
565
-    {
566
-        $success = $this->_delete_items($this->_question_group_model);
567
-        $this->_redirect_after_action($success, $this->_question_group_model->item_name($success),
568
-            'deleted permanently', array('action' => 'question_groups', 'status' => 'trash'));
569
-    }
570
-
571
-
572
-    /**
573
-     * @param bool $new_question_group
574
-     */
575
-    protected function _insert_or_update_question_group($new_question_group = true)
576
-    {
577
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
578
-        $set_column_values = $this->_set_column_values_for($this->_question_group_model);
579
-        if ($new_question_group) {
580
-            $QSG_ID  = $this->_question_group_model->insert($set_column_values);
581
-            $success = $QSG_ID ? 1 : 0;
582
-        } else {
583
-            $QSG_ID = absint($this->_req_data['QSG_ID']);
584
-            unset($set_column_values['QSG_ID']);
585
-            $success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
586
-        }
587
-        $phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(EEM_Attendee::system_question_phone);
588
-        // update the existing related questions
589
-        // BUT FIRST...  delete the phone question from the Question_Group_Question if it is being added to this question group (therefore removed from the existing group)
590
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][$phone_question_id])) {
591
-            // delete where QST ID = system phone question ID and Question Group ID is NOT this group
592
-            EEM_Question_Group_Question::instance()->delete(array(
593
-                array(
594
-                    'QST_ID' => $phone_question_id,
595
-                    'QSG_ID' => array('!=', $QSG_ID),
596
-                ),
597
-            ));
598
-        }
599
-        /** @type EE_Question_Group $question_group */
600
-        $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
601
-        $questions      = $question_group->questions();
602
-        // make sure system phone question is added to list of questions for this group
603
-        if (! isset($questions[$phone_question_id])) {
604
-            $questions[$phone_question_id] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
605
-        }
606
-
607
-        foreach ($questions as $question_ID => $question) {
608
-            // first we always check for order.
609
-            if (! empty($this->_req_data['question_orders'][$question_ID])) {
610
-                //update question order
611
-                $question_group->update_question_order($question_ID, $this->_req_data['question_orders'][$question_ID]);
612
-            }
613
-
614
-            // then we always check if adding or removing.
615
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][$question_ID])) {
616
-                $question_group->add_question($question_ID);
617
-            } else {
618
-                // not found, remove it (but only if not a system question for the personal group with the exception of lname system question - we allow removal of it)
619
-                if (
620
-                in_array(
621
-                    $question->system_ID(),
622
-                    EEM_Question::instance()->required_system_questions_in_system_question_group($question_group->system_group())
623
-                )
624
-                ) {
625
-                    continue;
626
-                } else {
627
-                    $question_group->remove_question($question_ID);
628
-                }
629
-            }
630
-        }
631
-        // save new related questions
632
-        if (isset($this->_req_data['questions'])) {
633
-            foreach ($this->_req_data['questions'] as $QST_ID) {
634
-                $question_group->add_question($QST_ID);
635
-                if (isset($this->_req_data['question_orders'][$QST_ID])) {
636
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][$QST_ID]);
637
-                }
638
-            }
639
-        }
640
-
641
-        if ($success !== false) {
642
-            $msg = $new_question_group ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
643
-                $this->_question_group_model->item_name()) : sprintf(esc_html__('The %s has been updated',
644
-                'event_espresso'), $this->_question_group_model->item_name());
645
-            EE_Error::add_success($msg);
646
-        }
647
-        $this->_redirect_after_action(false, '', '', array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
648
-            true);
649
-
650
-    }
651
-
652
-    /**
653
-     * duplicates a question and all its question options and redirects to the new question.
654
-     */
655
-    public function _duplicate_question()
656
-    {
657
-        $question_ID = (int)$this->_req_data['QST_ID'];
658
-        $question    = EEM_Question::instance()->get_one_by_ID($question_ID);
659
-        if ($question instanceof EE_Question) {
660
-            $new_question = $question->duplicate();
661
-            if ($new_question instanceof EE_Question) {
662
-                $this->_redirect_after_action(true, esc_html__('Question', 'event_espresso'),
663
-                    esc_html__('Duplicated', 'event_espresso'),
664
-                    array('action' => 'edit_question', 'QST_ID' => $new_question->ID()), true);
665
-            } else {
666
-                global $wpdb;
667
-                EE_Error::add_error(sprintf(esc_html__('Could not duplicate question with ID %1$d because: %2$s',
668
-                    'event_espresso'), $question_ID, $wpdb->last_error), __FILE__, __FUNCTION__, __LINE__);
669
-                $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
670
-            }
671
-        } else {
672
-            EE_Error::add_error(sprintf(esc_html__('Could not duplicate question with ID %d because it didn\'t exist!',
673
-                'event_espresso'), $question_ID), __FILE__, __FUNCTION__, __LINE__);
674
-            $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
675
-        }
676
-    }
677
-
678
-
679
-    /**
680
-     * @param bool $trash
681
-     */
682
-    protected function _trash_or_restore_question_groups($trash = true)
683
-    {
684
-        $this->_trash_or_restore_items($this->_question_group_model, $trash);
685
-    }
686
-
687
-
688
-    /**
689
-     *_trash_question
690
-     */
691
-    protected function _trash_question()
692
-    {
693
-        $success    = $this->_question_model->delete_by_ID((int)$this->_req_data['QST_ID']);
694
-        $query_args = array('action' => 'default', 'status' => 'all');
695
-        $this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
696
-    }
697
-
698
-
699
-    /**
700
-     * @param bool $trash
701
-     */
702
-    protected function _trash_or_restore_questions($trash = true)
703
-    {
704
-        $this->_trash_or_restore_items($this->_question_model, $trash);
705
-    }
706
-
707
-
708
-    /**
709
-     * Internally used to delete or restore items, using the request data. Meant to be
710
-     * flexible between question or question groups
711
-     *
712
-     * @param EEM_Soft_Delete_Base $model
713
-     * @param boolean              $trash whether to trash or restore
714
-     */
715
-    private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
716
-    {
717
-
718
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
719
-
720
-        $success = 1;
721
-        //Checkboxes
722
-        //echo "trash $trash";
723
-        //var_dump($this->_req_data['checkbox']);die;
724
-        if (isset($this->_req_data['checkbox'])) {
725
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
726
-                // if array has more than one element than success message should be plural
727
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
728
-                // cycle thru bulk action checkboxes
729
-                while (list($ID, $value) = each($this->_req_data['checkbox'])) {
730
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
731
-                        $success = 0;
732
-                    }
733
-                }
734
-
735
-            } else {
736
-                // grab single id and delete
737
-                $ID = absint($this->_req_data['checkbox']);
738
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
739
-                    $success = 0;
740
-                }
741
-            }
742
-
743
-        } else {
744
-            // delete via trash link
745
-            // grab single id and delete
746
-            $ID = absint($this->_req_data[$model->primary_key_name()]);
747
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
748
-                $success = 0;
749
-            }
750
-
751
-        }
752
-
753
-
754
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';//strtolower( $model->item_name(2) );
755
-        //echo "action :$action";
756
-        //$action = 'questions' ? 'default' : $action;
757
-        if ($trash) {
758
-            $action_desc = 'trashed';
759
-            $status      = 'trash';
760
-        } else {
761
-            $action_desc = 'restored';
762
-            $status      = 'all';
763
-        }
764
-        $this->_redirect_after_action($success, $model->item_name($success), $action_desc,
765
-            array('action' => $action, 'status' => $status));
766
-    }
767
-
768
-
769
-    /**
770
-     * @param            $per_page
771
-     * @param int        $current_page
772
-     * @param bool|false $count
773
-     * @return \EE_Soft_Delete_Base_Class[]|int
774
-     */
775
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
776
-    {
777
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
778
-
779
-        if ($count) {
780
-            //note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
781
-            $where   = isset($query_params[0]) ? array($query_params[0]) : array();
782
-            $results = $this->_question_model->count_deleted($where);
783
-        } else {
784
-            //note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
785
-            $results = $this->_question_model->get_all_deleted($query_params);
786
-        }
787
-        return $results;
788
-    }
789
-
790
-
791
-    /**
792
-     * @param            $per_page
793
-     * @param int        $current_page
794
-     * @param bool|false $count
795
-     * @return \EE_Soft_Delete_Base_Class[]
796
-     */
797
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
798
-    {
799
-        $questionGroupModel = EEM_Question_Group::instance();
800
-        $query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
801
-        if ($count) {
802
-            $where   = isset($query_params[0]) ? array($query_params[0]) : array();
803
-            $results = $questionGroupModel->count($where);
804
-        } else {
805
-            $results = $questionGroupModel->get_all($query_params);
806
-        }
807
-        return $results;
808
-    }
809
-
810
-
811
-    /**
812
-     * @param      $per_page
813
-     * @param int  $current_page
814
-     * @param bool $count
815
-     * @return \EE_Soft_Delete_Base_Class[]|int
816
-     */
817
-    public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
818
-    {
819
-        $questionGroupModel = EEM_Question_Group::instance();
820
-        $query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
821
-        if ($count) {
822
-            $where                 = isset($query_params[0]) ? array($query_params[0]) : array();
823
-            $query_params['limit'] = null;
824
-            $results               = $questionGroupModel->count_deleted($where);
825
-        } else {
826
-            $results = $questionGroupModel->get_all_deleted($query_params);
827
-        }
828
-        return $results;
829
-    }
830
-
831
-
832
-    /**
833
-     * method for performing updates to question order
834
-     *
835
-     * @return array results array
836
-     */
837
-    public function update_question_group_order()
838
-    {
839
-
840
-        $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
841
-
842
-        // grab our row IDs
843
-        $row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
844
-            ? explode(',', rtrim($this->_req_data['row_ids'], ','))
845
-            : array();
846
-
847
-        $perpage = ! empty($this->_req_data['perpage'])
848
-            ? (int)$this->_req_data['perpage']
849
-            : null;
850
-        $curpage = ! empty($this->_req_data['curpage'])
851
-            ? (int)$this->_req_data['curpage']
852
-            : null;
853
-
854
-        if (! empty($row_ids)) {
855
-            //figure out where we start the row_id count at for the current page.
856
-            $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
857
-
858
-            $row_count = count($row_ids);
859
-            for ($i = 0; $i < $row_count; $i++) {
860
-                //Update the questions when re-ordering
861
-                $updated = EEM_Question_Group::instance()->update(
862
-                    array('QSG_order' => $qsgcount),
863
-                    array(array('QSG_ID' => $row_ids[$i]))
864
-                );
865
-                if ($updated === false) {
866
-                    $success = false;
867
-                }
868
-                $qsgcount++;
869
-            }
870
-        } else {
871
-            $success = false;
872
-        }
873
-
874
-        $errors = ! $success
875
-            ? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
876
-            : false;
877
-
878
-        echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
879
-        die();
880
-
881
-    }
882
-
883
-
884
-
885
-    /***************************************        REGISTRATION SETTINGS        ***************************************/
886
-
887
-
888
-    /**
889
-     * _reg_form_settings
890
-     *
891
-     * @throws \EE_Error
892
-     */
893
-    protected function _reg_form_settings()
894
-    {
895
-        $this->_template_args['values'] = $this->_yes_no_values;
896
-        add_action(
897
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
898
-            array($this, 'email_validation_settings_form'),
899
-            2
900
-        );
901
-        $this->_template_args = (array)apply_filters(
902
-            'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
903
-            $this->_template_args
904
-        );
905
-        $this->_set_add_edit_form_tags('update_reg_form_settings');
906
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
907
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
908
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
909
-            $this->_template_args,
910
-            true
911
-        );
912
-        $this->display_admin_page_with_sidebar();
913
-    }
914
-
915
-
916
-    /**
917
-     * _update_reg_form_settings
918
-     */
919
-    protected function _update_reg_form_settings()
920
-    {
921
-        EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
922
-            EE_Registry::instance()->CFG->registration
923
-        );
924
-        EE_Registry::instance()->CFG->registration = apply_filters(
925
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
926
-            EE_Registry::instance()->CFG->registration
927
-        );
928
-        $success                                   = $this->_update_espresso_configuration(
929
-            esc_html__('Registration Form Options', 'event_espresso'),
930
-            EE_Registry::instance()->CFG,
931
-            __FILE__, __FUNCTION__, __LINE__
932
-        );
933
-        $this->_redirect_after_action($success, esc_html__('Registration Form Options', 'event_espresso'), 'updated',
934
-            array('action' => 'view_reg_form_settings'));
935
-    }
936
-
937
-
938
-    /**
939
-     * email_validation_settings_form
940
-     *
941
-     * @access    public
942
-     * @return    void
943
-     * @throws \EE_Error
944
-     */
945
-    public function email_validation_settings_form()
946
-    {
947
-        echo $this->_email_validation_settings_form()->get_html();
948
-    }
949
-
950
-
951
-    /**
952
-     * _email_validation_settings_form
953
-     *
954
-     * @access protected
955
-     * @return EE_Form_Section_Proper
956
-     * @throws \EE_Error
957
-     */
958
-    protected function _email_validation_settings_form()
959
-    {
960
-        return new EE_Form_Section_Proper(
961
-            array(
962
-                'name'            => 'email_validation_settings',
963
-                'html_id'         => 'email_validation_settings',
964
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
965
-                'subsections'     => apply_filters(
966
-                    'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
967
-                    array(
968
-                        'email_validation_hdr'   => new EE_Form_Section_HTML(
969
-                            EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
970
-                        ),
971
-                        'email_validation_level' => new EE_Select_Input(
972
-                            array(
973
-                                'basic'      => esc_html__('Basic', 'event_espresso'),
974
-                                'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
975
-                                'i18n'       => esc_html__('International', 'event_espresso'),
976
-                                'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
977
-                            ),
978
-                            array(
979
-                                'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
980
-                                                     . EEH_Template::get_help_tab_link('email_validation_info'),
981
-                                'html_help_text'  => esc_html__('These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
982
-                                    'event_espresso'),
983
-                                'default'         => isset(EE_Registry::instance()->CFG->registration->email_validation_level)
984
-                                    ? EE_Registry::instance()->CFG->registration->email_validation_level
985
-                                    : 'wp_default',
986
-                                'required'        => false,
987
-                            )
988
-                        ),
989
-                    )
990
-                ),
991
-            )
992
-        );
993
-    }
994
-
995
-
996
-    /**
997
-     * update_email_validation_settings_form
998
-     *
999
-     * @access    public
1000
-     * @param \EE_Registration_Config $EE_Registration_Config
1001
-     * @return \EE_Registration_Config
1002
-     */
1003
-    public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1004
-    {
1005
-        $prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1006
-        try {
1007
-            $email_validation_settings_form = $this->_email_validation_settings_form();
1008
-            // if not displaying a form, then check for form submission
1009
-            if ($email_validation_settings_form->was_submitted()) {
1010
-                // capture form data
1011
-                $email_validation_settings_form->receive_form_submission();
1012
-                // validate form data
1013
-                if ($email_validation_settings_form->is_valid()) {
1014
-                    // grab validated data from form
1015
-                    $valid_data = $email_validation_settings_form->valid_data();
1016
-                    if (isset($valid_data['email_validation_level'])) {
1017
-                        $email_validation_level = $valid_data['email_validation_level'];
1018
-                        // now if they want to use international email addresses
1019
-                        if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1020
-                            // in case we need to reset their email validation level,
1021
-                            // make sure that the previous value wasn't already set to one of the i18n options.
1022
-                            if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1023
-                                // if so, then reset it back to "basic" since that is the only other option that,
1024
-                                // despite offering poor validation, supports i18n email addresses
1025
-                                $prev_email_validation_level = 'basic';
1026
-                            }
1027
-                            // confirm our i18n email validation will work on the server
1028
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1029
-                                // or reset email validation level to previous value
1030
-                                $email_validation_level = $prev_email_validation_level;
1031
-                            }
1032
-                        }
1033
-                        $EE_Registration_Config->email_validation_level = $email_validation_level;
1034
-                    } else {
1035
-                        EE_Error::add_error(
1036
-                            esc_html__(
1037
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1038
-                                'event_espresso'
1039
-                            ),
1040
-                            __FILE__, __FUNCTION__, __LINE__
1041
-                        );
1042
-                    }
1043
-                } else {
1044
-                    if ($email_validation_settings_form->submission_error_message() !== '') {
1045
-                        EE_Error::add_error(
1046
-                            $email_validation_settings_form->submission_error_message(),
1047
-                            __FILE__, __FUNCTION__, __LINE__
1048
-                        );
1049
-                    }
1050
-                }
1051
-            }
1052
-        } catch (EE_Error $e) {
1053
-            $e->get_error();
1054
-        }
1055
-        return $EE_Registration_Config;
1056
-    }
1057
-
1058
-
1059
-    /**
1060
-     * confirms that the server's PHP version has the PCRE module enabled,
1061
-     * and that the PCRE version works with our i18n email validation
1062
-     *
1063
-     * @param \EE_Registration_Config $EE_Registration_Config
1064
-     * @param string                  $email_validation_level
1065
-     * @return bool
1066
-     */
1067
-    private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1068
-    {
1069
-        // first check that PCRE is enabled
1070
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1071
-            EE_Error::add_error(
1072
-                sprintf(
1073
-                    esc_html__(
1074
-                        'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1075
-                        'event_espresso'
1076
-                    ),
1077
-                    '<br />'
1078
-                ),
1079
-                __FILE__,
1080
-                __FUNCTION__,
1081
-                __LINE__
1082
-            );
1083
-            return false;
1084
-        } else {
1085
-            // PCRE support is enabled, but let's still
1086
-            // perform a test to see if the server will support it.
1087
-            // but first, save the updated validation level to the config,
1088
-            // so that the validation strategy picks it up.
1089
-            // this will get bumped back down if it doesn't work
1090
-            $EE_Registration_Config->email_validation_level = $email_validation_level;
1091
-            try {
1092
-                $email_validator    = new EE_Email_Validation_Strategy();
1093
-                $i18n_email_address = apply_filters(
1094
-                    'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1095
-                    'jägerjü[email protected]'
1096
-                );
1097
-                $email_validator->validate($i18n_email_address);
1098
-            } catch (Exception $e) {
1099
-                EE_Error::add_error(
1100
-                    sprintf(
1101
-                        esc_html__(
1102
-                            'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1103
-                            'event_espresso'
1104
-                        ),
1105
-                        '<br />',
1106
-                        '<a href="http://php.net/manual/en/pcre.installation.php" target="_blank">http://php.net/manual/en/pcre.installation.php</a>'
1107
-                    ),
1108
-                    __FILE__, __FUNCTION__, __LINE__
1109
-                );
1110
-                return false;
1111
-            }
1112
-        }
1113
-        return true;
1114
-    }
28
+	/**
29
+	 * @Constructor
30
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
31
+	 * @access public
32
+	 */
33
+	public function __construct($routing = true)
34
+	{
35
+		define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form' . DS);
36
+		define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets' . DS);
37
+		define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
38
+		define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates' . DS);
39
+		define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
40
+		parent::__construct($routing);
41
+	}
42
+
43
+
44
+	protected function _extend_page_config()
45
+	{
46
+		$this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
47
+		$qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
48
+		$qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID']) ? $this->_req_data['QSG_ID'] : 0;
49
+
50
+		$new_page_routes    = array(
51
+			'question_groups'    => array(
52
+				'func'       => '_question_groups_overview_list_table',
53
+				'capability' => 'ee_read_question_groups',
54
+			),
55
+			'add_question'       => array(
56
+				'func'       => '_edit_question',
57
+				'capability' => 'ee_edit_questions',
58
+			),
59
+			'insert_question'    => array(
60
+				'func'       => '_insert_or_update_question',
61
+				'args'       => array('new_question' => true),
62
+				'capability' => 'ee_edit_questions',
63
+				'noheader'   => true,
64
+			),
65
+			'duplicate_question' => array(
66
+				'func'       => '_duplicate_question',
67
+				'capability' => 'ee_edit_questions',
68
+				'noheader'   => true,
69
+			),
70
+			'trash_question'     => array(
71
+				'func'       => '_trash_question',
72
+				'capability' => 'ee_delete_question',
73
+				'obj_id'     => $qst_id,
74
+				'noheader'   => true,
75
+			),
76
+
77
+			'restore_question' => array(
78
+				'func'       => '_trash_or_restore_questions',
79
+				'capability' => 'ee_delete_question',
80
+				'obj_id'     => $qst_id,
81
+				'args'       => array('trash' => false),
82
+				'noheader'   => true,
83
+			),
84
+
85
+			'delete_question' => array(
86
+				'func'       => '_delete_question',
87
+				'capability' => 'ee_delete_question',
88
+				'obj_id'     => $qst_id,
89
+				'noheader'   => true,
90
+			),
91
+
92
+			'trash_questions' => array(
93
+				'func'       => '_trash_or_restore_questions',
94
+				'capability' => 'ee_delete_questions',
95
+				'args'       => array('trash' => true),
96
+				'noheader'   => true,
97
+			),
98
+
99
+			'restore_questions' => array(
100
+				'func'       => '_trash_or_restore_questions',
101
+				'capability' => 'ee_delete_questions',
102
+				'args'       => array('trash' => false),
103
+				'noheader'   => true,
104
+			),
105
+
106
+			'delete_questions' => array(
107
+				'func'       => '_delete_questions',
108
+				'args'       => array(),
109
+				'capability' => 'ee_delete_questions',
110
+				'noheader'   => true,
111
+			),
112
+
113
+			'add_question_group' => array(
114
+				'func'       => '_edit_question_group',
115
+				'capability' => 'ee_edit_question_groups',
116
+			),
117
+
118
+			'edit_question_group' => array(
119
+				'func'       => '_edit_question_group',
120
+				'capability' => 'ee_edit_question_group',
121
+				'obj_id'     => $qsg_id,
122
+				'args'       => array('edit'),
123
+			),
124
+
125
+			'delete_question_groups' => array(
126
+				'func'       => '_delete_question_groups',
127
+				'capability' => 'ee_delete_question_groups',
128
+				'noheader'   => true,
129
+			),
130
+
131
+			'delete_question_group' => array(
132
+				'func'       => '_delete_question_groups',
133
+				'capability' => 'ee_delete_question_group',
134
+				'obj_id'     => $qsg_id,
135
+				'noheader'   => true,
136
+			),
137
+
138
+			'trash_question_group' => array(
139
+				'func'       => '_trash_or_restore_question_groups',
140
+				'args'       => array('trash' => true),
141
+				'capability' => 'ee_delete_question_group',
142
+				'obj_id'     => $qsg_id,
143
+				'noheader'   => true,
144
+			),
145
+
146
+			'restore_question_group' => array(
147
+				'func'       => '_trash_or_restore_question_groups',
148
+				'args'       => array('trash' => false),
149
+				'capability' => 'ee_delete_question_group',
150
+				'obj_id'     => $qsg_id,
151
+				'noheader'   => true,
152
+			),
153
+
154
+			'insert_question_group' => array(
155
+				'func'       => '_insert_or_update_question_group',
156
+				'args'       => array('new_question_group' => true),
157
+				'capability' => 'ee_edit_question_groups',
158
+				'noheader'   => true,
159
+			),
160
+
161
+			'update_question_group' => array(
162
+				'func'       => '_insert_or_update_question_group',
163
+				'args'       => array('new_question_group' => false),
164
+				'capability' => 'ee_edit_question_group',
165
+				'obj_id'     => $qsg_id,
166
+				'noheader'   => true,
167
+			),
168
+
169
+			'trash_question_groups' => array(
170
+				'func'       => '_trash_or_restore_question_groups',
171
+				'args'       => array('trash' => true),
172
+				'capability' => 'ee_delete_question_groups',
173
+				'noheader'   => array('trash' => false),
174
+			),
175
+
176
+			'restore_question_groups' => array(
177
+				'func'       => '_trash_or_restore_question_groups',
178
+				'args'       => array('trash' => false),
179
+				'capability' => 'ee_delete_question_groups',
180
+				'noheader'   => true,
181
+			),
182
+
183
+
184
+			'espresso_update_question_group_order' => array(
185
+				'func'       => 'update_question_group_order',
186
+				'capability' => 'ee_edit_question_groups',
187
+				'noheader'   => true,
188
+			),
189
+
190
+			'view_reg_form_settings' => array(
191
+				'func'       => '_reg_form_settings',
192
+				'capability' => 'manage_options',
193
+			),
194
+
195
+			'update_reg_form_settings' => array(
196
+				'func'       => '_update_reg_form_settings',
197
+				'capability' => 'manage_options',
198
+				'noheader'   => true,
199
+			),
200
+		);
201
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
202
+
203
+		$new_page_config    = array(
204
+
205
+			'question_groups' => array(
206
+				'nav'           => array(
207
+					'label' => esc_html__('Question Groups', 'event_espresso'),
208
+					'order' => 20,
209
+				),
210
+				'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
211
+				'help_tabs'     => array(
212
+					'registration_form_question_groups_help_tab'                           => array(
213
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
214
+						'filename' => 'registration_form_question_groups',
215
+					),
216
+					'registration_form_question_groups_table_column_headings_help_tab'     => array(
217
+						'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
218
+						'filename' => 'registration_form_question_groups_table_column_headings',
219
+					),
220
+					'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
221
+						'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
222
+						'filename' => 'registration_form_question_groups_views_bulk_actions_search',
223
+					),
224
+				),
225
+				'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
226
+				'metaboxes'     => $this->_default_espresso_metaboxes,
227
+				'require_nonce' => false,
228
+				'qtips'         => array(
229
+					'EE_Registration_Form_Tips',
230
+				),
231
+			),
232
+
233
+			'add_question' => array(
234
+				'nav'           => array(
235
+					'label'      => esc_html__('Add Question', 'event_espresso'),
236
+					'order'      => 5,
237
+					'persistent' => false,
238
+				),
239
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
240
+				'help_tabs'     => array(
241
+					'registration_form_add_question_help_tab' => array(
242
+						'title'    => esc_html__('Add Question', 'event_espresso'),
243
+						'filename' => 'registration_form_add_question',
244
+					),
245
+				),
246
+				'help_tour'     => array('Registration_Form_Add_Question_Help_Tour'),
247
+				'require_nonce' => false,
248
+			),
249
+
250
+			'add_question_group' => array(
251
+				'nav'           => array(
252
+					'label'      => esc_html__('Add Question Group', 'event_espresso'),
253
+					'order'      => 5,
254
+					'persistent' => false,
255
+				),
256
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
257
+				'help_tabs'     => array(
258
+					'registration_form_add_question_group_help_tab' => array(
259
+						'title'    => esc_html__('Add Question Group', 'event_espresso'),
260
+						'filename' => 'registration_form_add_question_group',
261
+					),
262
+				),
263
+				'help_tour'     => array('Registration_Form_Add_Question_Group_Help_Tour'),
264
+				'require_nonce' => false,
265
+			),
266
+
267
+			'edit_question_group' => array(
268
+				'nav'           => array(
269
+					'label'      => esc_html__('Edit Question Group', 'event_espresso'),
270
+					'order'      => 5,
271
+					'persistent' => false,
272
+					'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(array('question_group_id' => $this->_req_data['question_group_id']),
273
+						$this->_current_page_view_url) : $this->_admin_base_url,
274
+				),
275
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
276
+				'help_tabs'     => array(
277
+					'registration_form_edit_question_group_help_tab' => array(
278
+						'title'    => esc_html__('Edit Question Group', 'event_espresso'),
279
+						'filename' => 'registration_form_edit_question_group',
280
+					),
281
+				),
282
+				'help_tour'     => array('Registration_Form_Edit_Question_Group_Help_Tour'),
283
+				'require_nonce' => false,
284
+			),
285
+
286
+			'view_reg_form_settings' => array(
287
+				'nav'           => array(
288
+					'label' => esc_html__('Reg Form Settings', 'event_espresso'),
289
+					'order' => 40,
290
+				),
291
+				'labels'        => array(
292
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
293
+				),
294
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
295
+				'help_tabs'     => array(
296
+					'registration_form_reg_form_settings_help_tab' => array(
297
+						'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
298
+						'filename' => 'registration_form_reg_form_settings',
299
+					),
300
+				),
301
+				'help_tour'     => array('Registration_Form_Settings_Help_Tour'),
302
+				'require_nonce' => false,
303
+			),
304
+
305
+		);
306
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
307
+
308
+		//change the list table we're going to use so it's the NEW list table!
309
+		$this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
310
+
311
+
312
+		//additional labels
313
+		$new_labels               = array(
314
+			'add_question'          => esc_html__('Add New Question', 'event_espresso'),
315
+			'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
316
+			'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
317
+			'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
318
+			'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
319
+		);
320
+		$this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
321
+
322
+	}
323
+
324
+
325
+	protected function _ajax_hooks()
326
+	{
327
+		add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
328
+	}
329
+
330
+
331
+	public function load_scripts_styles_question_groups()
332
+	{
333
+		wp_enqueue_script('espresso_ajax_table_sorting');
334
+	}
335
+
336
+
337
+	public function load_scripts_styles_add_question_group()
338
+	{
339
+		$this->load_scripts_styles_forms();
340
+		$this->load_sortable_question_script();
341
+	}
342
+
343
+	public function load_scripts_styles_edit_question_group()
344
+	{
345
+		$this->load_scripts_styles_forms();
346
+		$this->load_sortable_question_script();
347
+	}
348
+
349
+
350
+	/**
351
+	 * registers and enqueues script for questions
352
+	 *
353
+	 * @return void
354
+	 */
355
+	public function load_sortable_question_script()
356
+	{
357
+		wp_register_script('ee-question-sortable', REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
358
+			array('jquery-ui-sortable'), EVENT_ESPRESSO_VERSION, true);
359
+		wp_enqueue_script('ee-question-sortable');
360
+	}
361
+
362
+
363
+	protected function _set_list_table_views_default()
364
+	{
365
+		$this->_views = array(
366
+			'all' => array(
367
+				'slug'        => 'all',
368
+				'label'       => esc_html__('View All Questions', 'event_espresso'),
369
+				'count'       => 0,
370
+				'bulk_action' => array(
371
+					'trash_questions' => esc_html__('Trash', 'event_espresso'),
372
+				),
373
+			),
374
+		);
375
+
376
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
377
+			'espresso_registration_form_trash_questions')
378
+		) {
379
+			$this->_views['trash'] = array(
380
+				'slug'        => 'trash',
381
+				'label'       => esc_html__('Trash', 'event_espresso'),
382
+				'count'       => 0,
383
+				'bulk_action' => array(
384
+					'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
385
+					'restore_questions' => esc_html__('Restore', 'event_espresso'),
386
+				),
387
+			);
388
+		}
389
+	}
390
+
391
+
392
+	protected function _set_list_table_views_question_groups()
393
+	{
394
+		$this->_views = array(
395
+			'all' => array(
396
+				'slug'        => 'all',
397
+				'label'       => esc_html__('All', 'event_espresso'),
398
+				'count'       => 0,
399
+				'bulk_action' => array(
400
+					'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
401
+				),
402
+			),
403
+		);
404
+
405
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_question_groups',
406
+			'espresso_registration_form_trash_question_groups')
407
+		) {
408
+			$this->_views['trash'] = array(
409
+				'slug'        => 'trash',
410
+				'label'       => esc_html__('Trash', 'event_espresso'),
411
+				'count'       => 0,
412
+				'bulk_action' => array(
413
+					'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
414
+					'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
415
+				),
416
+			);
417
+		}
418
+	}
419
+
420
+
421
+	protected function _questions_overview_list_table()
422
+	{
423
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
424
+				'add_question',
425
+				'add_question',
426
+				array(),
427
+				'add-new-h2'
428
+			);
429
+		parent::_questions_overview_list_table();
430
+	}
431
+
432
+
433
+	protected function _question_groups_overview_list_table()
434
+	{
435
+		$this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
436
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
437
+				'add_question_group',
438
+				'add_question_group',
439
+				array(),
440
+				'add-new-h2'
441
+			);
442
+		$this->display_admin_list_table_page_with_sidebar();
443
+	}
444
+
445
+
446
+	protected function _delete_question()
447
+	{
448
+		$success = $this->_delete_items($this->_question_model);
449
+		$this->_redirect_after_action(
450
+			$success,
451
+			$this->_question_model->item_name($success),
452
+			'deleted',
453
+			array('action' => 'default', 'status' => 'all')
454
+		);
455
+	}
456
+
457
+
458
+	protected function _delete_questions()
459
+	{
460
+		$success = $this->_delete_items($this->_question_model);
461
+		$this->_redirect_after_action(
462
+			$success,
463
+			$this->_question_model->item_name($success),
464
+			'deleted permanently',
465
+			array('action' => 'default', 'status' => 'trash')
466
+		);
467
+	}
468
+
469
+
470
+	/**
471
+	 * Performs the deletion of a single or multiple questions or question groups.
472
+	 *
473
+	 * @param EEM_Soft_Delete_Base $model
474
+	 * @return int number of items deleted permanently
475
+	 */
476
+	private function _delete_items(EEM_Soft_Delete_Base $model)
477
+	{
478
+		$success = 0;
479
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
480
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
481
+			// if array has more than one element than success message should be plural
482
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
483
+			// cycle thru bulk action checkboxes
484
+			while (list($ID, $value) = each($this->_req_data['checkbox'])) {
485
+				if (! $this->_delete_item($ID, $model)) {
486
+					$success = 0;
487
+				}
488
+			}
489
+
490
+		} elseif (! empty($this->_req_data['QSG_ID'])) {
491
+			$success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
492
+
493
+		} elseif (! empty($this->_req_data['QST_ID'])) {
494
+			$success = $this->_delete_item($this->_req_data['QST_ID'], $model);
495
+		} else {
496
+			EE_Error::add_error(sprintf(esc_html__("No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
497
+				"event_espresso")), __FILE__, __FUNCTION__, __LINE__);
498
+		}
499
+		return $success;
500
+	}
501
+
502
+	/**
503
+	 * Deletes the specified question (and its associated question options) or question group
504
+	 *
505
+	 * @param int                  $id
506
+	 * @param EEM_Soft_Delete_Base $model
507
+	 * @return boolean
508
+	 */
509
+	protected function _delete_item($id, $model)
510
+	{
511
+		if ($model instanceof EEM_Question) {
512
+			EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
513
+		}
514
+		return $model->delete_permanently_by_ID(absint($id));
515
+	}
516
+
517
+
518
+	/******************************    QUESTION GROUPS    ******************************/
519
+
520
+
521
+	protected function _edit_question_group($type = 'add')
522
+	{
523
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
524
+		$ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID']) ? absint($this->_req_data['QSG_ID']) : false;
525
+
526
+		switch ($this->_req_action) {
527
+			case 'add_question_group' :
528
+				$this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
529
+				break;
530
+			case 'edit_question_group' :
531
+				$this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
532
+				break;
533
+			default :
534
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
535
+		}
536
+		// add ID to title if editing
537
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
538
+		if ($ID) {
539
+			/** @var EE_Question_Group $questionGroup */
540
+			$questionGroup            = $this->_question_group_model->get_one_by_ID($ID);
541
+			$additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
542
+			$this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
543
+		} else {
544
+			/** @var EE_Question_Group $questionGroup */
545
+			$questionGroup = EEM_Question_Group::instance()->create_default_object();
546
+			$questionGroup->set_order_to_latest();
547
+			$this->_set_add_edit_form_tags('insert_question_group');
548
+		}
549
+		$this->_template_args['values']         = $this->_yes_no_values;
550
+		$this->_template_args['all_questions']  = $questionGroup->questions_in_and_not_in_group();
551
+		$this->_template_args['QSG_ID']         = $ID ? $ID : true;
552
+		$this->_template_args['question_group'] = $questionGroup;
553
+
554
+		$redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
555
+		$this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
556
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
557
+			$this->_template_args, true);
558
+
559
+		// the details template wrapper
560
+		$this->display_admin_page_with_sidebar();
561
+	}
562
+
563
+
564
+	protected function _delete_question_groups()
565
+	{
566
+		$success = $this->_delete_items($this->_question_group_model);
567
+		$this->_redirect_after_action($success, $this->_question_group_model->item_name($success),
568
+			'deleted permanently', array('action' => 'question_groups', 'status' => 'trash'));
569
+	}
570
+
571
+
572
+	/**
573
+	 * @param bool $new_question_group
574
+	 */
575
+	protected function _insert_or_update_question_group($new_question_group = true)
576
+	{
577
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
578
+		$set_column_values = $this->_set_column_values_for($this->_question_group_model);
579
+		if ($new_question_group) {
580
+			$QSG_ID  = $this->_question_group_model->insert($set_column_values);
581
+			$success = $QSG_ID ? 1 : 0;
582
+		} else {
583
+			$QSG_ID = absint($this->_req_data['QSG_ID']);
584
+			unset($set_column_values['QSG_ID']);
585
+			$success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
586
+		}
587
+		$phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(EEM_Attendee::system_question_phone);
588
+		// update the existing related questions
589
+		// BUT FIRST...  delete the phone question from the Question_Group_Question if it is being added to this question group (therefore removed from the existing group)
590
+		if (isset($this->_req_data['questions'], $this->_req_data['questions'][$phone_question_id])) {
591
+			// delete where QST ID = system phone question ID and Question Group ID is NOT this group
592
+			EEM_Question_Group_Question::instance()->delete(array(
593
+				array(
594
+					'QST_ID' => $phone_question_id,
595
+					'QSG_ID' => array('!=', $QSG_ID),
596
+				),
597
+			));
598
+		}
599
+		/** @type EE_Question_Group $question_group */
600
+		$question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
601
+		$questions      = $question_group->questions();
602
+		// make sure system phone question is added to list of questions for this group
603
+		if (! isset($questions[$phone_question_id])) {
604
+			$questions[$phone_question_id] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
605
+		}
606
+
607
+		foreach ($questions as $question_ID => $question) {
608
+			// first we always check for order.
609
+			if (! empty($this->_req_data['question_orders'][$question_ID])) {
610
+				//update question order
611
+				$question_group->update_question_order($question_ID, $this->_req_data['question_orders'][$question_ID]);
612
+			}
613
+
614
+			// then we always check if adding or removing.
615
+			if (isset($this->_req_data['questions'], $this->_req_data['questions'][$question_ID])) {
616
+				$question_group->add_question($question_ID);
617
+			} else {
618
+				// not found, remove it (but only if not a system question for the personal group with the exception of lname system question - we allow removal of it)
619
+				if (
620
+				in_array(
621
+					$question->system_ID(),
622
+					EEM_Question::instance()->required_system_questions_in_system_question_group($question_group->system_group())
623
+				)
624
+				) {
625
+					continue;
626
+				} else {
627
+					$question_group->remove_question($question_ID);
628
+				}
629
+			}
630
+		}
631
+		// save new related questions
632
+		if (isset($this->_req_data['questions'])) {
633
+			foreach ($this->_req_data['questions'] as $QST_ID) {
634
+				$question_group->add_question($QST_ID);
635
+				if (isset($this->_req_data['question_orders'][$QST_ID])) {
636
+					$question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][$QST_ID]);
637
+				}
638
+			}
639
+		}
640
+
641
+		if ($success !== false) {
642
+			$msg = $new_question_group ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
643
+				$this->_question_group_model->item_name()) : sprintf(esc_html__('The %s has been updated',
644
+				'event_espresso'), $this->_question_group_model->item_name());
645
+			EE_Error::add_success($msg);
646
+		}
647
+		$this->_redirect_after_action(false, '', '', array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
648
+			true);
649
+
650
+	}
651
+
652
+	/**
653
+	 * duplicates a question and all its question options and redirects to the new question.
654
+	 */
655
+	public function _duplicate_question()
656
+	{
657
+		$question_ID = (int)$this->_req_data['QST_ID'];
658
+		$question    = EEM_Question::instance()->get_one_by_ID($question_ID);
659
+		if ($question instanceof EE_Question) {
660
+			$new_question = $question->duplicate();
661
+			if ($new_question instanceof EE_Question) {
662
+				$this->_redirect_after_action(true, esc_html__('Question', 'event_espresso'),
663
+					esc_html__('Duplicated', 'event_espresso'),
664
+					array('action' => 'edit_question', 'QST_ID' => $new_question->ID()), true);
665
+			} else {
666
+				global $wpdb;
667
+				EE_Error::add_error(sprintf(esc_html__('Could not duplicate question with ID %1$d because: %2$s',
668
+					'event_espresso'), $question_ID, $wpdb->last_error), __FILE__, __FUNCTION__, __LINE__);
669
+				$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
670
+			}
671
+		} else {
672
+			EE_Error::add_error(sprintf(esc_html__('Could not duplicate question with ID %d because it didn\'t exist!',
673
+				'event_espresso'), $question_ID), __FILE__, __FUNCTION__, __LINE__);
674
+			$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
675
+		}
676
+	}
677
+
678
+
679
+	/**
680
+	 * @param bool $trash
681
+	 */
682
+	protected function _trash_or_restore_question_groups($trash = true)
683
+	{
684
+		$this->_trash_or_restore_items($this->_question_group_model, $trash);
685
+	}
686
+
687
+
688
+	/**
689
+	 *_trash_question
690
+	 */
691
+	protected function _trash_question()
692
+	{
693
+		$success    = $this->_question_model->delete_by_ID((int)$this->_req_data['QST_ID']);
694
+		$query_args = array('action' => 'default', 'status' => 'all');
695
+		$this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
696
+	}
697
+
698
+
699
+	/**
700
+	 * @param bool $trash
701
+	 */
702
+	protected function _trash_or_restore_questions($trash = true)
703
+	{
704
+		$this->_trash_or_restore_items($this->_question_model, $trash);
705
+	}
706
+
707
+
708
+	/**
709
+	 * Internally used to delete or restore items, using the request data. Meant to be
710
+	 * flexible between question or question groups
711
+	 *
712
+	 * @param EEM_Soft_Delete_Base $model
713
+	 * @param boolean              $trash whether to trash or restore
714
+	 */
715
+	private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
716
+	{
717
+
718
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
719
+
720
+		$success = 1;
721
+		//Checkboxes
722
+		//echo "trash $trash";
723
+		//var_dump($this->_req_data['checkbox']);die;
724
+		if (isset($this->_req_data['checkbox'])) {
725
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
726
+				// if array has more than one element than success message should be plural
727
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
728
+				// cycle thru bulk action checkboxes
729
+				while (list($ID, $value) = each($this->_req_data['checkbox'])) {
730
+					if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
731
+						$success = 0;
732
+					}
733
+				}
734
+
735
+			} else {
736
+				// grab single id and delete
737
+				$ID = absint($this->_req_data['checkbox']);
738
+				if (! $model->delete_or_restore_by_ID($trash, $ID)) {
739
+					$success = 0;
740
+				}
741
+			}
742
+
743
+		} else {
744
+			// delete via trash link
745
+			// grab single id and delete
746
+			$ID = absint($this->_req_data[$model->primary_key_name()]);
747
+			if (! $model->delete_or_restore_by_ID($trash, $ID)) {
748
+				$success = 0;
749
+			}
750
+
751
+		}
752
+
753
+
754
+		$action = $model instanceof EEM_Question ? 'default' : 'question_groups';//strtolower( $model->item_name(2) );
755
+		//echo "action :$action";
756
+		//$action = 'questions' ? 'default' : $action;
757
+		if ($trash) {
758
+			$action_desc = 'trashed';
759
+			$status      = 'trash';
760
+		} else {
761
+			$action_desc = 'restored';
762
+			$status      = 'all';
763
+		}
764
+		$this->_redirect_after_action($success, $model->item_name($success), $action_desc,
765
+			array('action' => $action, 'status' => $status));
766
+	}
767
+
768
+
769
+	/**
770
+	 * @param            $per_page
771
+	 * @param int        $current_page
772
+	 * @param bool|false $count
773
+	 * @return \EE_Soft_Delete_Base_Class[]|int
774
+	 */
775
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
776
+	{
777
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
778
+
779
+		if ($count) {
780
+			//note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
781
+			$where   = isset($query_params[0]) ? array($query_params[0]) : array();
782
+			$results = $this->_question_model->count_deleted($where);
783
+		} else {
784
+			//note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
785
+			$results = $this->_question_model->get_all_deleted($query_params);
786
+		}
787
+		return $results;
788
+	}
789
+
790
+
791
+	/**
792
+	 * @param            $per_page
793
+	 * @param int        $current_page
794
+	 * @param bool|false $count
795
+	 * @return \EE_Soft_Delete_Base_Class[]
796
+	 */
797
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
798
+	{
799
+		$questionGroupModel = EEM_Question_Group::instance();
800
+		$query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
801
+		if ($count) {
802
+			$where   = isset($query_params[0]) ? array($query_params[0]) : array();
803
+			$results = $questionGroupModel->count($where);
804
+		} else {
805
+			$results = $questionGroupModel->get_all($query_params);
806
+		}
807
+		return $results;
808
+	}
809
+
810
+
811
+	/**
812
+	 * @param      $per_page
813
+	 * @param int  $current_page
814
+	 * @param bool $count
815
+	 * @return \EE_Soft_Delete_Base_Class[]|int
816
+	 */
817
+	public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
818
+	{
819
+		$questionGroupModel = EEM_Question_Group::instance();
820
+		$query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
821
+		if ($count) {
822
+			$where                 = isset($query_params[0]) ? array($query_params[0]) : array();
823
+			$query_params['limit'] = null;
824
+			$results               = $questionGroupModel->count_deleted($where);
825
+		} else {
826
+			$results = $questionGroupModel->get_all_deleted($query_params);
827
+		}
828
+		return $results;
829
+	}
830
+
831
+
832
+	/**
833
+	 * method for performing updates to question order
834
+	 *
835
+	 * @return array results array
836
+	 */
837
+	public function update_question_group_order()
838
+	{
839
+
840
+		$success = esc_html__('Question group order was updated successfully.', 'event_espresso');
841
+
842
+		// grab our row IDs
843
+		$row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
844
+			? explode(',', rtrim($this->_req_data['row_ids'], ','))
845
+			: array();
846
+
847
+		$perpage = ! empty($this->_req_data['perpage'])
848
+			? (int)$this->_req_data['perpage']
849
+			: null;
850
+		$curpage = ! empty($this->_req_data['curpage'])
851
+			? (int)$this->_req_data['curpage']
852
+			: null;
853
+
854
+		if (! empty($row_ids)) {
855
+			//figure out where we start the row_id count at for the current page.
856
+			$qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
857
+
858
+			$row_count = count($row_ids);
859
+			for ($i = 0; $i < $row_count; $i++) {
860
+				//Update the questions when re-ordering
861
+				$updated = EEM_Question_Group::instance()->update(
862
+					array('QSG_order' => $qsgcount),
863
+					array(array('QSG_ID' => $row_ids[$i]))
864
+				);
865
+				if ($updated === false) {
866
+					$success = false;
867
+				}
868
+				$qsgcount++;
869
+			}
870
+		} else {
871
+			$success = false;
872
+		}
873
+
874
+		$errors = ! $success
875
+			? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
876
+			: false;
877
+
878
+		echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
879
+		die();
880
+
881
+	}
882
+
883
+
884
+
885
+	/***************************************        REGISTRATION SETTINGS        ***************************************/
886
+
887
+
888
+	/**
889
+	 * _reg_form_settings
890
+	 *
891
+	 * @throws \EE_Error
892
+	 */
893
+	protected function _reg_form_settings()
894
+	{
895
+		$this->_template_args['values'] = $this->_yes_no_values;
896
+		add_action(
897
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
898
+			array($this, 'email_validation_settings_form'),
899
+			2
900
+		);
901
+		$this->_template_args = (array)apply_filters(
902
+			'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
903
+			$this->_template_args
904
+		);
905
+		$this->_set_add_edit_form_tags('update_reg_form_settings');
906
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
907
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
908
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
909
+			$this->_template_args,
910
+			true
911
+		);
912
+		$this->display_admin_page_with_sidebar();
913
+	}
914
+
915
+
916
+	/**
917
+	 * _update_reg_form_settings
918
+	 */
919
+	protected function _update_reg_form_settings()
920
+	{
921
+		EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
922
+			EE_Registry::instance()->CFG->registration
923
+		);
924
+		EE_Registry::instance()->CFG->registration = apply_filters(
925
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
926
+			EE_Registry::instance()->CFG->registration
927
+		);
928
+		$success                                   = $this->_update_espresso_configuration(
929
+			esc_html__('Registration Form Options', 'event_espresso'),
930
+			EE_Registry::instance()->CFG,
931
+			__FILE__, __FUNCTION__, __LINE__
932
+		);
933
+		$this->_redirect_after_action($success, esc_html__('Registration Form Options', 'event_espresso'), 'updated',
934
+			array('action' => 'view_reg_form_settings'));
935
+	}
936
+
937
+
938
+	/**
939
+	 * email_validation_settings_form
940
+	 *
941
+	 * @access    public
942
+	 * @return    void
943
+	 * @throws \EE_Error
944
+	 */
945
+	public function email_validation_settings_form()
946
+	{
947
+		echo $this->_email_validation_settings_form()->get_html();
948
+	}
949
+
950
+
951
+	/**
952
+	 * _email_validation_settings_form
953
+	 *
954
+	 * @access protected
955
+	 * @return EE_Form_Section_Proper
956
+	 * @throws \EE_Error
957
+	 */
958
+	protected function _email_validation_settings_form()
959
+	{
960
+		return new EE_Form_Section_Proper(
961
+			array(
962
+				'name'            => 'email_validation_settings',
963
+				'html_id'         => 'email_validation_settings',
964
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
965
+				'subsections'     => apply_filters(
966
+					'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
967
+					array(
968
+						'email_validation_hdr'   => new EE_Form_Section_HTML(
969
+							EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
970
+						),
971
+						'email_validation_level' => new EE_Select_Input(
972
+							array(
973
+								'basic'      => esc_html__('Basic', 'event_espresso'),
974
+								'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
975
+								'i18n'       => esc_html__('International', 'event_espresso'),
976
+								'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
977
+							),
978
+							array(
979
+								'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
980
+													 . EEH_Template::get_help_tab_link('email_validation_info'),
981
+								'html_help_text'  => esc_html__('These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
982
+									'event_espresso'),
983
+								'default'         => isset(EE_Registry::instance()->CFG->registration->email_validation_level)
984
+									? EE_Registry::instance()->CFG->registration->email_validation_level
985
+									: 'wp_default',
986
+								'required'        => false,
987
+							)
988
+						),
989
+					)
990
+				),
991
+			)
992
+		);
993
+	}
994
+
995
+
996
+	/**
997
+	 * update_email_validation_settings_form
998
+	 *
999
+	 * @access    public
1000
+	 * @param \EE_Registration_Config $EE_Registration_Config
1001
+	 * @return \EE_Registration_Config
1002
+	 */
1003
+	public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1004
+	{
1005
+		$prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1006
+		try {
1007
+			$email_validation_settings_form = $this->_email_validation_settings_form();
1008
+			// if not displaying a form, then check for form submission
1009
+			if ($email_validation_settings_form->was_submitted()) {
1010
+				// capture form data
1011
+				$email_validation_settings_form->receive_form_submission();
1012
+				// validate form data
1013
+				if ($email_validation_settings_form->is_valid()) {
1014
+					// grab validated data from form
1015
+					$valid_data = $email_validation_settings_form->valid_data();
1016
+					if (isset($valid_data['email_validation_level'])) {
1017
+						$email_validation_level = $valid_data['email_validation_level'];
1018
+						// now if they want to use international email addresses
1019
+						if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1020
+							// in case we need to reset their email validation level,
1021
+							// make sure that the previous value wasn't already set to one of the i18n options.
1022
+							if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1023
+								// if so, then reset it back to "basic" since that is the only other option that,
1024
+								// despite offering poor validation, supports i18n email addresses
1025
+								$prev_email_validation_level = 'basic';
1026
+							}
1027
+							// confirm our i18n email validation will work on the server
1028
+							if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1029
+								// or reset email validation level to previous value
1030
+								$email_validation_level = $prev_email_validation_level;
1031
+							}
1032
+						}
1033
+						$EE_Registration_Config->email_validation_level = $email_validation_level;
1034
+					} else {
1035
+						EE_Error::add_error(
1036
+							esc_html__(
1037
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1038
+								'event_espresso'
1039
+							),
1040
+							__FILE__, __FUNCTION__, __LINE__
1041
+						);
1042
+					}
1043
+				} else {
1044
+					if ($email_validation_settings_form->submission_error_message() !== '') {
1045
+						EE_Error::add_error(
1046
+							$email_validation_settings_form->submission_error_message(),
1047
+							__FILE__, __FUNCTION__, __LINE__
1048
+						);
1049
+					}
1050
+				}
1051
+			}
1052
+		} catch (EE_Error $e) {
1053
+			$e->get_error();
1054
+		}
1055
+		return $EE_Registration_Config;
1056
+	}
1057
+
1058
+
1059
+	/**
1060
+	 * confirms that the server's PHP version has the PCRE module enabled,
1061
+	 * and that the PCRE version works with our i18n email validation
1062
+	 *
1063
+	 * @param \EE_Registration_Config $EE_Registration_Config
1064
+	 * @param string                  $email_validation_level
1065
+	 * @return bool
1066
+	 */
1067
+	private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1068
+	{
1069
+		// first check that PCRE is enabled
1070
+		if (! defined('PREG_BAD_UTF8_ERROR')) {
1071
+			EE_Error::add_error(
1072
+				sprintf(
1073
+					esc_html__(
1074
+						'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1075
+						'event_espresso'
1076
+					),
1077
+					'<br />'
1078
+				),
1079
+				__FILE__,
1080
+				__FUNCTION__,
1081
+				__LINE__
1082
+			);
1083
+			return false;
1084
+		} else {
1085
+			// PCRE support is enabled, but let's still
1086
+			// perform a test to see if the server will support it.
1087
+			// but first, save the updated validation level to the config,
1088
+			// so that the validation strategy picks it up.
1089
+			// this will get bumped back down if it doesn't work
1090
+			$EE_Registration_Config->email_validation_level = $email_validation_level;
1091
+			try {
1092
+				$email_validator    = new EE_Email_Validation_Strategy();
1093
+				$i18n_email_address = apply_filters(
1094
+					'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1095
+					'jägerjü[email protected]'
1096
+				);
1097
+				$email_validator->validate($i18n_email_address);
1098
+			} catch (Exception $e) {
1099
+				EE_Error::add_error(
1100
+					sprintf(
1101
+						esc_html__(
1102
+							'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1103
+							'event_espresso'
1104
+						),
1105
+						'<br />',
1106
+						'<a href="http://php.net/manual/en/pcre.installation.php" target="_blank">http://php.net/manual/en/pcre.installation.php</a>'
1107
+					),
1108
+					__FILE__, __FUNCTION__, __LINE__
1109
+				);
1110
+				return false;
1111
+			}
1112
+		}
1113
+		return true;
1114
+	}
1115 1115
 
1116 1116
 
1117 1117
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/Model_Data_Translator.php 2 patches
Indentation   +521 added lines, -521 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 namespace EventEspresso\core\libraries\rest_api;
3 3
 
4 4
 if (! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -26,525 +26,525 @@  discard block
 block discarded – undo
26 26
 class Model_Data_Translator
27 27
 {
28 28
 
29
-    /**
30
-     * We used to use -1 for infinity in the rest api, but that's ambiguous for
31
-     * fields that COULD contain -1; so we use null
32
-     */
33
-    const ee_inf_in_rest = null;
34
-
35
-
36
-
37
-    /**
38
-     * Prepares a possible array of input values from JSON for use by the models
39
-     *
40
-     * @param \EE_Model_Field_Base $field_obj
41
-     * @param mixed                $original_value_maybe_array
42
-     * @param string               $requested_version
43
-     * @param string               $timezone_string treat values as being in this timezone
44
-     * @return mixed
45
-     * @throws \DomainException
46
-     */
47
-    public static function prepare_field_values_from_json(
48
-        $field_obj,
49
-        $original_value_maybe_array,
50
-        $requested_version,
51
-        $timezone_string = 'UTC'
52
-    ) {
53
-        if (is_array($original_value_maybe_array)) {
54
-            $new_value_maybe_array = array();
55
-            foreach ($original_value_maybe_array as $array_key => $array_item) {
56
-                $new_value_maybe_array[$array_key] = Model_Data_Translator::prepare_field_value_from_json(
57
-                    $field_obj,
58
-                    $array_item,
59
-                    $requested_version,
60
-                    $timezone_string
61
-                );
62
-            }
63
-        } else {
64
-            $new_value_maybe_array = Model_Data_Translator::prepare_field_value_from_json(
65
-                $field_obj,
66
-                $original_value_maybe_array,
67
-                $requested_version,
68
-                $timezone_string
69
-            );
70
-        }
71
-        return $new_value_maybe_array;
72
-    }
73
-
74
-
75
-
76
-    /**
77
-     * Prepares an array of field values FOR use in JSON/REST API
78
-     *
79
-     * @param \EE_Model_Field_Base $field_obj
80
-     * @param mixed                $original_value_maybe_array
81
-     * @param string               $request_version (eg 4.8.36)
82
-     * @return array
83
-     */
84
-    public static function prepare_field_values_for_json($field_obj, $original_value_maybe_array, $request_version)
85
-    {
86
-        if (is_array($original_value_maybe_array)) {
87
-            $new_value_maybe_array = array();
88
-            foreach ($original_value_maybe_array as $array_key => $array_item) {
89
-                $new_value_maybe_array[$array_key] = Model_Data_Translator::prepare_field_value_for_json(
90
-                    $field_obj,
91
-                    $array_item,
92
-                    $request_version
93
-                );
94
-            }
95
-        } else {
96
-            $new_value_maybe_array = Model_Data_Translator::prepare_field_value_for_json(
97
-                $field_obj,
98
-                $original_value_maybe_array,
99
-                $request_version
100
-            );
101
-        }
102
-        return $new_value_maybe_array;
103
-    }
104
-
105
-
106
-
107
-    /**
108
-     * Prepares incoming data from the json or $_REQUEST parameters for the models'
109
-     * "$query_params".
110
-     *
111
-     * @param \EE_Model_Field_Base $field_obj
112
-     * @param mixed                $original_value
113
-     * @param string               $requested_version
114
-     * @param string               $timezone_string treat values as being in this timezone
115
-     * @return mixed
116
-     * @throws \DomainException
117
-     */
118
-    public static function prepare_field_value_from_json(
119
-        $field_obj,
120
-        $original_value,
121
-        $requested_version,
122
-        $timezone_string = 'UTC' // UTC
123
-    )
124
-    {
125
-        $timezone_string = $timezone_string !== '' ? $timezone_string : get_option('timezone_string', '');
126
-        $new_value = null;
127
-        if ($field_obj instanceof \EE_Infinite_Integer_Field
128
-            && in_array($original_value, array(null, ''), true)
129
-        ) {
130
-            $new_value = EE_INF;
131
-        } elseif ($field_obj instanceof \EE_Datetime_Field) {
132
-            list($offset_sign, $offset_secs) = Model_Data_Translator::parse_timezone_offset(
133
-                $field_obj->get_timezone_offset(
134
-                    new \DateTimeZone($timezone_string)
135
-                )
136
-            );
137
-            $offset_string =
138
-                str_pad(
139
-                    floor($offset_secs / HOUR_IN_SECONDS),
140
-                    2,
141
-                    '0',
142
-                    STR_PAD_LEFT
143
-                )
144
-                . ':'
145
-                . str_pad(
146
-                    ($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
147
-                    2,
148
-                    '0',
149
-                    STR_PAD_LEFT
150
-                );
151
-            $new_value = rest_parse_date($original_value . $offset_sign . $offset_string);
152
-        } else {
153
-            $new_value = $original_value;
154
-        }
155
-        return $new_value;
156
-    }
157
-
158
-
159
-
160
-    /**
161
-     * determines what's going on with them timezone strings
162
-     *
163
-     * @param int $timezone_offset
164
-     * @return array
165
-     */
166
-    private static function parse_timezone_offset($timezone_offset)
167
-    {
168
-        $first_char = substr((string)$timezone_offset, 0, 1);
169
-        if ($first_char === '+' || $first_char === '-') {
170
-            $offset_sign = $first_char;
171
-            $offset_secs = substr((string)$timezone_offset, 1);
172
-        } else {
173
-            $offset_sign = '+';
174
-            $offset_secs = $timezone_offset;
175
-        }
176
-        return array($offset_sign, $offset_secs);
177
-    }
178
-
179
-
180
-
181
-    /**
182
-     * Prepares a field's value for display in the API.
183
-     * The $original_value should be in the model object's domain of values, see the explanation at the top of EEM_Base.
184
-     * However, for backward compatibility, we also attempt to handle $original_values from the
185
-     * model client-code domain, and from the database domain.
186
-     * E.g., when working with EE_Datetime_Fields, $original_value should be a DateTime or DbSafeDateTime
187
-     * (model object domain). However, for backward compatibility, we also accept a unix timestamp
188
-     * (old model object domain), MySQL datetime string (database domain) or string formatted according to the
189
-     * WP Datetime format (model client-code domain)
190
-     *
191
-     * @param \EE_Model_Field_Base $field_obj
192
-     * @param mixed                $original_value
193
-     * @param string               $requested_version
194
-     * @return mixed
195
-     */
196
-    public static function prepare_field_value_for_json($field_obj, $original_value, $requested_version)
197
-    {
198
-        if ($original_value === EE_INF) {
199
-            $new_value = Model_Data_Translator::ee_inf_in_rest;
200
-        } elseif ($field_obj instanceof \EE_Datetime_Field) {
201
-            if (is_string($original_value)) {
202
-                //did they submit a string of a unix timestamp?
203
-                if (is_numeric($original_value)) {
204
-                    $datetime_obj = new \DateTime();
205
-                    $datetime_obj->setTimestamp((int)$original_value);
206
-                } else {
207
-                    //first, check if its a MySQL timestamp in GMT
208
-                    $datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
209
-                }
210
-                if (! $datetime_obj instanceof \DateTime) {
211
-                    //so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
212
-                    $datetime_obj = $field_obj->prepare_for_set($original_value);
213
-                }
214
-                $original_value = $datetime_obj;
215
-            }
216
-            if ($original_value instanceof \DateTime) {
217
-                $new_value = $original_value->format('Y-m-d H:i:s');
218
-            } elseif (is_int($original_value)) {
219
-                $new_value = date('Y-m-d H:i:s', $original_value);
220
-            } elseif($original_value === null || $original_value === '') {
221
-                $new_value = null;
222
-            } else {
223
-                //so it's not a datetime object, unix timestamp (as string or int),
224
-                //MySQL timestamp, or even a string in the field object's format. So no idea what it is
225
-                throw new \EE_Error(
226
-                    sprintf(
227
-                        esc_html__(
228
-                            // @codingStandardsIgnoreStart
229
-                            'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
230
-                            // @codingStandardsIgnoreEnd
231
-                            'event_espressso'
232
-                        ),
233
-                        $original_value,
234
-                        $field_obj->get_name(),
235
-                        $field_obj->get_model_name(),
236
-                        $field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
237
-                    )
238
-                );
239
-            }
240
-            $new_value = mysql_to_rfc3339($new_value);
241
-        } else {
242
-            $new_value = $original_value;
243
-        }
244
-        return apply_filters(
245
-            'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
246
-            $new_value,
247
-            $field_obj,
248
-            $original_value,
249
-            $requested_version
250
-        );
251
-    }
252
-
253
-
254
-
255
-    /**
256
-     * Prepares condition-query-parameters (like what's in where and having) from
257
-     * the format expected in the API to use in the models
258
-     *
259
-     * @param array     $inputted_query_params_of_this_type
260
-     * @param \EEM_Base $model
261
-     * @param string    $requested_version
262
-     * @return array
263
-     * @throws \DomainException
264
-     * @throws \EE_Error
265
-     */
266
-    public static function prepare_conditions_query_params_for_models(
267
-        $inputted_query_params_of_this_type,
268
-        \EEM_Base $model,
269
-        $requested_version
270
-    ) {
271
-        $query_param_for_models = array();
272
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
273
-            $query_param_sans_stars = Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($query_param_key);
274
-            $field = Model_Data_Translator::deduce_field_from_query_param(
275
-                $query_param_sans_stars,
276
-                $model
277
-            );
278
-            //double-check is it a *_gmt field?
279
-            if (! $field instanceof \EE_Model_Field_Base
280
-                && Model_Data_Translator::is_gmt_date_field_name($query_param_sans_stars)
281
-            ) {
282
-                //yep, take off '_gmt', and find the field
283
-                $query_param_key = Model_Data_Translator::remove_gmt_from_field_name($query_param_sans_stars);
284
-                $field = Model_Data_Translator::deduce_field_from_query_param(
285
-                    $query_param_key,
286
-                    $model
287
-                );
288
-                $timezone = 'UTC';
289
-            } else {
290
-                //so it's not a GMT field. Set the timezone on the model to the default
291
-                $timezone = \EEH_DTT_Helper::get_valid_timezone_string();
292
-            }
293
-            if ($field instanceof \EE_Model_Field_Base) {
294
-                //did they specify an operator?
295
-                if (is_array($query_param_value)) {
296
-                    $op = $query_param_value[0];
297
-                    $translated_value = array($op);
298
-                    if (isset($query_param_value[1])) {
299
-                        $value = $query_param_value[1];
300
-                        $translated_value[1] = Model_Data_Translator::prepare_field_values_from_json($field, $value,
301
-                            $requested_version, $timezone);
302
-                    }
303
-                } else {
304
-                    $translated_value = Model_Data_Translator::prepare_field_value_from_json($field, $query_param_value,
305
-                        $requested_version, $timezone);
306
-                }
307
-                $query_param_for_models[$query_param_key] = $translated_value;
308
-            } else {
309
-                //so it's not for a field, assume it's a logic query param key
310
-                $query_param_for_models[$query_param_key] = Model_Data_Translator::prepare_conditions_query_params_for_models($query_param_value,
311
-                    $model, $requested_version);
312
-            }
313
-        }
314
-        return $query_param_for_models;
315
-    }
316
-
317
-
318
-
319
-    /**
320
-     * Mostly checks if the last 4 characters are "_gmt", indicating its a
321
-     * gmt date field name
322
-     *
323
-     * @param string $field_name
324
-     * @return boolean
325
-     */
326
-    public static function is_gmt_date_field_name($field_name)
327
-    {
328
-        return substr(
329
-                   Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($field_name),
330
-                   -4,
331
-                   4
332
-               ) === '_gmt';
333
-    }
334
-
335
-
336
-
337
-    /**
338
-     * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
339
-     *
340
-     * @param string $field_name
341
-     * @return string
342
-     */
343
-    public static function remove_gmt_from_field_name($field_name)
344
-    {
345
-        if (! Model_Data_Translator::is_gmt_date_field_name($field_name)) {
346
-            return $field_name;
347
-        }
348
-        $query_param_sans_stars = Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($field_name);
349
-        $query_param_sans_gmt_and_sans_stars = substr(
350
-            $query_param_sans_stars,
351
-            0,
352
-            strrpos(
353
-                $field_name,
354
-                '_gmt'
355
-            )
356
-        );
357
-        return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
358
-    }
359
-
360
-
361
-
362
-    /**
363
-     * Takes a field name from the REST API and prepares it for the model querying
364
-     *
365
-     * @param string $field_name
366
-     * @return string
367
-     */
368
-    public static function prepare_field_name_from_json($field_name)
369
-    {
370
-        if (Model_Data_Translator::is_gmt_date_field_name($field_name)) {
371
-            return Model_Data_Translator::remove_gmt_from_field_name($field_name);
372
-        }
373
-        return $field_name;
374
-    }
375
-
376
-
377
-
378
-    /**
379
-     * Takes array of field names from REST API and prepares for models
380
-     *
381
-     * @param array $field_names
382
-     * @return array of field names (possibly include model prefixes)
383
-     */
384
-    public static function prepare_field_names_from_json(array $field_names)
385
-    {
386
-        $new_array = array();
387
-        foreach ($field_names as $key => $field_name) {
388
-            $new_array[$key] = Model_Data_Translator::prepare_field_name_from_json($field_name);
389
-        }
390
-        return $new_array;
391
-    }
392
-
393
-
394
-
395
-    /**
396
-     * Takes array where array keys are field names (possibly with model path prefixes)
397
-     * from the REST API and prepares them for model querying
398
-     *
399
-     * @param array $field_names_as_keys
400
-     * @return array
401
-     */
402
-    public static function prepare_field_names_in_array_keys_from_json(array $field_names_as_keys)
403
-    {
404
-        $new_array = array();
405
-        foreach ($field_names_as_keys as $field_name => $value) {
406
-            $new_array[Model_Data_Translator::prepare_field_name_from_json($field_name)] = $value;
407
-        }
408
-        return $new_array;
409
-    }
410
-
411
-
412
-
413
-    /**
414
-     * Prepares an array of model query params for use in the REST API
415
-     *
416
-     * @param array     $model_query_params
417
-     * @param \EEM_Base $model
418
-     * @param string    $requested_version eg "4.8.36". If null is provided, defaults to the latest release of the EE4
419
-     *                                     REST API
420
-     * @return array which can be passed into the EE4 REST API when querying a model resource
421
-     * @throws \EE_Error
422
-     */
423
-    public static function prepare_query_params_for_rest_api(
424
-        array $model_query_params,
425
-        \EEM_Base $model,
426
-        $requested_version = null
427
-    ) {
428
-        if ($requested_version === null) {
429
-            $requested_version = \EED_Core_Rest_Api::latest_rest_api_version();
430
-        }
431
-        $rest_query_params = $model_query_params;
432
-        if (isset($model_query_params[0])) {
433
-            $rest_query_params['where'] = Model_Data_Translator::prepare_conditions_query_params_for_rest_api(
434
-                $model_query_params[0],
435
-                $model,
436
-                $requested_version
437
-            );
438
-            unset($rest_query_params[0]);
439
-        }
440
-        if (isset($model_query_params['having'])) {
441
-            $rest_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_rest_api(
442
-                $model_query_params['having'],
443
-                $model,
444
-                $requested_version
445
-            );
446
-        }
447
-        return apply_filters('FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
448
-            $rest_query_params, $model_query_params, $model, $requested_version);
449
-    }
450
-
451
-
452
-
453
-    /**
454
-     * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
455
-     *
456
-     * @param array     $inputted_query_params_of_this_type eg like the "where" or "having" conditions query params
457
-     *                                                      passed into EEM_Base::get_all()
458
-     * @param \EEM_Base $model
459
-     * @param string    $requested_version                  eg "4.8.36"
460
-     * @return array ready for use in the rest api query params
461
-     * @throws \EE_Error
462
-     */
463
-    public static function prepare_conditions_query_params_for_rest_api(
464
-        $inputted_query_params_of_this_type,
465
-        \EEM_Base $model,
466
-        $requested_version
467
-    ) {
468
-        $query_param_for_models = array();
469
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
470
-            $field = Model_Data_Translator::deduce_field_from_query_param(
471
-                Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($query_param_key),
472
-                $model
473
-            );
474
-            if ($field instanceof \EE_Model_Field_Base) {
475
-                //did they specify an operator?
476
-                if (is_array($query_param_value)) {
477
-                    $op = $query_param_value[0];
478
-                    $translated_value = array($op);
479
-                    if (isset($query_param_value[1])) {
480
-                        $value = $query_param_value[1];
481
-                        $translated_value[1] = Model_Data_Translator::prepare_field_values_for_json($field, $value,
482
-                            $requested_version);
483
-                    }
484
-                } else {
485
-                    $translated_value = Model_Data_Translator::prepare_field_value_for_json($field, $query_param_value,
486
-                        $requested_version);
487
-                }
488
-                $query_param_for_models[$query_param_key] = $translated_value;
489
-            } else {
490
-                //so it's not for a field, assume it's a logic query param key
491
-                $query_param_for_models[$query_param_key] = Model_Data_Translator::prepare_conditions_query_params_for_rest_api($query_param_value,
492
-                    $model, $requested_version);
493
-            }
494
-        }
495
-        return $query_param_for_models;
496
-    }
497
-
498
-
499
-
500
-    /**
501
-     * @param $condition_query_param_key
502
-     * @return string
503
-     */
504
-    public static function remove_stars_and_anything_after_from_condition_query_param_key($condition_query_param_key)
505
-    {
506
-        $pos_of_star = strpos($condition_query_param_key, '*');
507
-        if ($pos_of_star === false) {
508
-            return $condition_query_param_key;
509
-        } else {
510
-            $condition_query_param_sans_star = substr($condition_query_param_key, 0, $pos_of_star);
511
-            return $condition_query_param_sans_star;
512
-        }
513
-    }
514
-
515
-
516
-
517
-    /**
518
-     * Takes the input parameter and finds the model field that it indicates.
519
-     *
520
-     * @param string    $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
521
-     * @param \EEM_Base $model
522
-     * @return \EE_Model_Field_Base
523
-     * @throws \EE_Error
524
-     */
525
-    public static function deduce_field_from_query_param($query_param_name, \EEM_Base $model)
526
-    {
527
-        //ok, now proceed with deducing which part is the model's name, and which is the field's name
528
-        //which will help us find the database table and column
529
-        $query_param_parts = explode('.', $query_param_name);
530
-        if (empty($query_param_parts)) {
531
-            throw new \EE_Error(sprintf(__('_extract_column_name is empty when trying to extract column and table name from %s',
532
-                'event_espresso'), $query_param_name));
533
-        }
534
-        $number_of_parts = count($query_param_parts);
535
-        $last_query_param_part = $query_param_parts[count($query_param_parts) - 1];
536
-        if ($number_of_parts === 1) {
537
-            $field_name = $last_query_param_part;
538
-        } else {// $number_of_parts >= 2
539
-            //the last part is the column name, and there are only 2parts. therefore...
540
-            $field_name = $last_query_param_part;
541
-            $model = \EE_Registry::instance()->load_model($query_param_parts[$number_of_parts - 2]);
542
-        }
543
-        try {
544
-            return $model->field_settings_for($field_name);
545
-        } catch (\EE_Error $e) {
546
-            return null;
547
-        }
548
-    }
29
+	/**
30
+	 * We used to use -1 for infinity in the rest api, but that's ambiguous for
31
+	 * fields that COULD contain -1; so we use null
32
+	 */
33
+	const ee_inf_in_rest = null;
34
+
35
+
36
+
37
+	/**
38
+	 * Prepares a possible array of input values from JSON for use by the models
39
+	 *
40
+	 * @param \EE_Model_Field_Base $field_obj
41
+	 * @param mixed                $original_value_maybe_array
42
+	 * @param string               $requested_version
43
+	 * @param string               $timezone_string treat values as being in this timezone
44
+	 * @return mixed
45
+	 * @throws \DomainException
46
+	 */
47
+	public static function prepare_field_values_from_json(
48
+		$field_obj,
49
+		$original_value_maybe_array,
50
+		$requested_version,
51
+		$timezone_string = 'UTC'
52
+	) {
53
+		if (is_array($original_value_maybe_array)) {
54
+			$new_value_maybe_array = array();
55
+			foreach ($original_value_maybe_array as $array_key => $array_item) {
56
+				$new_value_maybe_array[$array_key] = Model_Data_Translator::prepare_field_value_from_json(
57
+					$field_obj,
58
+					$array_item,
59
+					$requested_version,
60
+					$timezone_string
61
+				);
62
+			}
63
+		} else {
64
+			$new_value_maybe_array = Model_Data_Translator::prepare_field_value_from_json(
65
+				$field_obj,
66
+				$original_value_maybe_array,
67
+				$requested_version,
68
+				$timezone_string
69
+			);
70
+		}
71
+		return $new_value_maybe_array;
72
+	}
73
+
74
+
75
+
76
+	/**
77
+	 * Prepares an array of field values FOR use in JSON/REST API
78
+	 *
79
+	 * @param \EE_Model_Field_Base $field_obj
80
+	 * @param mixed                $original_value_maybe_array
81
+	 * @param string               $request_version (eg 4.8.36)
82
+	 * @return array
83
+	 */
84
+	public static function prepare_field_values_for_json($field_obj, $original_value_maybe_array, $request_version)
85
+	{
86
+		if (is_array($original_value_maybe_array)) {
87
+			$new_value_maybe_array = array();
88
+			foreach ($original_value_maybe_array as $array_key => $array_item) {
89
+				$new_value_maybe_array[$array_key] = Model_Data_Translator::prepare_field_value_for_json(
90
+					$field_obj,
91
+					$array_item,
92
+					$request_version
93
+				);
94
+			}
95
+		} else {
96
+			$new_value_maybe_array = Model_Data_Translator::prepare_field_value_for_json(
97
+				$field_obj,
98
+				$original_value_maybe_array,
99
+				$request_version
100
+			);
101
+		}
102
+		return $new_value_maybe_array;
103
+	}
104
+
105
+
106
+
107
+	/**
108
+	 * Prepares incoming data from the json or $_REQUEST parameters for the models'
109
+	 * "$query_params".
110
+	 *
111
+	 * @param \EE_Model_Field_Base $field_obj
112
+	 * @param mixed                $original_value
113
+	 * @param string               $requested_version
114
+	 * @param string               $timezone_string treat values as being in this timezone
115
+	 * @return mixed
116
+	 * @throws \DomainException
117
+	 */
118
+	public static function prepare_field_value_from_json(
119
+		$field_obj,
120
+		$original_value,
121
+		$requested_version,
122
+		$timezone_string = 'UTC' // UTC
123
+	)
124
+	{
125
+		$timezone_string = $timezone_string !== '' ? $timezone_string : get_option('timezone_string', '');
126
+		$new_value = null;
127
+		if ($field_obj instanceof \EE_Infinite_Integer_Field
128
+			&& in_array($original_value, array(null, ''), true)
129
+		) {
130
+			$new_value = EE_INF;
131
+		} elseif ($field_obj instanceof \EE_Datetime_Field) {
132
+			list($offset_sign, $offset_secs) = Model_Data_Translator::parse_timezone_offset(
133
+				$field_obj->get_timezone_offset(
134
+					new \DateTimeZone($timezone_string)
135
+				)
136
+			);
137
+			$offset_string =
138
+				str_pad(
139
+					floor($offset_secs / HOUR_IN_SECONDS),
140
+					2,
141
+					'0',
142
+					STR_PAD_LEFT
143
+				)
144
+				. ':'
145
+				. str_pad(
146
+					($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
147
+					2,
148
+					'0',
149
+					STR_PAD_LEFT
150
+				);
151
+			$new_value = rest_parse_date($original_value . $offset_sign . $offset_string);
152
+		} else {
153
+			$new_value = $original_value;
154
+		}
155
+		return $new_value;
156
+	}
157
+
158
+
159
+
160
+	/**
161
+	 * determines what's going on with them timezone strings
162
+	 *
163
+	 * @param int $timezone_offset
164
+	 * @return array
165
+	 */
166
+	private static function parse_timezone_offset($timezone_offset)
167
+	{
168
+		$first_char = substr((string)$timezone_offset, 0, 1);
169
+		if ($first_char === '+' || $first_char === '-') {
170
+			$offset_sign = $first_char;
171
+			$offset_secs = substr((string)$timezone_offset, 1);
172
+		} else {
173
+			$offset_sign = '+';
174
+			$offset_secs = $timezone_offset;
175
+		}
176
+		return array($offset_sign, $offset_secs);
177
+	}
178
+
179
+
180
+
181
+	/**
182
+	 * Prepares a field's value for display in the API.
183
+	 * The $original_value should be in the model object's domain of values, see the explanation at the top of EEM_Base.
184
+	 * However, for backward compatibility, we also attempt to handle $original_values from the
185
+	 * model client-code domain, and from the database domain.
186
+	 * E.g., when working with EE_Datetime_Fields, $original_value should be a DateTime or DbSafeDateTime
187
+	 * (model object domain). However, for backward compatibility, we also accept a unix timestamp
188
+	 * (old model object domain), MySQL datetime string (database domain) or string formatted according to the
189
+	 * WP Datetime format (model client-code domain)
190
+	 *
191
+	 * @param \EE_Model_Field_Base $field_obj
192
+	 * @param mixed                $original_value
193
+	 * @param string               $requested_version
194
+	 * @return mixed
195
+	 */
196
+	public static function prepare_field_value_for_json($field_obj, $original_value, $requested_version)
197
+	{
198
+		if ($original_value === EE_INF) {
199
+			$new_value = Model_Data_Translator::ee_inf_in_rest;
200
+		} elseif ($field_obj instanceof \EE_Datetime_Field) {
201
+			if (is_string($original_value)) {
202
+				//did they submit a string of a unix timestamp?
203
+				if (is_numeric($original_value)) {
204
+					$datetime_obj = new \DateTime();
205
+					$datetime_obj->setTimestamp((int)$original_value);
206
+				} else {
207
+					//first, check if its a MySQL timestamp in GMT
208
+					$datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
209
+				}
210
+				if (! $datetime_obj instanceof \DateTime) {
211
+					//so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
212
+					$datetime_obj = $field_obj->prepare_for_set($original_value);
213
+				}
214
+				$original_value = $datetime_obj;
215
+			}
216
+			if ($original_value instanceof \DateTime) {
217
+				$new_value = $original_value->format('Y-m-d H:i:s');
218
+			} elseif (is_int($original_value)) {
219
+				$new_value = date('Y-m-d H:i:s', $original_value);
220
+			} elseif($original_value === null || $original_value === '') {
221
+				$new_value = null;
222
+			} else {
223
+				//so it's not a datetime object, unix timestamp (as string or int),
224
+				//MySQL timestamp, or even a string in the field object's format. So no idea what it is
225
+				throw new \EE_Error(
226
+					sprintf(
227
+						esc_html__(
228
+							// @codingStandardsIgnoreStart
229
+							'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
230
+							// @codingStandardsIgnoreEnd
231
+							'event_espressso'
232
+						),
233
+						$original_value,
234
+						$field_obj->get_name(),
235
+						$field_obj->get_model_name(),
236
+						$field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
237
+					)
238
+				);
239
+			}
240
+			$new_value = mysql_to_rfc3339($new_value);
241
+		} else {
242
+			$new_value = $original_value;
243
+		}
244
+		return apply_filters(
245
+			'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
246
+			$new_value,
247
+			$field_obj,
248
+			$original_value,
249
+			$requested_version
250
+		);
251
+	}
252
+
253
+
254
+
255
+	/**
256
+	 * Prepares condition-query-parameters (like what's in where and having) from
257
+	 * the format expected in the API to use in the models
258
+	 *
259
+	 * @param array     $inputted_query_params_of_this_type
260
+	 * @param \EEM_Base $model
261
+	 * @param string    $requested_version
262
+	 * @return array
263
+	 * @throws \DomainException
264
+	 * @throws \EE_Error
265
+	 */
266
+	public static function prepare_conditions_query_params_for_models(
267
+		$inputted_query_params_of_this_type,
268
+		\EEM_Base $model,
269
+		$requested_version
270
+	) {
271
+		$query_param_for_models = array();
272
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
273
+			$query_param_sans_stars = Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($query_param_key);
274
+			$field = Model_Data_Translator::deduce_field_from_query_param(
275
+				$query_param_sans_stars,
276
+				$model
277
+			);
278
+			//double-check is it a *_gmt field?
279
+			if (! $field instanceof \EE_Model_Field_Base
280
+				&& Model_Data_Translator::is_gmt_date_field_name($query_param_sans_stars)
281
+			) {
282
+				//yep, take off '_gmt', and find the field
283
+				$query_param_key = Model_Data_Translator::remove_gmt_from_field_name($query_param_sans_stars);
284
+				$field = Model_Data_Translator::deduce_field_from_query_param(
285
+					$query_param_key,
286
+					$model
287
+				);
288
+				$timezone = 'UTC';
289
+			} else {
290
+				//so it's not a GMT field. Set the timezone on the model to the default
291
+				$timezone = \EEH_DTT_Helper::get_valid_timezone_string();
292
+			}
293
+			if ($field instanceof \EE_Model_Field_Base) {
294
+				//did they specify an operator?
295
+				if (is_array($query_param_value)) {
296
+					$op = $query_param_value[0];
297
+					$translated_value = array($op);
298
+					if (isset($query_param_value[1])) {
299
+						$value = $query_param_value[1];
300
+						$translated_value[1] = Model_Data_Translator::prepare_field_values_from_json($field, $value,
301
+							$requested_version, $timezone);
302
+					}
303
+				} else {
304
+					$translated_value = Model_Data_Translator::prepare_field_value_from_json($field, $query_param_value,
305
+						$requested_version, $timezone);
306
+				}
307
+				$query_param_for_models[$query_param_key] = $translated_value;
308
+			} else {
309
+				//so it's not for a field, assume it's a logic query param key
310
+				$query_param_for_models[$query_param_key] = Model_Data_Translator::prepare_conditions_query_params_for_models($query_param_value,
311
+					$model, $requested_version);
312
+			}
313
+		}
314
+		return $query_param_for_models;
315
+	}
316
+
317
+
318
+
319
+	/**
320
+	 * Mostly checks if the last 4 characters are "_gmt", indicating its a
321
+	 * gmt date field name
322
+	 *
323
+	 * @param string $field_name
324
+	 * @return boolean
325
+	 */
326
+	public static function is_gmt_date_field_name($field_name)
327
+	{
328
+		return substr(
329
+				   Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($field_name),
330
+				   -4,
331
+				   4
332
+			   ) === '_gmt';
333
+	}
334
+
335
+
336
+
337
+	/**
338
+	 * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
339
+	 *
340
+	 * @param string $field_name
341
+	 * @return string
342
+	 */
343
+	public static function remove_gmt_from_field_name($field_name)
344
+	{
345
+		if (! Model_Data_Translator::is_gmt_date_field_name($field_name)) {
346
+			return $field_name;
347
+		}
348
+		$query_param_sans_stars = Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($field_name);
349
+		$query_param_sans_gmt_and_sans_stars = substr(
350
+			$query_param_sans_stars,
351
+			0,
352
+			strrpos(
353
+				$field_name,
354
+				'_gmt'
355
+			)
356
+		);
357
+		return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
358
+	}
359
+
360
+
361
+
362
+	/**
363
+	 * Takes a field name from the REST API and prepares it for the model querying
364
+	 *
365
+	 * @param string $field_name
366
+	 * @return string
367
+	 */
368
+	public static function prepare_field_name_from_json($field_name)
369
+	{
370
+		if (Model_Data_Translator::is_gmt_date_field_name($field_name)) {
371
+			return Model_Data_Translator::remove_gmt_from_field_name($field_name);
372
+		}
373
+		return $field_name;
374
+	}
375
+
376
+
377
+
378
+	/**
379
+	 * Takes array of field names from REST API and prepares for models
380
+	 *
381
+	 * @param array $field_names
382
+	 * @return array of field names (possibly include model prefixes)
383
+	 */
384
+	public static function prepare_field_names_from_json(array $field_names)
385
+	{
386
+		$new_array = array();
387
+		foreach ($field_names as $key => $field_name) {
388
+			$new_array[$key] = Model_Data_Translator::prepare_field_name_from_json($field_name);
389
+		}
390
+		return $new_array;
391
+	}
392
+
393
+
394
+
395
+	/**
396
+	 * Takes array where array keys are field names (possibly with model path prefixes)
397
+	 * from the REST API and prepares them for model querying
398
+	 *
399
+	 * @param array $field_names_as_keys
400
+	 * @return array
401
+	 */
402
+	public static function prepare_field_names_in_array_keys_from_json(array $field_names_as_keys)
403
+	{
404
+		$new_array = array();
405
+		foreach ($field_names_as_keys as $field_name => $value) {
406
+			$new_array[Model_Data_Translator::prepare_field_name_from_json($field_name)] = $value;
407
+		}
408
+		return $new_array;
409
+	}
410
+
411
+
412
+
413
+	/**
414
+	 * Prepares an array of model query params for use in the REST API
415
+	 *
416
+	 * @param array     $model_query_params
417
+	 * @param \EEM_Base $model
418
+	 * @param string    $requested_version eg "4.8.36". If null is provided, defaults to the latest release of the EE4
419
+	 *                                     REST API
420
+	 * @return array which can be passed into the EE4 REST API when querying a model resource
421
+	 * @throws \EE_Error
422
+	 */
423
+	public static function prepare_query_params_for_rest_api(
424
+		array $model_query_params,
425
+		\EEM_Base $model,
426
+		$requested_version = null
427
+	) {
428
+		if ($requested_version === null) {
429
+			$requested_version = \EED_Core_Rest_Api::latest_rest_api_version();
430
+		}
431
+		$rest_query_params = $model_query_params;
432
+		if (isset($model_query_params[0])) {
433
+			$rest_query_params['where'] = Model_Data_Translator::prepare_conditions_query_params_for_rest_api(
434
+				$model_query_params[0],
435
+				$model,
436
+				$requested_version
437
+			);
438
+			unset($rest_query_params[0]);
439
+		}
440
+		if (isset($model_query_params['having'])) {
441
+			$rest_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_rest_api(
442
+				$model_query_params['having'],
443
+				$model,
444
+				$requested_version
445
+			);
446
+		}
447
+		return apply_filters('FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
448
+			$rest_query_params, $model_query_params, $model, $requested_version);
449
+	}
450
+
451
+
452
+
453
+	/**
454
+	 * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
455
+	 *
456
+	 * @param array     $inputted_query_params_of_this_type eg like the "where" or "having" conditions query params
457
+	 *                                                      passed into EEM_Base::get_all()
458
+	 * @param \EEM_Base $model
459
+	 * @param string    $requested_version                  eg "4.8.36"
460
+	 * @return array ready for use in the rest api query params
461
+	 * @throws \EE_Error
462
+	 */
463
+	public static function prepare_conditions_query_params_for_rest_api(
464
+		$inputted_query_params_of_this_type,
465
+		\EEM_Base $model,
466
+		$requested_version
467
+	) {
468
+		$query_param_for_models = array();
469
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
470
+			$field = Model_Data_Translator::deduce_field_from_query_param(
471
+				Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($query_param_key),
472
+				$model
473
+			);
474
+			if ($field instanceof \EE_Model_Field_Base) {
475
+				//did they specify an operator?
476
+				if (is_array($query_param_value)) {
477
+					$op = $query_param_value[0];
478
+					$translated_value = array($op);
479
+					if (isset($query_param_value[1])) {
480
+						$value = $query_param_value[1];
481
+						$translated_value[1] = Model_Data_Translator::prepare_field_values_for_json($field, $value,
482
+							$requested_version);
483
+					}
484
+				} else {
485
+					$translated_value = Model_Data_Translator::prepare_field_value_for_json($field, $query_param_value,
486
+						$requested_version);
487
+				}
488
+				$query_param_for_models[$query_param_key] = $translated_value;
489
+			} else {
490
+				//so it's not for a field, assume it's a logic query param key
491
+				$query_param_for_models[$query_param_key] = Model_Data_Translator::prepare_conditions_query_params_for_rest_api($query_param_value,
492
+					$model, $requested_version);
493
+			}
494
+		}
495
+		return $query_param_for_models;
496
+	}
497
+
498
+
499
+
500
+	/**
501
+	 * @param $condition_query_param_key
502
+	 * @return string
503
+	 */
504
+	public static function remove_stars_and_anything_after_from_condition_query_param_key($condition_query_param_key)
505
+	{
506
+		$pos_of_star = strpos($condition_query_param_key, '*');
507
+		if ($pos_of_star === false) {
508
+			return $condition_query_param_key;
509
+		} else {
510
+			$condition_query_param_sans_star = substr($condition_query_param_key, 0, $pos_of_star);
511
+			return $condition_query_param_sans_star;
512
+		}
513
+	}
514
+
515
+
516
+
517
+	/**
518
+	 * Takes the input parameter and finds the model field that it indicates.
519
+	 *
520
+	 * @param string    $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
521
+	 * @param \EEM_Base $model
522
+	 * @return \EE_Model_Field_Base
523
+	 * @throws \EE_Error
524
+	 */
525
+	public static function deduce_field_from_query_param($query_param_name, \EEM_Base $model)
526
+	{
527
+		//ok, now proceed with deducing which part is the model's name, and which is the field's name
528
+		//which will help us find the database table and column
529
+		$query_param_parts = explode('.', $query_param_name);
530
+		if (empty($query_param_parts)) {
531
+			throw new \EE_Error(sprintf(__('_extract_column_name is empty when trying to extract column and table name from %s',
532
+				'event_espresso'), $query_param_name));
533
+		}
534
+		$number_of_parts = count($query_param_parts);
535
+		$last_query_param_part = $query_param_parts[count($query_param_parts) - 1];
536
+		if ($number_of_parts === 1) {
537
+			$field_name = $last_query_param_part;
538
+		} else {// $number_of_parts >= 2
539
+			//the last part is the column name, and there are only 2parts. therefore...
540
+			$field_name = $last_query_param_part;
541
+			$model = \EE_Registry::instance()->load_model($query_param_parts[$number_of_parts - 2]);
542
+		}
543
+		try {
544
+			return $model->field_settings_for($field_name);
545
+		} catch (\EE_Error $e) {
546
+			return null;
547
+		}
548
+	}
549 549
 
550 550
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 namespace EventEspresso\core\libraries\rest_api;
3 3
 
4
-if (! defined('EVENT_ESPRESSO_VERSION')) {
4
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5 5
     exit('No direct script access allowed');
6 6
 }
7 7
 
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
                     '0',
149 149
                     STR_PAD_LEFT
150 150
                 );
151
-            $new_value = rest_parse_date($original_value . $offset_sign . $offset_string);
151
+            $new_value = rest_parse_date($original_value.$offset_sign.$offset_string);
152 152
         } else {
153 153
             $new_value = $original_value;
154 154
         }
@@ -165,10 +165,10 @@  discard block
 block discarded – undo
165 165
      */
166 166
     private static function parse_timezone_offset($timezone_offset)
167 167
     {
168
-        $first_char = substr((string)$timezone_offset, 0, 1);
168
+        $first_char = substr((string) $timezone_offset, 0, 1);
169 169
         if ($first_char === '+' || $first_char === '-') {
170 170
             $offset_sign = $first_char;
171
-            $offset_secs = substr((string)$timezone_offset, 1);
171
+            $offset_secs = substr((string) $timezone_offset, 1);
172 172
         } else {
173 173
             $offset_sign = '+';
174 174
             $offset_secs = $timezone_offset;
@@ -202,12 +202,12 @@  discard block
 block discarded – undo
202 202
                 //did they submit a string of a unix timestamp?
203 203
                 if (is_numeric($original_value)) {
204 204
                     $datetime_obj = new \DateTime();
205
-                    $datetime_obj->setTimestamp((int)$original_value);
205
+                    $datetime_obj->setTimestamp((int) $original_value);
206 206
                 } else {
207 207
                     //first, check if its a MySQL timestamp in GMT
208 208
                     $datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
209 209
                 }
210
-                if (! $datetime_obj instanceof \DateTime) {
210
+                if ( ! $datetime_obj instanceof \DateTime) {
211 211
                     //so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
212 212
                     $datetime_obj = $field_obj->prepare_for_set($original_value);
213 213
                 }
@@ -217,7 +217,7 @@  discard block
 block discarded – undo
217 217
                 $new_value = $original_value->format('Y-m-d H:i:s');
218 218
             } elseif (is_int($original_value)) {
219 219
                 $new_value = date('Y-m-d H:i:s', $original_value);
220
-            } elseif($original_value === null || $original_value === '') {
220
+            } elseif ($original_value === null || $original_value === '') {
221 221
                 $new_value = null;
222 222
             } else {
223 223
                 //so it's not a datetime object, unix timestamp (as string or int),
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
                         $original_value,
234 234
                         $field_obj->get_name(),
235 235
                         $field_obj->get_model_name(),
236
-                        $field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
236
+                        $field_obj->get_time_format().' '.$field_obj->get_time_format()
237 237
                     )
238 238
                 );
239 239
             }
@@ -276,7 +276,7 @@  discard block
 block discarded – undo
276 276
                 $model
277 277
             );
278 278
             //double-check is it a *_gmt field?
279
-            if (! $field instanceof \EE_Model_Field_Base
279
+            if ( ! $field instanceof \EE_Model_Field_Base
280 280
                 && Model_Data_Translator::is_gmt_date_field_name($query_param_sans_stars)
281 281
             ) {
282 282
                 //yep, take off '_gmt', and find the field
@@ -342,7 +342,7 @@  discard block
 block discarded – undo
342 342
      */
343 343
     public static function remove_gmt_from_field_name($field_name)
344 344
     {
345
-        if (! Model_Data_Translator::is_gmt_date_field_name($field_name)) {
345
+        if ( ! Model_Data_Translator::is_gmt_date_field_name($field_name)) {
346 346
             return $field_name;
347 347
         }
348 348
         $query_param_sans_stars = Model_Data_Translator::remove_stars_and_anything_after_from_condition_query_param_key($field_name);
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 1 patch
Indentation   +1260 added lines, -1260 removed lines patch added patch discarded remove patch
@@ -14,1264 +14,1264 @@
 block discarded – undo
14 14
 {
15 15
 
16 16
 
17
-    /**
18
-     * Extend_Events_Admin_Page constructor.
19
-     *
20
-     * @param bool $routing
21
-     */
22
-    public function __construct($routing = true)
23
-    {
24
-        parent::__construct($routing);
25
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
26
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
27
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
28
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
29
-        }
30
-    }
31
-
32
-
33
-    /**
34
-     * Sets routes.
35
-     */
36
-    protected function _extend_page_config()
37
-    {
38
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
39
-        //is there a evt_id in the request?
40
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
41
-            ? $this->_req_data['EVT_ID']
42
-            : 0;
43
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
44
-        //tkt_id?
45
-        $tkt_id             = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
46
-            ? $this->_req_data['TKT_ID']
47
-            : 0;
48
-        $new_page_routes    = array(
49
-            'duplicate_event'          => array(
50
-                'func'       => '_duplicate_event',
51
-                'capability' => 'ee_edit_event',
52
-                'obj_id'     => $evt_id,
53
-                'noheader'   => true,
54
-            ),
55
-            'ticket_list_table'        => array(
56
-                'func'       => '_tickets_overview_list_table',
57
-                'capability' => 'ee_read_default_tickets',
58
-            ),
59
-            'trash_ticket'             => array(
60
-                'func'       => '_trash_or_restore_ticket',
61
-                'capability' => 'ee_delete_default_ticket',
62
-                'obj_id'     => $tkt_id,
63
-                'noheader'   => true,
64
-                'args'       => array('trash' => true),
65
-            ),
66
-            'trash_tickets'            => array(
67
-                'func'       => '_trash_or_restore_ticket',
68
-                'capability' => 'ee_delete_default_tickets',
69
-                'noheader'   => true,
70
-                'args'       => array('trash' => true),
71
-            ),
72
-            'restore_ticket'           => array(
73
-                'func'       => '_trash_or_restore_ticket',
74
-                'capability' => 'ee_delete_default_ticket',
75
-                'obj_id'     => $tkt_id,
76
-                'noheader'   => true,
77
-            ),
78
-            'restore_tickets'          => array(
79
-                'func'       => '_trash_or_restore_ticket',
80
-                'capability' => 'ee_delete_default_tickets',
81
-                'noheader'   => true,
82
-            ),
83
-            'delete_ticket'            => array(
84
-                'func'       => '_delete_ticket',
85
-                'capability' => 'ee_delete_default_ticket',
86
-                'obj_id'     => $tkt_id,
87
-                'noheader'   => true,
88
-            ),
89
-            'delete_tickets'           => array(
90
-                'func'       => '_delete_ticket',
91
-                'capability' => 'ee_delete_default_tickets',
92
-                'noheader'   => true,
93
-            ),
94
-            'import_page'              => array(
95
-                'func'       => '_import_page',
96
-                'capability' => 'import',
97
-            ),
98
-            'import'                   => array(
99
-                'func'       => '_import_events',
100
-                'capability' => 'import',
101
-                'noheader'   => true,
102
-            ),
103
-            'import_events'            => array(
104
-                'func'       => '_import_events',
105
-                'capability' => 'import',
106
-                'noheader'   => true,
107
-            ),
108
-            'export_events'            => array(
109
-                'func'       => '_events_export',
110
-                'capability' => 'export',
111
-                'noheader'   => true,
112
-            ),
113
-            'export_categories'        => array(
114
-                'func'       => '_categories_export',
115
-                'capability' => 'export',
116
-                'noheader'   => true,
117
-            ),
118
-            'sample_export_file'       => array(
119
-                'func'       => '_sample_export_file',
120
-                'capability' => 'export',
121
-                'noheader'   => true,
122
-            ),
123
-            'update_template_settings' => array(
124
-                'func'       => '_update_template_settings',
125
-                'capability' => 'manage_options',
126
-                'noheader'   => true,
127
-            ),
128
-        );
129
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
130
-        //partial route/config override
131
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
132
-        $this->_page_config['create_new']['metaboxes'][]  = '_premium_event_editor_meta_boxes';
133
-        $this->_page_config['create_new']['qtips'][]      = 'EE_Event_Editor_Tips';
134
-        $this->_page_config['edit']['qtips'][]            = 'EE_Event_Editor_Tips';
135
-        $this->_page_config['edit']['metaboxes'][]        = '_premium_event_editor_meta_boxes';
136
-        $this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
137
-        //add tickets tab but only if there are more than one default ticket!
138
-        $tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
139
-            array(array('TKT_is_default' => 1)),
140
-            'TKT_ID',
141
-            true
142
-        );
143
-        if ($tkt_count > 1) {
144
-            $new_page_config = array(
145
-                'ticket_list_table' => array(
146
-                    'nav'           => array(
147
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
148
-                        'order' => 60,
149
-                    ),
150
-                    'list_table'    => 'Tickets_List_Table',
151
-                    'require_nonce' => false,
152
-                ),
153
-            );
154
-        }
155
-        //template settings
156
-        $new_page_config['template_settings'] = array(
157
-            'nav'           => array(
158
-                'label' => esc_html__('Templates', 'event_espresso'),
159
-                'order' => 30,
160
-            ),
161
-            'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
162
-            'help_tabs'     => array(
163
-                'general_settings_templates_help_tab' => array(
164
-                    'title'    => esc_html__('Templates', 'event_espresso'),
165
-                    'filename' => 'general_settings_templates',
166
-                ),
167
-            ),
168
-            'help_tour'     => array('Templates_Help_Tour'),
169
-            'require_nonce' => false,
170
-        );
171
-        $this->_page_config                   = array_merge($this->_page_config, $new_page_config);
172
-        //add filters and actions
173
-        //modifying _views
174
-        add_filter(
175
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
176
-            array($this, 'add_additional_datetime_button'),
177
-            10,
178
-            2
179
-        );
180
-        add_filter(
181
-            'FHEE_event_datetime_metabox_clone_button_template',
182
-            array($this, 'add_datetime_clone_button'),
183
-            10,
184
-            2
185
-        );
186
-        add_filter(
187
-            'FHEE_event_datetime_metabox_timezones_template',
188
-            array($this, 'datetime_timezones_template'),
189
-            10,
190
-            2
191
-        );
192
-        //filters for event list table
193
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
194
-        add_filter(
195
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
196
-            array($this, 'extra_list_table_actions'),
197
-            10,
198
-            2
199
-        );
200
-        //legend item
201
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
202
-        add_action('admin_init', array($this, 'admin_init'));
203
-        //heartbeat stuff
204
-        add_filter('heartbeat_received', array($this, 'heartbeat_response'), 10, 2);
205
-    }
206
-
207
-
208
-    /**
209
-     * admin_init
210
-     */
211
-    public function admin_init()
212
-    {
213
-        EE_Registry::$i18n_js_strings = array_merge(
214
-            EE_Registry::$i18n_js_strings,
215
-            array(
216
-                'image_confirm'          => esc_html__(
217
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
218
-                    'event_espresso'
219
-                ),
220
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
221
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
222
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
223
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
224
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
225
-            )
226
-        );
227
-    }
228
-
229
-
230
-    /**
231
-     * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
232
-     * accordingly.
233
-     *
234
-     * @param array $response The existing heartbeat response array.
235
-     * @param array $data     The incoming data package.
236
-     * @return array  possibly appended response.
237
-     */
238
-    public function heartbeat_response($response, $data)
239
-    {
240
-        /**
241
-         * check whether count of tickets is approaching the potential
242
-         * limits for the server.
243
-         */
244
-        if (! empty($data['input_count'])) {
245
-            $response['max_input_vars_check'] = EE_Registry::instance()->CFG->environment->max_input_vars_limit_check(
246
-                $data['input_count']
247
-            );
248
-        }
249
-        return $response;
250
-    }
251
-
252
-
253
-    /**
254
-     * Add per page screen options to the default ticket list table view.
255
-     */
256
-    protected function _add_screen_options_ticket_list_table()
257
-    {
258
-        $this->_per_page_screen_option();
259
-    }
260
-
261
-
262
-    /**
263
-     * @param string $return
264
-     * @param int    $id
265
-     * @param string $new_title
266
-     * @param string $new_slug
267
-     * @return string
268
-     */
269
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
270
-    {
271
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
272
-        //make sure this is only when editing
273
-        if (! empty($id)) {
274
-            $href   = EE_Admin_Page::add_query_args_and_nonce(
275
-                array('action' => 'duplicate_event', 'EVT_ID' => $id),
276
-                $this->_admin_base_url
277
-            );
278
-            $title  = esc_attr__('Duplicate Event', 'event_espresso');
279
-            $return .= '<a href="'
280
-                       . $href
281
-                       . '" title="'
282
-                       . $title
283
-                       . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
284
-                       . $title
285
-                       . '</button>';
286
-        }
287
-        return $return;
288
-    }
289
-
290
-
291
-    /**
292
-     * Set the list table views for the default ticket list table view.
293
-     */
294
-    public function _set_list_table_views_ticket_list_table()
295
-    {
296
-        $this->_views = array(
297
-            'all'     => array(
298
-                'slug'        => 'all',
299
-                'label'       => esc_html__('All', 'event_espresso'),
300
-                'count'       => 0,
301
-                'bulk_action' => array(
302
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
303
-                ),
304
-            ),
305
-            'trashed' => array(
306
-                'slug'        => 'trashed',
307
-                'label'       => esc_html__('Trash', 'event_espresso'),
308
-                'count'       => 0,
309
-                'bulk_action' => array(
310
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
311
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
312
-                ),
313
-            ),
314
-        );
315
-    }
316
-
317
-
318
-    /**
319
-     * Enqueue scripts and styles for the event editor.
320
-     */
321
-    public function load_scripts_styles_edit()
322
-    {
323
-        wp_register_script(
324
-            'ee-event-editor-heartbeat',
325
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
326
-            array('ee_admin_js', 'heartbeat'),
327
-            EVENT_ESPRESSO_VERSION,
328
-            true
329
-        );
330
-        wp_enqueue_script('ee-accounting');
331
-        //styles
332
-        wp_enqueue_style('espresso-ui-theme');
333
-        wp_enqueue_script('event_editor_js');
334
-        wp_enqueue_script('ee-event-editor-heartbeat');
335
-    }
336
-
337
-
338
-    /**
339
-     * Returns template for the additional datetime.
340
-     * @param $template
341
-     * @param $template_args
342
-     * @return mixed
343
-     * @throws DomainException
344
-     */
345
-    public function add_additional_datetime_button($template, $template_args)
346
-    {
347
-        return EEH_Template::display_template(
348
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
349
-            $template_args,
350
-            true
351
-        );
352
-    }
353
-
354
-
355
-    /**
356
-     * Returns the template for cloning a datetime.
357
-     * @param $template
358
-     * @param $template_args
359
-     * @return mixed
360
-     * @throws DomainException
361
-     */
362
-    public function add_datetime_clone_button($template, $template_args)
363
-    {
364
-        return EEH_Template::display_template(
365
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
366
-            $template_args,
367
-            true
368
-        );
369
-    }
370
-
371
-
372
-    /**
373
-     * Returns the template for datetime timezones.
374
-     * @param $template
375
-     * @param $template_args
376
-     * @return mixed
377
-     * @throws DomainException
378
-     */
379
-    public function datetime_timezones_template($template, $template_args)
380
-    {
381
-        return EEH_Template::display_template(
382
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
383
-            $template_args,
384
-            true
385
-        );
386
-    }
387
-
388
-
389
-    /**
390
-     * Sets the views for the default list table view.
391
-     */
392
-    protected function _set_list_table_views_default()
393
-    {
394
-        parent::_set_list_table_views_default();
395
-        $new_views    = array(
396
-            'today' => array(
397
-                'slug'        => 'today',
398
-                'label'       => esc_html__('Today', 'event_espresso'),
399
-                'count'       => $this->total_events_today(),
400
-                'bulk_action' => array(
401
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
402
-                ),
403
-            ),
404
-            'month' => array(
405
-                'slug'        => 'month',
406
-                'label'       => esc_html__('This Month', 'event_espresso'),
407
-                'count'       => $this->total_events_this_month(),
408
-                'bulk_action' => array(
409
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
410
-                ),
411
-            ),
412
-        );
413
-        $this->_views = array_merge($this->_views, $new_views);
414
-    }
415
-
416
-
417
-    /**
418
-     * Returns the extra action links for the default list table view.
419
-     * @param array     $action_links
420
-     * @param \EE_Event $event
421
-     * @return array
422
-     * @throws EE_Error
423
-     */
424
-    public function extra_list_table_actions(array $action_links, \EE_Event $event)
425
-    {
426
-        if (EE_Registry::instance()->CAP->current_user_can(
427
-            'ee_read_registrations',
428
-            'espresso_registrations_reports',
429
-            $event->ID()
430
-        )
431
-        ) {
432
-            $reports_query_args = array(
433
-                'action' => 'reports',
434
-                'EVT_ID' => $event->ID(),
435
-            );
436
-            $reports_link       = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
437
-            $action_links[]     = '<a href="'
438
-                                  . $reports_link
439
-                                  . '" title="'
440
-                                  . esc_attr__('View Report', 'event_espresso')
441
-                                  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
442
-                                  . "\n\t";
443
-        }
444
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
445
-            EE_Registry::instance()->load_helper('MSG_Template');
446
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
447
-                'see_notifications_for',
448
-                null,
449
-                array('EVT_ID' => $event->ID())
450
-            );
451
-        }
452
-        return $action_links;
453
-    }
454
-
455
-
456
-    /**
457
-     * @param $items
458
-     * @return mixed
459
-     */
460
-    public function additional_legend_items($items)
461
-    {
462
-        if (EE_Registry::instance()->CAP->current_user_can(
463
-            'ee_read_registrations',
464
-            'espresso_registrations_reports'
465
-        )
466
-        ) {
467
-            $items['reports'] = array(
468
-                'class' => 'dashicons dashicons-chart-bar',
469
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
470
-            );
471
-        }
472
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
473
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
474
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
475
-                $items['view_related_messages'] = array(
476
-                    'class' => $related_for_icon['css_class'],
477
-                    'desc'  => $related_for_icon['label'],
478
-                );
479
-            }
480
-        }
481
-        return $items;
482
-    }
483
-
484
-
485
-    /**
486
-     * This is the callback method for the duplicate event route
487
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
488
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
489
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
490
-     * After duplication the redirect is to the new event edit page.
491
-     *
492
-     * @return void
493
-     * @access protected
494
-     * @throws EE_Error If EE_Event is not available with given ID
495
-     */
496
-    protected function _duplicate_event()
497
-    {
498
-        // first make sure the ID for the event is in the request.
499
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
500
-        if (! isset($this->_req_data['EVT_ID'])) {
501
-            EE_Error::add_error(
502
-                esc_html__(
503
-                    'In order to duplicate an event an Event ID is required.  None was given.',
504
-                    'event_espresso'
505
-                ),
506
-                __FILE__,
507
-                __FUNCTION__,
508
-                __LINE__
509
-            );
510
-            $this->_redirect_after_action(false, '', '', array(), true);
511
-            return;
512
-        }
513
-        //k we've got EVT_ID so let's use that to get the event we'll duplicate
514
-        $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
515
-        if (! $orig_event instanceof EE_Event) {
516
-            throw new EE_Error(
517
-                sprintf(
518
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
519
-                    $this->_req_data['EVT_ID']
520
-                )
521
-            );
522
-        }
523
-        //k now let's clone the $orig_event before getting relations
524
-        $new_event = clone $orig_event;
525
-        //original datetimes
526
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
527
-        //other original relations
528
-        $orig_ven = $orig_event->get_many_related('Venue');
529
-        //reset the ID and modify other details to make it clear this is a dupe
530
-        $new_event->set('EVT_ID', 0);
531
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
532
-        $new_event->set('EVT_name', $new_name);
533
-        $new_event->set(
534
-            'EVT_slug',
535
-            wp_unique_post_slug(
536
-                sanitize_title($orig_event->name()),
537
-                0,
538
-                'publish',
539
-                'espresso_events',
540
-                0
541
-            )
542
-        );
543
-        $new_event->set('status', 'draft');
544
-        //duplicate discussion settings
545
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
546
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
547
-        //save the new event
548
-        $new_event->save();
549
-        //venues
550
-        foreach ($orig_ven as $ven) {
551
-            $new_event->_add_relation_to($ven, 'Venue');
552
-        }
553
-        $new_event->save();
554
-        //now we need to get the question group relations and handle that
555
-        //first primary question groups
556
-        $orig_primary_qgs = $orig_event->get_many_related(
557
-            'Question_Group',
558
-            array(array('Event_Question_Group.EQG_primary' => 1))
559
-        );
560
-        if (! empty($orig_primary_qgs)) {
561
-            foreach ($orig_primary_qgs as $id => $obj) {
562
-                if ($obj instanceof EE_Question_Group) {
563
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
564
-                }
565
-            }
566
-        }
567
-        //next additional attendee question groups
568
-        $orig_additional_qgs = $orig_event->get_many_related(
569
-            'Question_Group',
570
-            array(array('Event_Question_Group.EQG_primary' => 0))
571
-        );
572
-        if (! empty($orig_additional_qgs)) {
573
-            foreach ($orig_additional_qgs as $id => $obj) {
574
-                if ($obj instanceof EE_Question_Group) {
575
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
576
-                }
577
-            }
578
-        }
579
-
580
-        $new_event->save();
581
-
582
-        //k now that we have the new event saved we can loop through the datetimes and start adding relations.
583
-        $cloned_tickets = array();
584
-        foreach ($orig_datetimes as $orig_dtt) {
585
-            if (! $orig_dtt instanceof EE_Datetime) {
586
-                continue;
587
-            }
588
-            $new_dtt   = clone $orig_dtt;
589
-            $orig_tkts = $orig_dtt->tickets();
590
-            //save new dtt then add to event
591
-            $new_dtt->set('DTT_ID', 0);
592
-            $new_dtt->set('DTT_sold', 0);
593
-            $new_dtt->set_reserved(0);
594
-            $new_dtt->save();
595
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
596
-            $new_event->save();
597
-            //now let's get the ticket relations setup.
598
-            foreach ((array)$orig_tkts as $orig_tkt) {
599
-                //it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
600
-                if (! $orig_tkt instanceof EE_Ticket) {
601
-                    continue;
602
-                }
603
-                //is this ticket archived?  If it is then let's skip
604
-                if ($orig_tkt->get('TKT_deleted')) {
605
-                    continue;
606
-                }
607
-                // does this original ticket already exist in the clone_tickets cache?
608
-                //  If so we'll just use the new ticket from it.
609
-                if (isset($cloned_tickets[$orig_tkt->ID()])) {
610
-                    $new_tkt = $cloned_tickets[$orig_tkt->ID()];
611
-                } else {
612
-                    $new_tkt = clone $orig_tkt;
613
-                    //get relations on the $orig_tkt that we need to setup.
614
-                    $orig_prices = $orig_tkt->prices();
615
-                    $new_tkt->set('TKT_ID', 0);
616
-                    $new_tkt->set('TKT_sold', 0);
617
-                    $new_tkt->set('TKT_reserved', 0);
618
-                    $new_tkt->save(); //make sure new ticket has ID.
619
-                    //price relations on new ticket need to be setup.
620
-                    foreach ($orig_prices as $orig_price) {
621
-                        $new_price = clone $orig_price;
622
-                        $new_price->set('PRC_ID', 0);
623
-                        $new_price->save();
624
-                        $new_tkt->_add_relation_to($new_price, 'Price');
625
-                        $new_tkt->save();
626
-                    }
627
-
628
-                    do_action(
629
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
630
-                        $orig_tkt,
631
-                        $new_tkt,
632
-                        $orig_prices,
633
-                        $orig_event,
634
-                        $orig_dtt,
635
-                        $new_dtt
636
-                    );
637
-                }
638
-                // k now we can add the new ticket as a relation to the new datetime
639
-                // and make sure its added to our cached $cloned_tickets array
640
-                // for use with later datetimes that have the same ticket.
641
-                $new_dtt->_add_relation_to($new_tkt, 'Ticket');
642
-                $new_dtt->save();
643
-                $cloned_tickets[$orig_tkt->ID()] = $new_tkt;
644
-            }
645
-        }
646
-        //clone taxonomy information
647
-        $taxonomies_to_clone_with = apply_filters(
648
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
649
-            array('espresso_event_categories', 'espresso_event_type', 'post_tag')
650
-        );
651
-        //get terms for original event (notice)
652
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
653
-        //loop through terms and add them to new event.
654
-        foreach ($orig_terms as $term) {
655
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
656
-        }
657
-
658
-        //duplicate other core WP_Post items for this event.
659
-        //post thumbnail (feature image).
660
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
661
-        if ($feature_image_id) {
662
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
663
-        }
664
-
665
-        //duplicate page_template setting
666
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
667
-        if ($page_template) {
668
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
669
-        }
670
-
671
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
672
-        //now let's redirect to the edit page for this duplicated event if we have a new event id.
673
-        if ($new_event->ID()) {
674
-            $redirect_args = array(
675
-                'post'   => $new_event->ID(),
676
-                'action' => 'edit',
677
-            );
678
-            EE_Error::add_success(
679
-                esc_html__(
680
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
681
-                    'event_espresso'
682
-                )
683
-            );
684
-        } else {
685
-            $redirect_args = array(
686
-                'action' => 'default',
687
-            );
688
-            EE_Error::add_error(
689
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
690
-                __FILE__,
691
-                __FUNCTION__,
692
-                __LINE__
693
-            );
694
-        }
695
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
696
-    }
697
-
698
-
699
-    /**
700
-     * Generates output for the import page.
701
-     * @throws DomainException
702
-     */
703
-    protected function _import_page()
704
-    {
705
-        $title                                      = esc_html__('Import', 'event_espresso');
706
-        $intro                                      = esc_html__(
707
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
708
-            'event_espresso'
709
-        );
710
-        $form_url                                   = EVENTS_ADMIN_URL;
711
-        $action                                     = 'import_events';
712
-        $type                                       = 'csv';
713
-        $this->_template_args['form']               = EE_Import::instance()->upload_form(
714
-            $title, $intro, $form_url, $action, $type
715
-        );
716
-        $this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
717
-            array('action' => 'sample_export_file'),
718
-            $this->_admin_base_url
719
-        );
720
-        $content                                    = EEH_Template::display_template(
721
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
722
-            $this->_template_args,
723
-            true
724
-        );
725
-        $this->_template_args['admin_page_content'] = $content;
726
-        $this->display_admin_page_with_sidebar();
727
-    }
728
-
729
-
730
-    /**
731
-     * _import_events
732
-     * This handles displaying the screen and running imports for importing events.
733
-     *
734
-     * @return void
735
-     */
736
-    protected function _import_events()
737
-    {
738
-        require_once(EE_CLASSES . 'EE_Import.class.php');
739
-        $success = EE_Import::instance()->import();
740
-        $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
741
-    }
742
-
743
-
744
-    /**
745
-     * _events_export
746
-     * Will export all (or just the given event) to a Excel compatible file.
747
-     *
748
-     * @access protected
749
-     * @return void
750
-     */
751
-    protected function _events_export()
752
-    {
753
-        if (isset($this->_req_data['EVT_ID'])) {
754
-            $event_ids = $this->_req_data['EVT_ID'];
755
-        } elseif (isset($this->_req_data['EVT_IDs'])) {
756
-            $event_ids = $this->_req_data['EVT_IDs'];
757
-        } else {
758
-            $event_ids = null;
759
-        }
760
-        //todo: I don't like doing this but it'll do until we modify EE_Export Class.
761
-        $new_request_args = array(
762
-            'export' => 'report',
763
-            'action' => 'all_event_data',
764
-            'EVT_ID' => $event_ids,
765
-        );
766
-        $this->_req_data  = array_merge($this->_req_data, $new_request_args);
767
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
768
-            require_once(EE_CLASSES . 'EE_Export.class.php');
769
-            $EE_Export = EE_Export::instance($this->_req_data);
770
-            $EE_Export->export();
771
-        }
772
-    }
773
-
774
-
775
-    /**
776
-     * handle category exports()
777
-     *
778
-     * @return void
779
-     */
780
-    protected function _categories_export()
781
-    {
782
-        //todo: I don't like doing this but it'll do until we modify EE_Export Class.
783
-        $new_request_args = array(
784
-            'export'       => 'report',
785
-            'action'       => 'categories',
786
-            'category_ids' => $this->_req_data['EVT_CAT_ID'],
787
-        );
788
-        $this->_req_data  = array_merge($this->_req_data, $new_request_args);
789
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
790
-            require_once(EE_CLASSES . 'EE_Export.class.php');
791
-            $EE_Export = EE_Export::instance($this->_req_data);
792
-            $EE_Export->export();
793
-        }
794
-    }
795
-
796
-
797
-    /**
798
-     * Creates a sample CSV file for importing
799
-     */
800
-    protected function _sample_export_file()
801
-    {
802
-        //		require_once(EE_CLASSES . 'EE_Export.class.php');
803
-        EE_Export::instance()->export_sample();
804
-    }
805
-
806
-
807
-    /*************        Template Settings        *************/
808
-    /**
809
-     * Generates template settings page output
810
-     * @throws DomainException
811
-     * @throws EE_Error
812
-     */
813
-    protected function _template_settings()
814
-    {
815
-        $this->_template_args['values'] = $this->_yes_no_values;
816
-        /**
817
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
818
-         * from General_Settings_Admin_Page to here.
819
-         */
820
-        $this->_template_args = apply_filters(
821
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
822
-            $this->_template_args
823
-        );
824
-        $this->_set_add_edit_form_tags('update_template_settings');
825
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
826
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
827
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
828
-            $this->_template_args,
829
-            true
830
-        );
831
-        $this->display_admin_page_with_sidebar();
832
-    }
833
-
834
-
835
-    /**
836
-     * Handler for updating template settings.
837
-     */
838
-    protected function _update_template_settings()
839
-    {
840
-        /**
841
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
842
-         * from General_Settings_Admin_Page to here.
843
-         */
844
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
845
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
846
-            EE_Registry::instance()->CFG->template_settings,
847
-            $this->_req_data
848
-        );
849
-        //update custom post type slugs and detect if we need to flush rewrite rules
850
-        $old_slug                                          = EE_Registry::instance()->CFG->core->event_cpt_slug;
851
-        EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
852
-            ? EE_Registry::instance()->CFG->core->event_cpt_slug
853
-            : sanitize_title_with_dashes($this->_req_data['event_cpt_slug']);
854
-        $what                                              = 'Template Settings';
855
-        $success                                           = $this->_update_espresso_configuration(
856
-            $what,
857
-            EE_Registry::instance()->CFG->template_settings,
858
-            __FILE__,
859
-            __FUNCTION__,
860
-            __LINE__
861
-        );
862
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
863
-            update_option('ee_flush_rewrite_rules', true);
864
-        }
865
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
866
-    }
867
-
868
-
869
-    /**
870
-     * _premium_event_editor_meta_boxes
871
-     * add all metaboxes related to the event_editor
872
-     *
873
-     * @access protected
874
-     * @return void
875
-     * @throws EE_Error
876
-     */
877
-    protected function _premium_event_editor_meta_boxes()
878
-    {
879
-        $this->verify_cpt_object();
880
-        add_meta_box(
881
-            'espresso_event_editor_event_options',
882
-            esc_html__('Event Registration Options', 'event_espresso'),
883
-            array($this, 'registration_options_meta_box'),
884
-            $this->page_slug,
885
-            'side',
886
-            'core'
887
-        );
888
-    }
889
-
890
-
891
-    /**
892
-     * override caf metabox
893
-     *
894
-     * @return void
895
-     * @throws DomainException
896
-     */
897
-    public function registration_options_meta_box()
898
-    {
899
-        $yes_no_values                                    = array(
900
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
901
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
902
-        );
903
-        $default_reg_status_values                        = EEM_Registration::reg_status_array(
904
-            array(
905
-                EEM_Registration::status_id_cancelled,
906
-                EEM_Registration::status_id_declined,
907
-                EEM_Registration::status_id_incomplete,
908
-                EEM_Registration::status_id_wait_list,
909
-            ),
910
-            true
911
-        );
912
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
913
-        $template_args['_event']                          = $this->_cpt_model_obj;
914
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
915
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
916
-            'default_reg_status',
917
-            $default_reg_status_values,
918
-            $this->_cpt_model_obj->default_registration_status()
919
-        );
920
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
921
-            'display_desc',
922
-            $yes_no_values,
923
-            $this->_cpt_model_obj->display_description()
924
-        );
925
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
926
-            'display_ticket_selector',
927
-            $yes_no_values,
928
-            $this->_cpt_model_obj->display_ticket_selector(),
929
-            '',
930
-            '',
931
-            false
932
-        );
933
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
934
-            'EVT_default_registration_status',
935
-            $default_reg_status_values,
936
-            $this->_cpt_model_obj->default_registration_status()
937
-        );
938
-        $template_args['additional_registration_options'] = apply_filters(
939
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
940
-            '',
941
-            $template_args,
942
-            $yes_no_values,
943
-            $default_reg_status_values
944
-        );
945
-        EEH_Template::display_template(
946
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
947
-            $template_args
948
-        );
949
-    }
950
-
951
-
952
-
953
-    /**
954
-     * wp_list_table_mods for caf
955
-     * ============================
956
-     */
957
-    /**
958
-     * hook into list table filters and provide filters for caffeinated list table
959
-     *
960
-     * @param  array $old_filters    any existing filters present
961
-     * @param  array $list_table_obj the list table object
962
-     * @return array                  new filters
963
-     */
964
-    public function list_table_filters($old_filters, $list_table_obj)
965
-    {
966
-        $filters = array();
967
-        //first month/year filters
968
-        $filters[] = $this->espresso_event_months_dropdown();
969
-        $status    = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
970
-        //active status dropdown
971
-        if ($status !== 'draft') {
972
-            $filters[] = $this->active_status_dropdown(
973
-                isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
974
-            );
975
-        }
976
-        //category filter
977
-        $filters[] = $this->category_dropdown();
978
-        return array_merge($old_filters, $filters);
979
-    }
980
-
981
-
982
-    /**
983
-     * espresso_event_months_dropdown
984
-     *
985
-     * @access public
986
-     * @return string                dropdown listing month/year selections for events.
987
-     */
988
-    public function espresso_event_months_dropdown()
989
-    {
990
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
991
-        // Note we need to include any other filters that are set!
992
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
993
-        //categories?
994
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
995
-            ? $this->_req_data['EVT_CAT']
996
-            : null;
997
-        //active status?
998
-        $active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
999
-        $cur_date      = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1000
-        return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1001
-    }
1002
-
1003
-
1004
-    /**
1005
-     * returns a list of "active" statuses on the event
1006
-     *
1007
-     * @param  string $current_value whatever the current active status is
1008
-     * @return string
1009
-     */
1010
-    public function active_status_dropdown($current_value = '')
1011
-    {
1012
-        $select_name = 'active_status';
1013
-        $values      = array(
1014
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1015
-            'active'   => esc_html__('Active', 'event_espresso'),
1016
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1017
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1018
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1019
-        );
1020
-        $id          = 'id="espresso-active-status-dropdown-filter"';
1021
-        $class       = 'wide';
1022
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1023
-    }
1024
-
1025
-
1026
-    /**
1027
-     * output a dropdown of the categories for the category filter on the event admin list table
1028
-     *
1029
-     * @access  public
1030
-     * @return string html
1031
-     */
1032
-    public function category_dropdown()
1033
-    {
1034
-        $cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1035
-        return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1036
-    }
1037
-
1038
-
1039
-    /**
1040
-     * get total number of events today
1041
-     *
1042
-     * @access public
1043
-     * @return int
1044
-     * @throws EE_Error
1045
-     */
1046
-    public function total_events_today()
1047
-    {
1048
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1049
-            'DTT_EVT_start',
1050
-            date('Y-m-d') . ' 00:00:00',
1051
-            'Y-m-d H:i:s',
1052
-            'UTC'
1053
-        );
1054
-        $end   = EEM_Datetime::instance()->convert_datetime_for_query(
1055
-            'DTT_EVT_start',
1056
-            date('Y-m-d') . ' 23:59:59',
1057
-            'Y-m-d H:i:s',
1058
-            'UTC'
1059
-        );
1060
-        $where = array(
1061
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1062
-        );
1063
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1064
-        return $count;
1065
-    }
1066
-
1067
-
1068
-    /**
1069
-     * get total number of events this month
1070
-     *
1071
-     * @access public
1072
-     * @return int
1073
-     * @throws EE_Error
1074
-     */
1075
-    public function total_events_this_month()
1076
-    {
1077
-        //Dates
1078
-        $this_year_r     = date('Y');
1079
-        $this_month_r    = date('m');
1080
-        $days_this_month = date('t');
1081
-        $start           = EEM_Datetime::instance()->convert_datetime_for_query(
1082
-            'DTT_EVT_start',
1083
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1084
-            'Y-m-d H:i:s',
1085
-            'UTC'
1086
-        );
1087
-        $end             = EEM_Datetime::instance()->convert_datetime_for_query(
1088
-            'DTT_EVT_start',
1089
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1090
-            'Y-m-d H:i:s',
1091
-            'UTC'
1092
-        );
1093
-        $where           = array(
1094
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1095
-        );
1096
-        $count           = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1097
-        return $count;
1098
-    }
1099
-
1100
-
1101
-    /** DEFAULT TICKETS STUFF **/
1102
-
1103
-    /**
1104
-     * Output default tickets list table view.
1105
-     */
1106
-    public function _tickets_overview_list_table()
1107
-    {
1108
-        $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1109
-        $this->display_admin_list_table_page_with_no_sidebar();
1110
-    }
1111
-
1112
-
1113
-    /**
1114
-     * @param int  $per_page
1115
-     * @param bool $count
1116
-     * @param bool $trashed
1117
-     * @return \EE_Soft_Delete_Base_Class[]|int
1118
-     */
1119
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1120
-    {
1121
-        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1122
-        $order   = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1123
-        switch ($orderby) {
1124
-            case 'TKT_name':
1125
-                $orderby = array('TKT_name' => $order);
1126
-                break;
1127
-            case 'TKT_price':
1128
-                $orderby = array('TKT_price' => $order);
1129
-                break;
1130
-            case 'TKT_uses':
1131
-                $orderby = array('TKT_uses' => $order);
1132
-                break;
1133
-            case 'TKT_min':
1134
-                $orderby = array('TKT_min' => $order);
1135
-                break;
1136
-            case 'TKT_max':
1137
-                $orderby = array('TKT_max' => $order);
1138
-                break;
1139
-            case 'TKT_qty':
1140
-                $orderby = array('TKT_qty' => $order);
1141
-                break;
1142
-        }
1143
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1144
-            ? $this->_req_data['paged']
1145
-            : 1;
1146
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1147
-            ? $this->_req_data['perpage']
1148
-            : $per_page;
1149
-        $_where       = array(
1150
-            'TKT_is_default' => 1,
1151
-            'TKT_deleted'    => $trashed,
1152
-        );
1153
-        $offset       = ($current_page - 1) * $per_page;
1154
-        $limit        = array($offset, $per_page);
1155
-        if (isset($this->_req_data['s'])) {
1156
-            $sstr         = '%' . $this->_req_data['s'] . '%';
1157
-            $_where['OR'] = array(
1158
-                'TKT_name'        => array('LIKE', $sstr),
1159
-                'TKT_description' => array('LIKE', $sstr),
1160
-            );
1161
-        }
1162
-        $query_params = array(
1163
-            $_where,
1164
-            'order_by' => $orderby,
1165
-            'limit'    => $limit,
1166
-            'group_by' => 'TKT_ID',
1167
-        );
1168
-        if ($count) {
1169
-            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1170
-        } else {
1171
-            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1172
-        }
1173
-    }
1174
-
1175
-
1176
-    /**
1177
-     * @param bool $trash
1178
-     * @throws EE_Error
1179
-     */
1180
-    protected function _trash_or_restore_ticket($trash = false)
1181
-    {
1182
-        $success = 1;
1183
-        $TKT     = EEM_Ticket::instance();
1184
-        //checkboxes?
1185
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1186
-            //if array has more than one element then success message should be plural
1187
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1188
-            //cycle thru the boxes
1189
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1190
-                if ($trash) {
1191
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1192
-                        $success = 0;
1193
-                    }
1194
-                } else {
1195
-                    if (! $TKT->restore_by_ID($TKT_ID)) {
1196
-                        $success = 0;
1197
-                    }
1198
-                }
1199
-            }
1200
-        } else {
1201
-            //grab single id and trash
1202
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1203
-            if ($trash) {
1204
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1205
-                    $success = 0;
1206
-                }
1207
-            } else {
1208
-                if (! $TKT->restore_by_ID($TKT_ID)) {
1209
-                    $success = 0;
1210
-                }
1211
-            }
1212
-        }
1213
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1214
-        $query_args  = array(
1215
-            'action' => 'ticket_list_table',
1216
-            'status' => $trash ? '' : 'trashed',
1217
-        );
1218
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1219
-    }
1220
-
1221
-
1222
-    /**
1223
-     * Handles trashing default ticket.
1224
-     */
1225
-    protected function _delete_ticket()
1226
-    {
1227
-        $success = 1;
1228
-        //checkboxes?
1229
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1230
-            //if array has more than one element then success message should be plural
1231
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1232
-            //cycle thru the boxes
1233
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1234
-                //delete
1235
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1236
-                    $success = 0;
1237
-                }
1238
-            }
1239
-        } else {
1240
-            //grab single id and trash
1241
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1242
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1243
-                $success = 0;
1244
-            }
1245
-        }
1246
-        $action_desc = 'deleted';
1247
-        $query_args  = array(
1248
-            'action' => 'ticket_list_table',
1249
-            'status' => 'trashed',
1250
-        );
1251
-        //fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1252
-        if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1253
-            array(array('TKT_is_default' => 1)),
1254
-            'TKT_ID',
1255
-            true
1256
-        )
1257
-        ) {
1258
-            $query_args = array();
1259
-        }
1260
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1261
-    }
1262
-
1263
-
1264
-    /**
1265
-     * @param int $TKT_ID
1266
-     * @return bool|int
1267
-     * @throws EE_Error
1268
-     */
1269
-    protected function _delete_the_ticket($TKT_ID)
1270
-    {
1271
-        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1272
-        $tkt->_remove_relations('Datetime');
1273
-        //delete all related prices first
1274
-        $tkt->delete_related_permanently('Price');
1275
-        return $tkt->delete_permanently();
1276
-    }
17
+	/**
18
+	 * Extend_Events_Admin_Page constructor.
19
+	 *
20
+	 * @param bool $routing
21
+	 */
22
+	public function __construct($routing = true)
23
+	{
24
+		parent::__construct($routing);
25
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
26
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
27
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
28
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
29
+		}
30
+	}
31
+
32
+
33
+	/**
34
+	 * Sets routes.
35
+	 */
36
+	protected function _extend_page_config()
37
+	{
38
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
39
+		//is there a evt_id in the request?
40
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
41
+			? $this->_req_data['EVT_ID']
42
+			: 0;
43
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
44
+		//tkt_id?
45
+		$tkt_id             = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
46
+			? $this->_req_data['TKT_ID']
47
+			: 0;
48
+		$new_page_routes    = array(
49
+			'duplicate_event'          => array(
50
+				'func'       => '_duplicate_event',
51
+				'capability' => 'ee_edit_event',
52
+				'obj_id'     => $evt_id,
53
+				'noheader'   => true,
54
+			),
55
+			'ticket_list_table'        => array(
56
+				'func'       => '_tickets_overview_list_table',
57
+				'capability' => 'ee_read_default_tickets',
58
+			),
59
+			'trash_ticket'             => array(
60
+				'func'       => '_trash_or_restore_ticket',
61
+				'capability' => 'ee_delete_default_ticket',
62
+				'obj_id'     => $tkt_id,
63
+				'noheader'   => true,
64
+				'args'       => array('trash' => true),
65
+			),
66
+			'trash_tickets'            => array(
67
+				'func'       => '_trash_or_restore_ticket',
68
+				'capability' => 'ee_delete_default_tickets',
69
+				'noheader'   => true,
70
+				'args'       => array('trash' => true),
71
+			),
72
+			'restore_ticket'           => array(
73
+				'func'       => '_trash_or_restore_ticket',
74
+				'capability' => 'ee_delete_default_ticket',
75
+				'obj_id'     => $tkt_id,
76
+				'noheader'   => true,
77
+			),
78
+			'restore_tickets'          => array(
79
+				'func'       => '_trash_or_restore_ticket',
80
+				'capability' => 'ee_delete_default_tickets',
81
+				'noheader'   => true,
82
+			),
83
+			'delete_ticket'            => array(
84
+				'func'       => '_delete_ticket',
85
+				'capability' => 'ee_delete_default_ticket',
86
+				'obj_id'     => $tkt_id,
87
+				'noheader'   => true,
88
+			),
89
+			'delete_tickets'           => array(
90
+				'func'       => '_delete_ticket',
91
+				'capability' => 'ee_delete_default_tickets',
92
+				'noheader'   => true,
93
+			),
94
+			'import_page'              => array(
95
+				'func'       => '_import_page',
96
+				'capability' => 'import',
97
+			),
98
+			'import'                   => array(
99
+				'func'       => '_import_events',
100
+				'capability' => 'import',
101
+				'noheader'   => true,
102
+			),
103
+			'import_events'            => array(
104
+				'func'       => '_import_events',
105
+				'capability' => 'import',
106
+				'noheader'   => true,
107
+			),
108
+			'export_events'            => array(
109
+				'func'       => '_events_export',
110
+				'capability' => 'export',
111
+				'noheader'   => true,
112
+			),
113
+			'export_categories'        => array(
114
+				'func'       => '_categories_export',
115
+				'capability' => 'export',
116
+				'noheader'   => true,
117
+			),
118
+			'sample_export_file'       => array(
119
+				'func'       => '_sample_export_file',
120
+				'capability' => 'export',
121
+				'noheader'   => true,
122
+			),
123
+			'update_template_settings' => array(
124
+				'func'       => '_update_template_settings',
125
+				'capability' => 'manage_options',
126
+				'noheader'   => true,
127
+			),
128
+		);
129
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
130
+		//partial route/config override
131
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
132
+		$this->_page_config['create_new']['metaboxes'][]  = '_premium_event_editor_meta_boxes';
133
+		$this->_page_config['create_new']['qtips'][]      = 'EE_Event_Editor_Tips';
134
+		$this->_page_config['edit']['qtips'][]            = 'EE_Event_Editor_Tips';
135
+		$this->_page_config['edit']['metaboxes'][]        = '_premium_event_editor_meta_boxes';
136
+		$this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
137
+		//add tickets tab but only if there are more than one default ticket!
138
+		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
139
+			array(array('TKT_is_default' => 1)),
140
+			'TKT_ID',
141
+			true
142
+		);
143
+		if ($tkt_count > 1) {
144
+			$new_page_config = array(
145
+				'ticket_list_table' => array(
146
+					'nav'           => array(
147
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
148
+						'order' => 60,
149
+					),
150
+					'list_table'    => 'Tickets_List_Table',
151
+					'require_nonce' => false,
152
+				),
153
+			);
154
+		}
155
+		//template settings
156
+		$new_page_config['template_settings'] = array(
157
+			'nav'           => array(
158
+				'label' => esc_html__('Templates', 'event_espresso'),
159
+				'order' => 30,
160
+			),
161
+			'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
162
+			'help_tabs'     => array(
163
+				'general_settings_templates_help_tab' => array(
164
+					'title'    => esc_html__('Templates', 'event_espresso'),
165
+					'filename' => 'general_settings_templates',
166
+				),
167
+			),
168
+			'help_tour'     => array('Templates_Help_Tour'),
169
+			'require_nonce' => false,
170
+		);
171
+		$this->_page_config                   = array_merge($this->_page_config, $new_page_config);
172
+		//add filters and actions
173
+		//modifying _views
174
+		add_filter(
175
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
176
+			array($this, 'add_additional_datetime_button'),
177
+			10,
178
+			2
179
+		);
180
+		add_filter(
181
+			'FHEE_event_datetime_metabox_clone_button_template',
182
+			array($this, 'add_datetime_clone_button'),
183
+			10,
184
+			2
185
+		);
186
+		add_filter(
187
+			'FHEE_event_datetime_metabox_timezones_template',
188
+			array($this, 'datetime_timezones_template'),
189
+			10,
190
+			2
191
+		);
192
+		//filters for event list table
193
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
194
+		add_filter(
195
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
196
+			array($this, 'extra_list_table_actions'),
197
+			10,
198
+			2
199
+		);
200
+		//legend item
201
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
202
+		add_action('admin_init', array($this, 'admin_init'));
203
+		//heartbeat stuff
204
+		add_filter('heartbeat_received', array($this, 'heartbeat_response'), 10, 2);
205
+	}
206
+
207
+
208
+	/**
209
+	 * admin_init
210
+	 */
211
+	public function admin_init()
212
+	{
213
+		EE_Registry::$i18n_js_strings = array_merge(
214
+			EE_Registry::$i18n_js_strings,
215
+			array(
216
+				'image_confirm'          => esc_html__(
217
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
218
+					'event_espresso'
219
+				),
220
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
221
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
222
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
223
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
224
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
225
+			)
226
+		);
227
+	}
228
+
229
+
230
+	/**
231
+	 * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
232
+	 * accordingly.
233
+	 *
234
+	 * @param array $response The existing heartbeat response array.
235
+	 * @param array $data     The incoming data package.
236
+	 * @return array  possibly appended response.
237
+	 */
238
+	public function heartbeat_response($response, $data)
239
+	{
240
+		/**
241
+		 * check whether count of tickets is approaching the potential
242
+		 * limits for the server.
243
+		 */
244
+		if (! empty($data['input_count'])) {
245
+			$response['max_input_vars_check'] = EE_Registry::instance()->CFG->environment->max_input_vars_limit_check(
246
+				$data['input_count']
247
+			);
248
+		}
249
+		return $response;
250
+	}
251
+
252
+
253
+	/**
254
+	 * Add per page screen options to the default ticket list table view.
255
+	 */
256
+	protected function _add_screen_options_ticket_list_table()
257
+	{
258
+		$this->_per_page_screen_option();
259
+	}
260
+
261
+
262
+	/**
263
+	 * @param string $return
264
+	 * @param int    $id
265
+	 * @param string $new_title
266
+	 * @param string $new_slug
267
+	 * @return string
268
+	 */
269
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
270
+	{
271
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
272
+		//make sure this is only when editing
273
+		if (! empty($id)) {
274
+			$href   = EE_Admin_Page::add_query_args_and_nonce(
275
+				array('action' => 'duplicate_event', 'EVT_ID' => $id),
276
+				$this->_admin_base_url
277
+			);
278
+			$title  = esc_attr__('Duplicate Event', 'event_espresso');
279
+			$return .= '<a href="'
280
+					   . $href
281
+					   . '" title="'
282
+					   . $title
283
+					   . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
284
+					   . $title
285
+					   . '</button>';
286
+		}
287
+		return $return;
288
+	}
289
+
290
+
291
+	/**
292
+	 * Set the list table views for the default ticket list table view.
293
+	 */
294
+	public function _set_list_table_views_ticket_list_table()
295
+	{
296
+		$this->_views = array(
297
+			'all'     => array(
298
+				'slug'        => 'all',
299
+				'label'       => esc_html__('All', 'event_espresso'),
300
+				'count'       => 0,
301
+				'bulk_action' => array(
302
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
303
+				),
304
+			),
305
+			'trashed' => array(
306
+				'slug'        => 'trashed',
307
+				'label'       => esc_html__('Trash', 'event_espresso'),
308
+				'count'       => 0,
309
+				'bulk_action' => array(
310
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
311
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
312
+				),
313
+			),
314
+		);
315
+	}
316
+
317
+
318
+	/**
319
+	 * Enqueue scripts and styles for the event editor.
320
+	 */
321
+	public function load_scripts_styles_edit()
322
+	{
323
+		wp_register_script(
324
+			'ee-event-editor-heartbeat',
325
+			EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
326
+			array('ee_admin_js', 'heartbeat'),
327
+			EVENT_ESPRESSO_VERSION,
328
+			true
329
+		);
330
+		wp_enqueue_script('ee-accounting');
331
+		//styles
332
+		wp_enqueue_style('espresso-ui-theme');
333
+		wp_enqueue_script('event_editor_js');
334
+		wp_enqueue_script('ee-event-editor-heartbeat');
335
+	}
336
+
337
+
338
+	/**
339
+	 * Returns template for the additional datetime.
340
+	 * @param $template
341
+	 * @param $template_args
342
+	 * @return mixed
343
+	 * @throws DomainException
344
+	 */
345
+	public function add_additional_datetime_button($template, $template_args)
346
+	{
347
+		return EEH_Template::display_template(
348
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
349
+			$template_args,
350
+			true
351
+		);
352
+	}
353
+
354
+
355
+	/**
356
+	 * Returns the template for cloning a datetime.
357
+	 * @param $template
358
+	 * @param $template_args
359
+	 * @return mixed
360
+	 * @throws DomainException
361
+	 */
362
+	public function add_datetime_clone_button($template, $template_args)
363
+	{
364
+		return EEH_Template::display_template(
365
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
366
+			$template_args,
367
+			true
368
+		);
369
+	}
370
+
371
+
372
+	/**
373
+	 * Returns the template for datetime timezones.
374
+	 * @param $template
375
+	 * @param $template_args
376
+	 * @return mixed
377
+	 * @throws DomainException
378
+	 */
379
+	public function datetime_timezones_template($template, $template_args)
380
+	{
381
+		return EEH_Template::display_template(
382
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
383
+			$template_args,
384
+			true
385
+		);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Sets the views for the default list table view.
391
+	 */
392
+	protected function _set_list_table_views_default()
393
+	{
394
+		parent::_set_list_table_views_default();
395
+		$new_views    = array(
396
+			'today' => array(
397
+				'slug'        => 'today',
398
+				'label'       => esc_html__('Today', 'event_espresso'),
399
+				'count'       => $this->total_events_today(),
400
+				'bulk_action' => array(
401
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
402
+				),
403
+			),
404
+			'month' => array(
405
+				'slug'        => 'month',
406
+				'label'       => esc_html__('This Month', 'event_espresso'),
407
+				'count'       => $this->total_events_this_month(),
408
+				'bulk_action' => array(
409
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
410
+				),
411
+			),
412
+		);
413
+		$this->_views = array_merge($this->_views, $new_views);
414
+	}
415
+
416
+
417
+	/**
418
+	 * Returns the extra action links for the default list table view.
419
+	 * @param array     $action_links
420
+	 * @param \EE_Event $event
421
+	 * @return array
422
+	 * @throws EE_Error
423
+	 */
424
+	public function extra_list_table_actions(array $action_links, \EE_Event $event)
425
+	{
426
+		if (EE_Registry::instance()->CAP->current_user_can(
427
+			'ee_read_registrations',
428
+			'espresso_registrations_reports',
429
+			$event->ID()
430
+		)
431
+		) {
432
+			$reports_query_args = array(
433
+				'action' => 'reports',
434
+				'EVT_ID' => $event->ID(),
435
+			);
436
+			$reports_link       = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
437
+			$action_links[]     = '<a href="'
438
+								  . $reports_link
439
+								  . '" title="'
440
+								  . esc_attr__('View Report', 'event_espresso')
441
+								  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
442
+								  . "\n\t";
443
+		}
444
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
445
+			EE_Registry::instance()->load_helper('MSG_Template');
446
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
447
+				'see_notifications_for',
448
+				null,
449
+				array('EVT_ID' => $event->ID())
450
+			);
451
+		}
452
+		return $action_links;
453
+	}
454
+
455
+
456
+	/**
457
+	 * @param $items
458
+	 * @return mixed
459
+	 */
460
+	public function additional_legend_items($items)
461
+	{
462
+		if (EE_Registry::instance()->CAP->current_user_can(
463
+			'ee_read_registrations',
464
+			'espresso_registrations_reports'
465
+		)
466
+		) {
467
+			$items['reports'] = array(
468
+				'class' => 'dashicons dashicons-chart-bar',
469
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
470
+			);
471
+		}
472
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
473
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
474
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
475
+				$items['view_related_messages'] = array(
476
+					'class' => $related_for_icon['css_class'],
477
+					'desc'  => $related_for_icon['label'],
478
+				);
479
+			}
480
+		}
481
+		return $items;
482
+	}
483
+
484
+
485
+	/**
486
+	 * This is the callback method for the duplicate event route
487
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
488
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
489
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
490
+	 * After duplication the redirect is to the new event edit page.
491
+	 *
492
+	 * @return void
493
+	 * @access protected
494
+	 * @throws EE_Error If EE_Event is not available with given ID
495
+	 */
496
+	protected function _duplicate_event()
497
+	{
498
+		// first make sure the ID for the event is in the request.
499
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
500
+		if (! isset($this->_req_data['EVT_ID'])) {
501
+			EE_Error::add_error(
502
+				esc_html__(
503
+					'In order to duplicate an event an Event ID is required.  None was given.',
504
+					'event_espresso'
505
+				),
506
+				__FILE__,
507
+				__FUNCTION__,
508
+				__LINE__
509
+			);
510
+			$this->_redirect_after_action(false, '', '', array(), true);
511
+			return;
512
+		}
513
+		//k we've got EVT_ID so let's use that to get the event we'll duplicate
514
+		$orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
515
+		if (! $orig_event instanceof EE_Event) {
516
+			throw new EE_Error(
517
+				sprintf(
518
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
519
+					$this->_req_data['EVT_ID']
520
+				)
521
+			);
522
+		}
523
+		//k now let's clone the $orig_event before getting relations
524
+		$new_event = clone $orig_event;
525
+		//original datetimes
526
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
527
+		//other original relations
528
+		$orig_ven = $orig_event->get_many_related('Venue');
529
+		//reset the ID and modify other details to make it clear this is a dupe
530
+		$new_event->set('EVT_ID', 0);
531
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
532
+		$new_event->set('EVT_name', $new_name);
533
+		$new_event->set(
534
+			'EVT_slug',
535
+			wp_unique_post_slug(
536
+				sanitize_title($orig_event->name()),
537
+				0,
538
+				'publish',
539
+				'espresso_events',
540
+				0
541
+			)
542
+		);
543
+		$new_event->set('status', 'draft');
544
+		//duplicate discussion settings
545
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
546
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
547
+		//save the new event
548
+		$new_event->save();
549
+		//venues
550
+		foreach ($orig_ven as $ven) {
551
+			$new_event->_add_relation_to($ven, 'Venue');
552
+		}
553
+		$new_event->save();
554
+		//now we need to get the question group relations and handle that
555
+		//first primary question groups
556
+		$orig_primary_qgs = $orig_event->get_many_related(
557
+			'Question_Group',
558
+			array(array('Event_Question_Group.EQG_primary' => 1))
559
+		);
560
+		if (! empty($orig_primary_qgs)) {
561
+			foreach ($orig_primary_qgs as $id => $obj) {
562
+				if ($obj instanceof EE_Question_Group) {
563
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
564
+				}
565
+			}
566
+		}
567
+		//next additional attendee question groups
568
+		$orig_additional_qgs = $orig_event->get_many_related(
569
+			'Question_Group',
570
+			array(array('Event_Question_Group.EQG_primary' => 0))
571
+		);
572
+		if (! empty($orig_additional_qgs)) {
573
+			foreach ($orig_additional_qgs as $id => $obj) {
574
+				if ($obj instanceof EE_Question_Group) {
575
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
576
+				}
577
+			}
578
+		}
579
+
580
+		$new_event->save();
581
+
582
+		//k now that we have the new event saved we can loop through the datetimes and start adding relations.
583
+		$cloned_tickets = array();
584
+		foreach ($orig_datetimes as $orig_dtt) {
585
+			if (! $orig_dtt instanceof EE_Datetime) {
586
+				continue;
587
+			}
588
+			$new_dtt   = clone $orig_dtt;
589
+			$orig_tkts = $orig_dtt->tickets();
590
+			//save new dtt then add to event
591
+			$new_dtt->set('DTT_ID', 0);
592
+			$new_dtt->set('DTT_sold', 0);
593
+			$new_dtt->set_reserved(0);
594
+			$new_dtt->save();
595
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
596
+			$new_event->save();
597
+			//now let's get the ticket relations setup.
598
+			foreach ((array)$orig_tkts as $orig_tkt) {
599
+				//it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
600
+				if (! $orig_tkt instanceof EE_Ticket) {
601
+					continue;
602
+				}
603
+				//is this ticket archived?  If it is then let's skip
604
+				if ($orig_tkt->get('TKT_deleted')) {
605
+					continue;
606
+				}
607
+				// does this original ticket already exist in the clone_tickets cache?
608
+				//  If so we'll just use the new ticket from it.
609
+				if (isset($cloned_tickets[$orig_tkt->ID()])) {
610
+					$new_tkt = $cloned_tickets[$orig_tkt->ID()];
611
+				} else {
612
+					$new_tkt = clone $orig_tkt;
613
+					//get relations on the $orig_tkt that we need to setup.
614
+					$orig_prices = $orig_tkt->prices();
615
+					$new_tkt->set('TKT_ID', 0);
616
+					$new_tkt->set('TKT_sold', 0);
617
+					$new_tkt->set('TKT_reserved', 0);
618
+					$new_tkt->save(); //make sure new ticket has ID.
619
+					//price relations on new ticket need to be setup.
620
+					foreach ($orig_prices as $orig_price) {
621
+						$new_price = clone $orig_price;
622
+						$new_price->set('PRC_ID', 0);
623
+						$new_price->save();
624
+						$new_tkt->_add_relation_to($new_price, 'Price');
625
+						$new_tkt->save();
626
+					}
627
+
628
+					do_action(
629
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
630
+						$orig_tkt,
631
+						$new_tkt,
632
+						$orig_prices,
633
+						$orig_event,
634
+						$orig_dtt,
635
+						$new_dtt
636
+					);
637
+				}
638
+				// k now we can add the new ticket as a relation to the new datetime
639
+				// and make sure its added to our cached $cloned_tickets array
640
+				// for use with later datetimes that have the same ticket.
641
+				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
642
+				$new_dtt->save();
643
+				$cloned_tickets[$orig_tkt->ID()] = $new_tkt;
644
+			}
645
+		}
646
+		//clone taxonomy information
647
+		$taxonomies_to_clone_with = apply_filters(
648
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
649
+			array('espresso_event_categories', 'espresso_event_type', 'post_tag')
650
+		);
651
+		//get terms for original event (notice)
652
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
653
+		//loop through terms and add them to new event.
654
+		foreach ($orig_terms as $term) {
655
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
656
+		}
657
+
658
+		//duplicate other core WP_Post items for this event.
659
+		//post thumbnail (feature image).
660
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
661
+		if ($feature_image_id) {
662
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
663
+		}
664
+
665
+		//duplicate page_template setting
666
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
667
+		if ($page_template) {
668
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
669
+		}
670
+
671
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
672
+		//now let's redirect to the edit page for this duplicated event if we have a new event id.
673
+		if ($new_event->ID()) {
674
+			$redirect_args = array(
675
+				'post'   => $new_event->ID(),
676
+				'action' => 'edit',
677
+			);
678
+			EE_Error::add_success(
679
+				esc_html__(
680
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
681
+					'event_espresso'
682
+				)
683
+			);
684
+		} else {
685
+			$redirect_args = array(
686
+				'action' => 'default',
687
+			);
688
+			EE_Error::add_error(
689
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
690
+				__FILE__,
691
+				__FUNCTION__,
692
+				__LINE__
693
+			);
694
+		}
695
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
696
+	}
697
+
698
+
699
+	/**
700
+	 * Generates output for the import page.
701
+	 * @throws DomainException
702
+	 */
703
+	protected function _import_page()
704
+	{
705
+		$title                                      = esc_html__('Import', 'event_espresso');
706
+		$intro                                      = esc_html__(
707
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
708
+			'event_espresso'
709
+		);
710
+		$form_url                                   = EVENTS_ADMIN_URL;
711
+		$action                                     = 'import_events';
712
+		$type                                       = 'csv';
713
+		$this->_template_args['form']               = EE_Import::instance()->upload_form(
714
+			$title, $intro, $form_url, $action, $type
715
+		);
716
+		$this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
717
+			array('action' => 'sample_export_file'),
718
+			$this->_admin_base_url
719
+		);
720
+		$content                                    = EEH_Template::display_template(
721
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
722
+			$this->_template_args,
723
+			true
724
+		);
725
+		$this->_template_args['admin_page_content'] = $content;
726
+		$this->display_admin_page_with_sidebar();
727
+	}
728
+
729
+
730
+	/**
731
+	 * _import_events
732
+	 * This handles displaying the screen and running imports for importing events.
733
+	 *
734
+	 * @return void
735
+	 */
736
+	protected function _import_events()
737
+	{
738
+		require_once(EE_CLASSES . 'EE_Import.class.php');
739
+		$success = EE_Import::instance()->import();
740
+		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
741
+	}
742
+
743
+
744
+	/**
745
+	 * _events_export
746
+	 * Will export all (or just the given event) to a Excel compatible file.
747
+	 *
748
+	 * @access protected
749
+	 * @return void
750
+	 */
751
+	protected function _events_export()
752
+	{
753
+		if (isset($this->_req_data['EVT_ID'])) {
754
+			$event_ids = $this->_req_data['EVT_ID'];
755
+		} elseif (isset($this->_req_data['EVT_IDs'])) {
756
+			$event_ids = $this->_req_data['EVT_IDs'];
757
+		} else {
758
+			$event_ids = null;
759
+		}
760
+		//todo: I don't like doing this but it'll do until we modify EE_Export Class.
761
+		$new_request_args = array(
762
+			'export' => 'report',
763
+			'action' => 'all_event_data',
764
+			'EVT_ID' => $event_ids,
765
+		);
766
+		$this->_req_data  = array_merge($this->_req_data, $new_request_args);
767
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
768
+			require_once(EE_CLASSES . 'EE_Export.class.php');
769
+			$EE_Export = EE_Export::instance($this->_req_data);
770
+			$EE_Export->export();
771
+		}
772
+	}
773
+
774
+
775
+	/**
776
+	 * handle category exports()
777
+	 *
778
+	 * @return void
779
+	 */
780
+	protected function _categories_export()
781
+	{
782
+		//todo: I don't like doing this but it'll do until we modify EE_Export Class.
783
+		$new_request_args = array(
784
+			'export'       => 'report',
785
+			'action'       => 'categories',
786
+			'category_ids' => $this->_req_data['EVT_CAT_ID'],
787
+		);
788
+		$this->_req_data  = array_merge($this->_req_data, $new_request_args);
789
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
790
+			require_once(EE_CLASSES . 'EE_Export.class.php');
791
+			$EE_Export = EE_Export::instance($this->_req_data);
792
+			$EE_Export->export();
793
+		}
794
+	}
795
+
796
+
797
+	/**
798
+	 * Creates a sample CSV file for importing
799
+	 */
800
+	protected function _sample_export_file()
801
+	{
802
+		//		require_once(EE_CLASSES . 'EE_Export.class.php');
803
+		EE_Export::instance()->export_sample();
804
+	}
805
+
806
+
807
+	/*************        Template Settings        *************/
808
+	/**
809
+	 * Generates template settings page output
810
+	 * @throws DomainException
811
+	 * @throws EE_Error
812
+	 */
813
+	protected function _template_settings()
814
+	{
815
+		$this->_template_args['values'] = $this->_yes_no_values;
816
+		/**
817
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
818
+		 * from General_Settings_Admin_Page to here.
819
+		 */
820
+		$this->_template_args = apply_filters(
821
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
822
+			$this->_template_args
823
+		);
824
+		$this->_set_add_edit_form_tags('update_template_settings');
825
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
826
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
827
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
828
+			$this->_template_args,
829
+			true
830
+		);
831
+		$this->display_admin_page_with_sidebar();
832
+	}
833
+
834
+
835
+	/**
836
+	 * Handler for updating template settings.
837
+	 */
838
+	protected function _update_template_settings()
839
+	{
840
+		/**
841
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
842
+		 * from General_Settings_Admin_Page to here.
843
+		 */
844
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
845
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
846
+			EE_Registry::instance()->CFG->template_settings,
847
+			$this->_req_data
848
+		);
849
+		//update custom post type slugs and detect if we need to flush rewrite rules
850
+		$old_slug                                          = EE_Registry::instance()->CFG->core->event_cpt_slug;
851
+		EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
852
+			? EE_Registry::instance()->CFG->core->event_cpt_slug
853
+			: sanitize_title_with_dashes($this->_req_data['event_cpt_slug']);
854
+		$what                                              = 'Template Settings';
855
+		$success                                           = $this->_update_espresso_configuration(
856
+			$what,
857
+			EE_Registry::instance()->CFG->template_settings,
858
+			__FILE__,
859
+			__FUNCTION__,
860
+			__LINE__
861
+		);
862
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
863
+			update_option('ee_flush_rewrite_rules', true);
864
+		}
865
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
866
+	}
867
+
868
+
869
+	/**
870
+	 * _premium_event_editor_meta_boxes
871
+	 * add all metaboxes related to the event_editor
872
+	 *
873
+	 * @access protected
874
+	 * @return void
875
+	 * @throws EE_Error
876
+	 */
877
+	protected function _premium_event_editor_meta_boxes()
878
+	{
879
+		$this->verify_cpt_object();
880
+		add_meta_box(
881
+			'espresso_event_editor_event_options',
882
+			esc_html__('Event Registration Options', 'event_espresso'),
883
+			array($this, 'registration_options_meta_box'),
884
+			$this->page_slug,
885
+			'side',
886
+			'core'
887
+		);
888
+	}
889
+
890
+
891
+	/**
892
+	 * override caf metabox
893
+	 *
894
+	 * @return void
895
+	 * @throws DomainException
896
+	 */
897
+	public function registration_options_meta_box()
898
+	{
899
+		$yes_no_values                                    = array(
900
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
901
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
902
+		);
903
+		$default_reg_status_values                        = EEM_Registration::reg_status_array(
904
+			array(
905
+				EEM_Registration::status_id_cancelled,
906
+				EEM_Registration::status_id_declined,
907
+				EEM_Registration::status_id_incomplete,
908
+				EEM_Registration::status_id_wait_list,
909
+			),
910
+			true
911
+		);
912
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
913
+		$template_args['_event']                          = $this->_cpt_model_obj;
914
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
915
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
916
+			'default_reg_status',
917
+			$default_reg_status_values,
918
+			$this->_cpt_model_obj->default_registration_status()
919
+		);
920
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
921
+			'display_desc',
922
+			$yes_no_values,
923
+			$this->_cpt_model_obj->display_description()
924
+		);
925
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
926
+			'display_ticket_selector',
927
+			$yes_no_values,
928
+			$this->_cpt_model_obj->display_ticket_selector(),
929
+			'',
930
+			'',
931
+			false
932
+		);
933
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
934
+			'EVT_default_registration_status',
935
+			$default_reg_status_values,
936
+			$this->_cpt_model_obj->default_registration_status()
937
+		);
938
+		$template_args['additional_registration_options'] = apply_filters(
939
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
940
+			'',
941
+			$template_args,
942
+			$yes_no_values,
943
+			$default_reg_status_values
944
+		);
945
+		EEH_Template::display_template(
946
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
947
+			$template_args
948
+		);
949
+	}
950
+
951
+
952
+
953
+	/**
954
+	 * wp_list_table_mods for caf
955
+	 * ============================
956
+	 */
957
+	/**
958
+	 * hook into list table filters and provide filters for caffeinated list table
959
+	 *
960
+	 * @param  array $old_filters    any existing filters present
961
+	 * @param  array $list_table_obj the list table object
962
+	 * @return array                  new filters
963
+	 */
964
+	public function list_table_filters($old_filters, $list_table_obj)
965
+	{
966
+		$filters = array();
967
+		//first month/year filters
968
+		$filters[] = $this->espresso_event_months_dropdown();
969
+		$status    = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
970
+		//active status dropdown
971
+		if ($status !== 'draft') {
972
+			$filters[] = $this->active_status_dropdown(
973
+				isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
974
+			);
975
+		}
976
+		//category filter
977
+		$filters[] = $this->category_dropdown();
978
+		return array_merge($old_filters, $filters);
979
+	}
980
+
981
+
982
+	/**
983
+	 * espresso_event_months_dropdown
984
+	 *
985
+	 * @access public
986
+	 * @return string                dropdown listing month/year selections for events.
987
+	 */
988
+	public function espresso_event_months_dropdown()
989
+	{
990
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
991
+		// Note we need to include any other filters that are set!
992
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
993
+		//categories?
994
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
995
+			? $this->_req_data['EVT_CAT']
996
+			: null;
997
+		//active status?
998
+		$active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
999
+		$cur_date      = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1000
+		return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1001
+	}
1002
+
1003
+
1004
+	/**
1005
+	 * returns a list of "active" statuses on the event
1006
+	 *
1007
+	 * @param  string $current_value whatever the current active status is
1008
+	 * @return string
1009
+	 */
1010
+	public function active_status_dropdown($current_value = '')
1011
+	{
1012
+		$select_name = 'active_status';
1013
+		$values      = array(
1014
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1015
+			'active'   => esc_html__('Active', 'event_espresso'),
1016
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1017
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1018
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1019
+		);
1020
+		$id          = 'id="espresso-active-status-dropdown-filter"';
1021
+		$class       = 'wide';
1022
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1023
+	}
1024
+
1025
+
1026
+	/**
1027
+	 * output a dropdown of the categories for the category filter on the event admin list table
1028
+	 *
1029
+	 * @access  public
1030
+	 * @return string html
1031
+	 */
1032
+	public function category_dropdown()
1033
+	{
1034
+		$cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1035
+		return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1036
+	}
1037
+
1038
+
1039
+	/**
1040
+	 * get total number of events today
1041
+	 *
1042
+	 * @access public
1043
+	 * @return int
1044
+	 * @throws EE_Error
1045
+	 */
1046
+	public function total_events_today()
1047
+	{
1048
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1049
+			'DTT_EVT_start',
1050
+			date('Y-m-d') . ' 00:00:00',
1051
+			'Y-m-d H:i:s',
1052
+			'UTC'
1053
+		);
1054
+		$end   = EEM_Datetime::instance()->convert_datetime_for_query(
1055
+			'DTT_EVT_start',
1056
+			date('Y-m-d') . ' 23:59:59',
1057
+			'Y-m-d H:i:s',
1058
+			'UTC'
1059
+		);
1060
+		$where = array(
1061
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1062
+		);
1063
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1064
+		return $count;
1065
+	}
1066
+
1067
+
1068
+	/**
1069
+	 * get total number of events this month
1070
+	 *
1071
+	 * @access public
1072
+	 * @return int
1073
+	 * @throws EE_Error
1074
+	 */
1075
+	public function total_events_this_month()
1076
+	{
1077
+		//Dates
1078
+		$this_year_r     = date('Y');
1079
+		$this_month_r    = date('m');
1080
+		$days_this_month = date('t');
1081
+		$start           = EEM_Datetime::instance()->convert_datetime_for_query(
1082
+			'DTT_EVT_start',
1083
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1084
+			'Y-m-d H:i:s',
1085
+			'UTC'
1086
+		);
1087
+		$end             = EEM_Datetime::instance()->convert_datetime_for_query(
1088
+			'DTT_EVT_start',
1089
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1090
+			'Y-m-d H:i:s',
1091
+			'UTC'
1092
+		);
1093
+		$where           = array(
1094
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1095
+		);
1096
+		$count           = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1097
+		return $count;
1098
+	}
1099
+
1100
+
1101
+	/** DEFAULT TICKETS STUFF **/
1102
+
1103
+	/**
1104
+	 * Output default tickets list table view.
1105
+	 */
1106
+	public function _tickets_overview_list_table()
1107
+	{
1108
+		$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1109
+		$this->display_admin_list_table_page_with_no_sidebar();
1110
+	}
1111
+
1112
+
1113
+	/**
1114
+	 * @param int  $per_page
1115
+	 * @param bool $count
1116
+	 * @param bool $trashed
1117
+	 * @return \EE_Soft_Delete_Base_Class[]|int
1118
+	 */
1119
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1120
+	{
1121
+		$orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1122
+		$order   = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1123
+		switch ($orderby) {
1124
+			case 'TKT_name':
1125
+				$orderby = array('TKT_name' => $order);
1126
+				break;
1127
+			case 'TKT_price':
1128
+				$orderby = array('TKT_price' => $order);
1129
+				break;
1130
+			case 'TKT_uses':
1131
+				$orderby = array('TKT_uses' => $order);
1132
+				break;
1133
+			case 'TKT_min':
1134
+				$orderby = array('TKT_min' => $order);
1135
+				break;
1136
+			case 'TKT_max':
1137
+				$orderby = array('TKT_max' => $order);
1138
+				break;
1139
+			case 'TKT_qty':
1140
+				$orderby = array('TKT_qty' => $order);
1141
+				break;
1142
+		}
1143
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1144
+			? $this->_req_data['paged']
1145
+			: 1;
1146
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1147
+			? $this->_req_data['perpage']
1148
+			: $per_page;
1149
+		$_where       = array(
1150
+			'TKT_is_default' => 1,
1151
+			'TKT_deleted'    => $trashed,
1152
+		);
1153
+		$offset       = ($current_page - 1) * $per_page;
1154
+		$limit        = array($offset, $per_page);
1155
+		if (isset($this->_req_data['s'])) {
1156
+			$sstr         = '%' . $this->_req_data['s'] . '%';
1157
+			$_where['OR'] = array(
1158
+				'TKT_name'        => array('LIKE', $sstr),
1159
+				'TKT_description' => array('LIKE', $sstr),
1160
+			);
1161
+		}
1162
+		$query_params = array(
1163
+			$_where,
1164
+			'order_by' => $orderby,
1165
+			'limit'    => $limit,
1166
+			'group_by' => 'TKT_ID',
1167
+		);
1168
+		if ($count) {
1169
+			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1170
+		} else {
1171
+			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1172
+		}
1173
+	}
1174
+
1175
+
1176
+	/**
1177
+	 * @param bool $trash
1178
+	 * @throws EE_Error
1179
+	 */
1180
+	protected function _trash_or_restore_ticket($trash = false)
1181
+	{
1182
+		$success = 1;
1183
+		$TKT     = EEM_Ticket::instance();
1184
+		//checkboxes?
1185
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1186
+			//if array has more than one element then success message should be plural
1187
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1188
+			//cycle thru the boxes
1189
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1190
+				if ($trash) {
1191
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1192
+						$success = 0;
1193
+					}
1194
+				} else {
1195
+					if (! $TKT->restore_by_ID($TKT_ID)) {
1196
+						$success = 0;
1197
+					}
1198
+				}
1199
+			}
1200
+		} else {
1201
+			//grab single id and trash
1202
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1203
+			if ($trash) {
1204
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1205
+					$success = 0;
1206
+				}
1207
+			} else {
1208
+				if (! $TKT->restore_by_ID($TKT_ID)) {
1209
+					$success = 0;
1210
+				}
1211
+			}
1212
+		}
1213
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1214
+		$query_args  = array(
1215
+			'action' => 'ticket_list_table',
1216
+			'status' => $trash ? '' : 'trashed',
1217
+		);
1218
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1219
+	}
1220
+
1221
+
1222
+	/**
1223
+	 * Handles trashing default ticket.
1224
+	 */
1225
+	protected function _delete_ticket()
1226
+	{
1227
+		$success = 1;
1228
+		//checkboxes?
1229
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1230
+			//if array has more than one element then success message should be plural
1231
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1232
+			//cycle thru the boxes
1233
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1234
+				//delete
1235
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1236
+					$success = 0;
1237
+				}
1238
+			}
1239
+		} else {
1240
+			//grab single id and trash
1241
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1242
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1243
+				$success = 0;
1244
+			}
1245
+		}
1246
+		$action_desc = 'deleted';
1247
+		$query_args  = array(
1248
+			'action' => 'ticket_list_table',
1249
+			'status' => 'trashed',
1250
+		);
1251
+		//fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1252
+		if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1253
+			array(array('TKT_is_default' => 1)),
1254
+			'TKT_ID',
1255
+			true
1256
+		)
1257
+		) {
1258
+			$query_args = array();
1259
+		}
1260
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1261
+	}
1262
+
1263
+
1264
+	/**
1265
+	 * @param int $TKT_ID
1266
+	 * @return bool|int
1267
+	 * @throws EE_Error
1268
+	 */
1269
+	protected function _delete_the_ticket($TKT_ID)
1270
+	{
1271
+		$tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1272
+		$tkt->_remove_relations('Datetime');
1273
+		//delete all related prices first
1274
+		$tkt->delete_related_permanently('Price');
1275
+		return $tkt->delete_permanently();
1276
+	}
1277 1277
 }
Please login to merge, or discard this patch.
core/libraries/payment_methods/EE_Payment_Method_Manager.lib.php 1 patch
Indentation   +564 added lines, -564 removed lines patch added patch discarded remove patch
@@ -19,570 +19,570 @@
 block discarded – undo
19 19
 class EE_Payment_Method_Manager implements ResettableInterface
20 20
 {
21 21
 
22
-    /**
23
-     * prefix added to all payment method capabilities names
24
-     */
25
-    const   CAPABILITIES_PREFIX= 'ee_payment_method_';
26
-
27
-    /**
28
-     * @var EE_Payment_Method_Manager $_instance
29
-     */
30
-    private static $_instance;
31
-
32
-    /**
33
-     * @var boolean
34
-     */
35
-    protected $payment_method_caps_initialized = false;
36
-
37
-    /**
38
-     * @var array keys are class names without 'EE_PMT_', values are their filepaths
39
-     */
40
-    protected $_payment_method_types = array();
41
-
42
-    /**
43
-     * @var EE_PMT_Base[]
44
-     */
45
-    protected $payment_method_objects = array();
46
-
47
-
48
-
49
-    /**
50
-     * EE_Payment_Method_Manager constructor.
51
-     *
52
-     * @throws EE_Error
53
-     * @throws DomainException
54
-     */
55
-    public function __construct()
56
-    {
57
-        // if in admin lets ensure caps are set.
58
-        if (is_admin()) {
59
-            $this->_register_payment_methods();
60
-            // set them immediately
61
-            $this->initializePaymentMethodCaps();
62
-            // plus any time they get reset
63
-            add_filter(
64
-                'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
65
-                array($this, 'addPaymentMethodCapsDuringReset')
66
-            );
67
-        }
68
-    }
69
-
70
-
71
-
72
-    /**
73
-     * @singleton method used to instantiate class object
74
-     * @return EE_Payment_Method_Manager instance
75
-     * @throws DomainException
76
-     * @throws EE_Error
77
-     */
78
-    public static function instance()
79
-    {
80
-        // check if class object is instantiated, and instantiated properly
81
-        if (! self::$_instance instanceof EE_Payment_Method_Manager) {
82
-            EE_Registry::instance()->load_lib('PMT_Base');
83
-            self::$_instance = new self();
84
-        }
85
-        return self::$_instance;
86
-    }
87
-
88
-
89
-
90
-    /**
91
-     * Resets the instance and returns a new one
92
-     *
93
-     * @return EE_Payment_Method_Manager
94
-     * @throws DomainException
95
-     * @throws EE_Error
96
-     */
97
-    public static function reset()
98
-    {
99
-        self::$_instance = null;
100
-        return self::instance();
101
-    }
102
-
103
-
104
-
105
-    /**
106
-     * If necessary, re-register payment methods
107
-     *
108
-     * @param boolean $force_recheck whether to recheck for payment method types,
109
-     *                               or just re-use the PMTs we found last time we checked during this request (if
110
-     *                               we have not yet checked during this request, then we need to check anyways)
111
-     */
112
-    public function maybe_register_payment_methods($force_recheck = false)
113
-    {
114
-        if (! $this->_payment_method_types || $force_recheck) {
115
-            $this->_register_payment_methods();
116
-        }
117
-    }
118
-
119
-
120
-
121
-    /**
122
-     * register_payment_methods
123
-     *
124
-     * @return array
125
-     */
126
-    protected function _register_payment_methods()
127
-    {
128
-        // grab list of installed modules
129
-        $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
130
-        // filter list of modules to register
131
-        $pm_to_register = apply_filters(
132
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
133
-            $pm_to_register
134
-        );
135
-        // remove any duplicates if that should happen for some reason
136
-        $pm_to_register = array_unique($pm_to_register);
137
-        // loop through folders
138
-        foreach ($pm_to_register as $pm_path) {
139
-            $this->register_payment_method($pm_path);
140
-        }
141
-        do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods');
142
-        // filter list of installed modules
143
-        //keep them organized alphabetically by the payment method type's name
144
-        ksort($this->_payment_method_types);
145
-        return apply_filters(
146
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods',
147
-            $this->_payment_method_types
148
-        );
149
-    }
150
-
151
-
152
-
153
-    /**
154
-     * register_payment_method- makes core aware of this payment method
155
-     *
156
-     * @param string $payment_method_path - full path up to and including payment method folder
157
-     * @return boolean
158
-     */
159
-    public function register_payment_method($payment_method_path = '')
160
-    {
161
-        do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path);
162
-        $module_ext = '.pm.php';
163
-        // make all separators match
164
-        $payment_method_path = rtrim(str_replace('/\\', DS, $payment_method_path), DS);
165
-        // grab and sanitize module name
166
-        $module_dir = basename($payment_method_path);
167
-        // create class name from module directory name
168
-        $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
169
-        // add class prefix
170
-        $module_class = 'EE_PMT_' . $module;
171
-        // does the module exist ?
172
-        if (! is_readable($payment_method_path . DS . $module_class . $module_ext)) {
173
-            $msg = sprintf(
174
-                esc_html__(
175
-                    'The requested %s payment method file could not be found or is not readable due to file permissions.',
176
-                    'event_espresso'
177
-                ), $module
178
-            );
179
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
180
-            return false;
181
-        }
182
-        // load the module class file
183
-        require_once($payment_method_path . DS . $module_class . $module_ext);
184
-        // verify that class exists
185
-        if (! class_exists($module_class)) {
186
-            $msg = sprintf(
187
-                esc_html__('The requested %s module class does not exist.', 'event_espresso'),
188
-                $module_class
189
-            );
190
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
191
-            return false;
192
-        }
193
-        // add to array of registered modules
194
-        $this->_payment_method_types[$module] = $payment_method_path . DS . $module_class . $module_ext;
195
-        return true;
196
-    }
197
-
198
-
199
-
200
-    /**
201
-     * Checks if a payment method has been registered, and if so includes it
202
-     *
203
-     * @param string  $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_')
204
-     * @param boolean $force_recheck       whether to force re-checking for new payment method types
205
-     * @return boolean
206
-     */
207
-    public function payment_method_type_exists($payment_method_name, $force_recheck = false)
208
-    {
209
-        if (
210
-            $force_recheck
211
-            || ! is_array($this->_payment_method_types)
212
-            || ! isset($this->_payment_method_types[$payment_method_name])
213
-        ) {
214
-            $this->maybe_register_payment_methods($force_recheck);
215
-        }
216
-        if (isset($this->_payment_method_types[$payment_method_name])) {
217
-            require_once($this->_payment_method_types[$payment_method_name]);
218
-            return true;
219
-        }
220
-        return false;
221
-    }
222
-
223
-
224
-
225
-    /**
226
-     * Returns all the class names of the various payment method types
227
-     *
228
-     * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names'
229
-     *                               (what you'd find in wp_esp_payment_method.PMD_type)
230
-     * @param boolean $force_recheck whether to force re-checking for new payment method types
231
-     * @return array
232
-     */
233
-    public function payment_method_type_names($with_prefixes = false, $force_recheck = false)
234
-    {
235
-        $this->maybe_register_payment_methods($force_recheck);
236
-        if ($with_prefixes) {
237
-            $classnames = array_keys($this->_payment_method_types);
238
-            $payment_methods = array();
239
-            foreach ($classnames as $classname) {
240
-                $payment_methods[] = $this->payment_method_class_from_type($classname);
241
-            }
242
-            return $payment_methods;
243
-        }
244
-        return array_keys($this->_payment_method_types);
245
-    }
246
-
247
-
248
-
249
-    /**
250
-     * Gets an object of each payment method type, none of which are bound to a
251
-     * payment method instance
252
-     *
253
-     * @param boolean $force_recheck whether to force re-checking for new payment method types
254
-     * @return EE_PMT_Base[]
255
-     */
256
-    public function payment_method_types($force_recheck = false)
257
-    {
258
-        if ($force_recheck || empty($this->payment_method_objects)) {
259
-            $this->maybe_register_payment_methods($force_recheck);
260
-            foreach ($this->payment_method_type_names(true) as $classname) {
261
-                if (! isset($this->payment_method_objects[$classname])) {
262
-                    $this->payment_method_objects[$classname] = new $classname;
263
-                }
264
-            }
265
-        }
266
-        return $this->payment_method_objects;
267
-    }
268
-
269
-
270
-
271
-    /**
272
-     * Changes the payment method's class name into the payment method type's name
273
-     * (as used on the payment method's table's PMD_type field)
274
-     *
275
-     * @param string $classname
276
-     * @return string
277
-     */
278
-    public function payment_method_type_sans_class_prefix($classname)
279
-    {
280
-        return str_replace('EE_PMT_', '', $classname);
281
-    }
282
-
283
-
284
-
285
-    /**
286
-     * Does the opposite of payment-method_type_sans_prefix
287
-     *
288
-     * @param string $type
289
-     * @return string
290
-     */
291
-    public function payment_method_class_from_type($type)
292
-    {
293
-        return 'EE_PMT_' . $type;
294
-    }
295
-
296
-
297
-
298
-    /**
299
-     * Activates a payment method of the given type.
300
-     *
301
-     * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice'
302
-     * @return EE_Payment_Method
303
-     * @throws EE_Error
304
-     */
305
-    public function activate_a_payment_method_of_type($payment_method_type)
306
-    {
307
-        $this->maybe_register_payment_methods();
308
-        $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
309
-        if (! $payment_method instanceof EE_Payment_Method) {
310
-            $pm_type_class = $this->payment_method_class_from_type($payment_method_type);
311
-            if (class_exists($pm_type_class)) {
312
-                /** @var $pm_type_obj EE_PMT_Base */
313
-                $pm_type_obj = new $pm_type_class;
314
-                $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
315
-                if (! $payment_method) {
316
-                    $payment_method = $this->create_payment_method_of_type($pm_type_obj);
317
-                }
318
-                $payment_method->set_type($payment_method_type);
319
-                $this->initialize_payment_method($payment_method);
320
-            } else {
321
-                throw new EE_Error(
322
-                    sprintf(
323
-                        esc_html__(
324
-                            'There is no payment method of type %1$s, so it could not be activated',
325
-                            'event_espresso'
326
-                        ),
327
-                        $pm_type_class
328
-                    )
329
-                );
330
-            }
331
-        }
332
-        $payment_method->set_active();
333
-        $payment_method->save();
334
-        if ($payment_method->type() === 'Invoice') {
335
-            /** @type EE_Message_Resource_Manager $message_resource_manager */
336
-            $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
337
-            $message_resource_manager->ensure_message_type_is_active('invoice', 'html');
338
-            $message_resource_manager->ensure_messenger_is_active('pdf');
339
-            EE_Error::add_persistent_admin_notice(
340
-                'invoice_pm_requirements_notice',
341
-                sprintf(
342
-                    esc_html__(
343
-                        'The Invoice payment method has been activated. It requires the invoice message type, html messenger, and pdf messenger be activated as well for the %1$smessages system%2$s, so it has been automatically verified that they are also active.',
344
-                        'event_espresso'
345
-                    ),
346
-                    '<a href="' . admin_url('admin.php?page=espresso_messages') . '">',
347
-                    '</a>'
348
-                ),
349
-                true
350
-            );
351
-        }
352
-        return $payment_method;
353
-    }
354
-
355
-
356
-
357
-    /**
358
-     * Creates a payment method of the specified type. Does not save it.
359
-     *
360
-     * @global WP_User    $current_user
361
-     * @param EE_PMT_Base $pm_type_obj
362
-     * @return EE_Payment_Method
363
-     * @throws EE_Error
364
-     */
365
-    public function create_payment_method_of_type($pm_type_obj)
366
-    {
367
-        global $current_user;
368
-        $payment_method = EE_Payment_Method::new_instance(
369
-            array(
370
-                'PMD_type'       => $pm_type_obj->system_name(),
371
-                'PMD_name'       => $pm_type_obj->pretty_name(),
372
-                'PMD_admin_name' => $pm_type_obj->pretty_name(),
373
-                'PMD_slug'       => $pm_type_obj->system_name(),//automatically converted to slug
374
-                'PMD_wp_user'    => $current_user->ID,
375
-                'PMD_order'      => EEM_Payment_Method::instance()->count(
376
-                        array(array('PMD_type' => array('!=', 'Admin_Only')))
377
-                    ) * 10,
378
-            )
379
-        );
380
-        return $payment_method;
381
-    }
382
-
383
-
384
-
385
-    /**
386
-     * Sets the initial payment method properties (including extra meta)
387
-     *
388
-     * @param EE_Payment_Method $payment_method
389
-     * @return EE_Payment_Method
390
-     * @throws EE_Error
391
-     */
392
-    public function initialize_payment_method($payment_method)
393
-    {
394
-        $pm_type_obj = $payment_method->type_obj();
395
-        $payment_method->set_description($pm_type_obj->default_description());
396
-        if (! $payment_method->button_url()) {
397
-            $payment_method->set_button_url($pm_type_obj->default_button_url());
398
-        }
399
-        //now add setup its default extra meta properties
400
-        $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
401
-        if (! empty($extra_metas)) {
402
-            //verify the payment method has an ID before adding extra meta
403
-            if (! $payment_method->ID()) {
404
-                $payment_method->save();
405
-            }
406
-            foreach ($extra_metas as $meta_name => $input) {
407
-                $payment_method->update_extra_meta($meta_name, $input->raw_value());
408
-            }
409
-        }
410
-        return $payment_method;
411
-    }
412
-
413
-
414
-
415
-    /**
416
-     * Makes sure the payment method is related to the specified payment method
417
-     *
418
-     * @deprecated in 4.9.40 because the currency payment method table is being deprecated
419
-     * @param EE_Payment_Method $payment_method
420
-     * @return EE_Payment_Method
421
-     * @throws EE_Error
422
-     */
423
-    public function set_usable_currencies_on_payment_method($payment_method)
424
-    {
425
-        EE_Error::doing_it_wrong(
426
-            'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method',
427
-            esc_html__(
428
-                'We no longer define what currencies are usable by payment methods. Its not used nor efficient.',
429
-                'event_espresso'
430
-            ),
431
-            '4.9.40'
432
-        );
433
-        return $payment_method;
434
-    }
435
-
436
-
437
-
438
-    /**
439
-     * Deactivates a payment method of the given payment method slug.
440
-     *
441
-     * @param string $payment_method_slug The slug for the payment method to deactivate.
442
-     * @return int count of rows updated.
443
-     * @throws EE_Error
444
-     */
445
-    public function deactivate_payment_method($payment_method_slug)
446
-    {
447
-        EE_Log::instance()->log(
448
-            __FILE__,
449
-            __FUNCTION__,
450
-            sprintf(
451
-                esc_html__(
452
-                    'Payment method with slug %1$s is being deactivated by site admin',
453
-                    'event_espresso'
454
-                ),
455
-                $payment_method_slug
456
-            ),
457
-            'payment_method_change'
458
-        );
459
-        $count_updated = EEM_Payment_Method::instance()->update(
460
-            array('PMD_scope' => array()),
461
-            array(array('PMD_slug' => $payment_method_slug))
462
-        );
463
-        return $count_updated;
464
-    }
465
-
466
-
467
-
468
-    /**
469
-     * initializes payment method access caps via EE_Capabilities::init_role_caps()
470
-     * upon EE_Payment_Method_Manager construction
471
-     *
472
-     * @throws EE_Error
473
-     * @throws DomainException
474
-     */
475
-    protected function initializePaymentMethodCaps()
476
-    {
477
-        // don't do this twice
478
-        if ($this->payment_method_caps_initialized) {
479
-            return;
480
-        }
481
-        EE_Capabilities::instance()->addCaps(
482
-            $this->getPaymentMethodCaps()
483
-        );
484
-        $this->payment_method_caps_initialized = true;
485
-    }
486
-
487
-
488
-
489
-    /**
490
-     * array  of dynamic payment method access caps.
491
-     * at the time of writing, october 20 2014, these are the caps added:
492
-     *  ee_payment_method_admin_only
493
-     *  ee_payment_method_aim
494
-     *  ee_payment_method_bank
495
-     *  ee_payment_method_check
496
-     *  ee_payment_method_invoice
497
-     *  ee_payment_method_mijireh
498
-     *  ee_payment_method_paypal_pro
499
-     *  ee_payment_method_paypal_standard
500
-     * Any other payment methods added to core or via addons will also get
501
-     * their related capability automatically added too, so long as they are
502
-     * registered properly using EE_Register_Payment_Method::register()
503
-     *
504
-     * @return array
505
-     * @throws DomainException
506
-     */
507
-    protected function getPaymentMethodCaps()
508
-    {
509
-        $caps = array();
510
-        foreach ($this->payment_method_type_names() as $payment_method_name) {
511
-            $caps = $this->addPaymentMethodCap($payment_method_name,$caps);
512
-        }
513
-        return $caps;
514
-    }
515
-
516
-
517
-
518
-    /**
519
-     * @param string $payment_method_name
520
-     * @param array  $payment_method_caps
521
-     * @param string $role
522
-     * @return array
523
-     * @throws DomainException
524
-     */
525
-    public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator')
526
-    {
527
-        if (empty($payment_method_name)) {
528
-            throw new DomainException(
529
-                esc_html__(
530
-                    'The name of a payment method must be specified to add capabilities.',
531
-                    'event_espresso'
532
-                )
533
-            );
534
-        }
535
-        if (empty($role)) {
536
-            throw new DomainException(
537
-                sprintf(
538
-                    esc_html__(
539
-                        'No role was supplied while trying to add capabilities for the %1$s payment method.',
540
-                        'event_espresso'
541
-                    ),
542
-                    $payment_method_name
543
-                )
544
-            );
545
-        }
546
-        if(! isset($payment_method_caps[$role])) {
547
-            $payment_method_caps[$role] = array();
548
-        }
549
-        $payment_method_caps[$role][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
550
-                                                  . strtolower($payment_method_name);
551
-        return $payment_method_caps;
552
-    }
553
-
554
-
555
-
556
-    /**
557
-     * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter
558
-     * to add dynamic payment method access caps when capabilities are reset
559
-     * (or if that filter is called and PM caps are not already set)
560
-     *
561
-     * @param array $caps capabilities being filtered
562
-     * @param bool  $reset
563
-     * @return array
564
-     * @throws DomainException
565
-     */
566
-    public function addPaymentMethodCapsDuringReset(array $caps, $reset = false)
567
-    {
568
-        if ($reset || ! $this->payment_method_caps_initialized) {
569
-            $this->payment_method_caps_initialized = true;
570
-            $caps = array_merge_recursive($caps, $this->getPaymentMethodCaps());
571
-        }
572
-        return $caps;
573
-    }
574
-
575
-
576
-
577
-    /**
578
-     * @deprecated 4.9.42
579
-     * @param $caps
580
-     * @return mixed
581
-     */
582
-    public function add_payment_method_caps($caps)
583
-    {
584
-        return $caps;
585
-    }
22
+	/**
23
+	 * prefix added to all payment method capabilities names
24
+	 */
25
+	const   CAPABILITIES_PREFIX= 'ee_payment_method_';
26
+
27
+	/**
28
+	 * @var EE_Payment_Method_Manager $_instance
29
+	 */
30
+	private static $_instance;
31
+
32
+	/**
33
+	 * @var boolean
34
+	 */
35
+	protected $payment_method_caps_initialized = false;
36
+
37
+	/**
38
+	 * @var array keys are class names without 'EE_PMT_', values are their filepaths
39
+	 */
40
+	protected $_payment_method_types = array();
41
+
42
+	/**
43
+	 * @var EE_PMT_Base[]
44
+	 */
45
+	protected $payment_method_objects = array();
46
+
47
+
48
+
49
+	/**
50
+	 * EE_Payment_Method_Manager constructor.
51
+	 *
52
+	 * @throws EE_Error
53
+	 * @throws DomainException
54
+	 */
55
+	public function __construct()
56
+	{
57
+		// if in admin lets ensure caps are set.
58
+		if (is_admin()) {
59
+			$this->_register_payment_methods();
60
+			// set them immediately
61
+			$this->initializePaymentMethodCaps();
62
+			// plus any time they get reset
63
+			add_filter(
64
+				'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
65
+				array($this, 'addPaymentMethodCapsDuringReset')
66
+			);
67
+		}
68
+	}
69
+
70
+
71
+
72
+	/**
73
+	 * @singleton method used to instantiate class object
74
+	 * @return EE_Payment_Method_Manager instance
75
+	 * @throws DomainException
76
+	 * @throws EE_Error
77
+	 */
78
+	public static function instance()
79
+	{
80
+		// check if class object is instantiated, and instantiated properly
81
+		if (! self::$_instance instanceof EE_Payment_Method_Manager) {
82
+			EE_Registry::instance()->load_lib('PMT_Base');
83
+			self::$_instance = new self();
84
+		}
85
+		return self::$_instance;
86
+	}
87
+
88
+
89
+
90
+	/**
91
+	 * Resets the instance and returns a new one
92
+	 *
93
+	 * @return EE_Payment_Method_Manager
94
+	 * @throws DomainException
95
+	 * @throws EE_Error
96
+	 */
97
+	public static function reset()
98
+	{
99
+		self::$_instance = null;
100
+		return self::instance();
101
+	}
102
+
103
+
104
+
105
+	/**
106
+	 * If necessary, re-register payment methods
107
+	 *
108
+	 * @param boolean $force_recheck whether to recheck for payment method types,
109
+	 *                               or just re-use the PMTs we found last time we checked during this request (if
110
+	 *                               we have not yet checked during this request, then we need to check anyways)
111
+	 */
112
+	public function maybe_register_payment_methods($force_recheck = false)
113
+	{
114
+		if (! $this->_payment_method_types || $force_recheck) {
115
+			$this->_register_payment_methods();
116
+		}
117
+	}
118
+
119
+
120
+
121
+	/**
122
+	 * register_payment_methods
123
+	 *
124
+	 * @return array
125
+	 */
126
+	protected function _register_payment_methods()
127
+	{
128
+		// grab list of installed modules
129
+		$pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
130
+		// filter list of modules to register
131
+		$pm_to_register = apply_filters(
132
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
133
+			$pm_to_register
134
+		);
135
+		// remove any duplicates if that should happen for some reason
136
+		$pm_to_register = array_unique($pm_to_register);
137
+		// loop through folders
138
+		foreach ($pm_to_register as $pm_path) {
139
+			$this->register_payment_method($pm_path);
140
+		}
141
+		do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods');
142
+		// filter list of installed modules
143
+		//keep them organized alphabetically by the payment method type's name
144
+		ksort($this->_payment_method_types);
145
+		return apply_filters(
146
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods',
147
+			$this->_payment_method_types
148
+		);
149
+	}
150
+
151
+
152
+
153
+	/**
154
+	 * register_payment_method- makes core aware of this payment method
155
+	 *
156
+	 * @param string $payment_method_path - full path up to and including payment method folder
157
+	 * @return boolean
158
+	 */
159
+	public function register_payment_method($payment_method_path = '')
160
+	{
161
+		do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path);
162
+		$module_ext = '.pm.php';
163
+		// make all separators match
164
+		$payment_method_path = rtrim(str_replace('/\\', DS, $payment_method_path), DS);
165
+		// grab and sanitize module name
166
+		$module_dir = basename($payment_method_path);
167
+		// create class name from module directory name
168
+		$module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
169
+		// add class prefix
170
+		$module_class = 'EE_PMT_' . $module;
171
+		// does the module exist ?
172
+		if (! is_readable($payment_method_path . DS . $module_class . $module_ext)) {
173
+			$msg = sprintf(
174
+				esc_html__(
175
+					'The requested %s payment method file could not be found or is not readable due to file permissions.',
176
+					'event_espresso'
177
+				), $module
178
+			);
179
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
180
+			return false;
181
+		}
182
+		// load the module class file
183
+		require_once($payment_method_path . DS . $module_class . $module_ext);
184
+		// verify that class exists
185
+		if (! class_exists($module_class)) {
186
+			$msg = sprintf(
187
+				esc_html__('The requested %s module class does not exist.', 'event_espresso'),
188
+				$module_class
189
+			);
190
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
191
+			return false;
192
+		}
193
+		// add to array of registered modules
194
+		$this->_payment_method_types[$module] = $payment_method_path . DS . $module_class . $module_ext;
195
+		return true;
196
+	}
197
+
198
+
199
+
200
+	/**
201
+	 * Checks if a payment method has been registered, and if so includes it
202
+	 *
203
+	 * @param string  $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_')
204
+	 * @param boolean $force_recheck       whether to force re-checking for new payment method types
205
+	 * @return boolean
206
+	 */
207
+	public function payment_method_type_exists($payment_method_name, $force_recheck = false)
208
+	{
209
+		if (
210
+			$force_recheck
211
+			|| ! is_array($this->_payment_method_types)
212
+			|| ! isset($this->_payment_method_types[$payment_method_name])
213
+		) {
214
+			$this->maybe_register_payment_methods($force_recheck);
215
+		}
216
+		if (isset($this->_payment_method_types[$payment_method_name])) {
217
+			require_once($this->_payment_method_types[$payment_method_name]);
218
+			return true;
219
+		}
220
+		return false;
221
+	}
222
+
223
+
224
+
225
+	/**
226
+	 * Returns all the class names of the various payment method types
227
+	 *
228
+	 * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names'
229
+	 *                               (what you'd find in wp_esp_payment_method.PMD_type)
230
+	 * @param boolean $force_recheck whether to force re-checking for new payment method types
231
+	 * @return array
232
+	 */
233
+	public function payment_method_type_names($with_prefixes = false, $force_recheck = false)
234
+	{
235
+		$this->maybe_register_payment_methods($force_recheck);
236
+		if ($with_prefixes) {
237
+			$classnames = array_keys($this->_payment_method_types);
238
+			$payment_methods = array();
239
+			foreach ($classnames as $classname) {
240
+				$payment_methods[] = $this->payment_method_class_from_type($classname);
241
+			}
242
+			return $payment_methods;
243
+		}
244
+		return array_keys($this->_payment_method_types);
245
+	}
246
+
247
+
248
+
249
+	/**
250
+	 * Gets an object of each payment method type, none of which are bound to a
251
+	 * payment method instance
252
+	 *
253
+	 * @param boolean $force_recheck whether to force re-checking for new payment method types
254
+	 * @return EE_PMT_Base[]
255
+	 */
256
+	public function payment_method_types($force_recheck = false)
257
+	{
258
+		if ($force_recheck || empty($this->payment_method_objects)) {
259
+			$this->maybe_register_payment_methods($force_recheck);
260
+			foreach ($this->payment_method_type_names(true) as $classname) {
261
+				if (! isset($this->payment_method_objects[$classname])) {
262
+					$this->payment_method_objects[$classname] = new $classname;
263
+				}
264
+			}
265
+		}
266
+		return $this->payment_method_objects;
267
+	}
268
+
269
+
270
+
271
+	/**
272
+	 * Changes the payment method's class name into the payment method type's name
273
+	 * (as used on the payment method's table's PMD_type field)
274
+	 *
275
+	 * @param string $classname
276
+	 * @return string
277
+	 */
278
+	public function payment_method_type_sans_class_prefix($classname)
279
+	{
280
+		return str_replace('EE_PMT_', '', $classname);
281
+	}
282
+
283
+
284
+
285
+	/**
286
+	 * Does the opposite of payment-method_type_sans_prefix
287
+	 *
288
+	 * @param string $type
289
+	 * @return string
290
+	 */
291
+	public function payment_method_class_from_type($type)
292
+	{
293
+		return 'EE_PMT_' . $type;
294
+	}
295
+
296
+
297
+
298
+	/**
299
+	 * Activates a payment method of the given type.
300
+	 *
301
+	 * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice'
302
+	 * @return EE_Payment_Method
303
+	 * @throws EE_Error
304
+	 */
305
+	public function activate_a_payment_method_of_type($payment_method_type)
306
+	{
307
+		$this->maybe_register_payment_methods();
308
+		$payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
309
+		if (! $payment_method instanceof EE_Payment_Method) {
310
+			$pm_type_class = $this->payment_method_class_from_type($payment_method_type);
311
+			if (class_exists($pm_type_class)) {
312
+				/** @var $pm_type_obj EE_PMT_Base */
313
+				$pm_type_obj = new $pm_type_class;
314
+				$payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
315
+				if (! $payment_method) {
316
+					$payment_method = $this->create_payment_method_of_type($pm_type_obj);
317
+				}
318
+				$payment_method->set_type($payment_method_type);
319
+				$this->initialize_payment_method($payment_method);
320
+			} else {
321
+				throw new EE_Error(
322
+					sprintf(
323
+						esc_html__(
324
+							'There is no payment method of type %1$s, so it could not be activated',
325
+							'event_espresso'
326
+						),
327
+						$pm_type_class
328
+					)
329
+				);
330
+			}
331
+		}
332
+		$payment_method->set_active();
333
+		$payment_method->save();
334
+		if ($payment_method->type() === 'Invoice') {
335
+			/** @type EE_Message_Resource_Manager $message_resource_manager */
336
+			$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
337
+			$message_resource_manager->ensure_message_type_is_active('invoice', 'html');
338
+			$message_resource_manager->ensure_messenger_is_active('pdf');
339
+			EE_Error::add_persistent_admin_notice(
340
+				'invoice_pm_requirements_notice',
341
+				sprintf(
342
+					esc_html__(
343
+						'The Invoice payment method has been activated. It requires the invoice message type, html messenger, and pdf messenger be activated as well for the %1$smessages system%2$s, so it has been automatically verified that they are also active.',
344
+						'event_espresso'
345
+					),
346
+					'<a href="' . admin_url('admin.php?page=espresso_messages') . '">',
347
+					'</a>'
348
+				),
349
+				true
350
+			);
351
+		}
352
+		return $payment_method;
353
+	}
354
+
355
+
356
+
357
+	/**
358
+	 * Creates a payment method of the specified type. Does not save it.
359
+	 *
360
+	 * @global WP_User    $current_user
361
+	 * @param EE_PMT_Base $pm_type_obj
362
+	 * @return EE_Payment_Method
363
+	 * @throws EE_Error
364
+	 */
365
+	public function create_payment_method_of_type($pm_type_obj)
366
+	{
367
+		global $current_user;
368
+		$payment_method = EE_Payment_Method::new_instance(
369
+			array(
370
+				'PMD_type'       => $pm_type_obj->system_name(),
371
+				'PMD_name'       => $pm_type_obj->pretty_name(),
372
+				'PMD_admin_name' => $pm_type_obj->pretty_name(),
373
+				'PMD_slug'       => $pm_type_obj->system_name(),//automatically converted to slug
374
+				'PMD_wp_user'    => $current_user->ID,
375
+				'PMD_order'      => EEM_Payment_Method::instance()->count(
376
+						array(array('PMD_type' => array('!=', 'Admin_Only')))
377
+					) * 10,
378
+			)
379
+		);
380
+		return $payment_method;
381
+	}
382
+
383
+
384
+
385
+	/**
386
+	 * Sets the initial payment method properties (including extra meta)
387
+	 *
388
+	 * @param EE_Payment_Method $payment_method
389
+	 * @return EE_Payment_Method
390
+	 * @throws EE_Error
391
+	 */
392
+	public function initialize_payment_method($payment_method)
393
+	{
394
+		$pm_type_obj = $payment_method->type_obj();
395
+		$payment_method->set_description($pm_type_obj->default_description());
396
+		if (! $payment_method->button_url()) {
397
+			$payment_method->set_button_url($pm_type_obj->default_button_url());
398
+		}
399
+		//now add setup its default extra meta properties
400
+		$extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
401
+		if (! empty($extra_metas)) {
402
+			//verify the payment method has an ID before adding extra meta
403
+			if (! $payment_method->ID()) {
404
+				$payment_method->save();
405
+			}
406
+			foreach ($extra_metas as $meta_name => $input) {
407
+				$payment_method->update_extra_meta($meta_name, $input->raw_value());
408
+			}
409
+		}
410
+		return $payment_method;
411
+	}
412
+
413
+
414
+
415
+	/**
416
+	 * Makes sure the payment method is related to the specified payment method
417
+	 *
418
+	 * @deprecated in 4.9.40 because the currency payment method table is being deprecated
419
+	 * @param EE_Payment_Method $payment_method
420
+	 * @return EE_Payment_Method
421
+	 * @throws EE_Error
422
+	 */
423
+	public function set_usable_currencies_on_payment_method($payment_method)
424
+	{
425
+		EE_Error::doing_it_wrong(
426
+			'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method',
427
+			esc_html__(
428
+				'We no longer define what currencies are usable by payment methods. Its not used nor efficient.',
429
+				'event_espresso'
430
+			),
431
+			'4.9.40'
432
+		);
433
+		return $payment_method;
434
+	}
435
+
436
+
437
+
438
+	/**
439
+	 * Deactivates a payment method of the given payment method slug.
440
+	 *
441
+	 * @param string $payment_method_slug The slug for the payment method to deactivate.
442
+	 * @return int count of rows updated.
443
+	 * @throws EE_Error
444
+	 */
445
+	public function deactivate_payment_method($payment_method_slug)
446
+	{
447
+		EE_Log::instance()->log(
448
+			__FILE__,
449
+			__FUNCTION__,
450
+			sprintf(
451
+				esc_html__(
452
+					'Payment method with slug %1$s is being deactivated by site admin',
453
+					'event_espresso'
454
+				),
455
+				$payment_method_slug
456
+			),
457
+			'payment_method_change'
458
+		);
459
+		$count_updated = EEM_Payment_Method::instance()->update(
460
+			array('PMD_scope' => array()),
461
+			array(array('PMD_slug' => $payment_method_slug))
462
+		);
463
+		return $count_updated;
464
+	}
465
+
466
+
467
+
468
+	/**
469
+	 * initializes payment method access caps via EE_Capabilities::init_role_caps()
470
+	 * upon EE_Payment_Method_Manager construction
471
+	 *
472
+	 * @throws EE_Error
473
+	 * @throws DomainException
474
+	 */
475
+	protected function initializePaymentMethodCaps()
476
+	{
477
+		// don't do this twice
478
+		if ($this->payment_method_caps_initialized) {
479
+			return;
480
+		}
481
+		EE_Capabilities::instance()->addCaps(
482
+			$this->getPaymentMethodCaps()
483
+		);
484
+		$this->payment_method_caps_initialized = true;
485
+	}
486
+
487
+
488
+
489
+	/**
490
+	 * array  of dynamic payment method access caps.
491
+	 * at the time of writing, october 20 2014, these are the caps added:
492
+	 *  ee_payment_method_admin_only
493
+	 *  ee_payment_method_aim
494
+	 *  ee_payment_method_bank
495
+	 *  ee_payment_method_check
496
+	 *  ee_payment_method_invoice
497
+	 *  ee_payment_method_mijireh
498
+	 *  ee_payment_method_paypal_pro
499
+	 *  ee_payment_method_paypal_standard
500
+	 * Any other payment methods added to core or via addons will also get
501
+	 * their related capability automatically added too, so long as they are
502
+	 * registered properly using EE_Register_Payment_Method::register()
503
+	 *
504
+	 * @return array
505
+	 * @throws DomainException
506
+	 */
507
+	protected function getPaymentMethodCaps()
508
+	{
509
+		$caps = array();
510
+		foreach ($this->payment_method_type_names() as $payment_method_name) {
511
+			$caps = $this->addPaymentMethodCap($payment_method_name,$caps);
512
+		}
513
+		return $caps;
514
+	}
515
+
516
+
517
+
518
+	/**
519
+	 * @param string $payment_method_name
520
+	 * @param array  $payment_method_caps
521
+	 * @param string $role
522
+	 * @return array
523
+	 * @throws DomainException
524
+	 */
525
+	public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator')
526
+	{
527
+		if (empty($payment_method_name)) {
528
+			throw new DomainException(
529
+				esc_html__(
530
+					'The name of a payment method must be specified to add capabilities.',
531
+					'event_espresso'
532
+				)
533
+			);
534
+		}
535
+		if (empty($role)) {
536
+			throw new DomainException(
537
+				sprintf(
538
+					esc_html__(
539
+						'No role was supplied while trying to add capabilities for the %1$s payment method.',
540
+						'event_espresso'
541
+					),
542
+					$payment_method_name
543
+				)
544
+			);
545
+		}
546
+		if(! isset($payment_method_caps[$role])) {
547
+			$payment_method_caps[$role] = array();
548
+		}
549
+		$payment_method_caps[$role][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
550
+												  . strtolower($payment_method_name);
551
+		return $payment_method_caps;
552
+	}
553
+
554
+
555
+
556
+	/**
557
+	 * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter
558
+	 * to add dynamic payment method access caps when capabilities are reset
559
+	 * (or if that filter is called and PM caps are not already set)
560
+	 *
561
+	 * @param array $caps capabilities being filtered
562
+	 * @param bool  $reset
563
+	 * @return array
564
+	 * @throws DomainException
565
+	 */
566
+	public function addPaymentMethodCapsDuringReset(array $caps, $reset = false)
567
+	{
568
+		if ($reset || ! $this->payment_method_caps_initialized) {
569
+			$this->payment_method_caps_initialized = true;
570
+			$caps = array_merge_recursive($caps, $this->getPaymentMethodCaps());
571
+		}
572
+		return $caps;
573
+	}
574
+
575
+
576
+
577
+	/**
578
+	 * @deprecated 4.9.42
579
+	 * @param $caps
580
+	 * @return mixed
581
+	 */
582
+	public function add_payment_method_caps($caps)
583
+	{
584
+		return $caps;
585
+	}
586 586
 
587 587
 
588 588
 
Please login to merge, or discard this patch.
core/EE_Deprecated.core.php 2 patches
Indentation   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
 		);
1048 1048
 		do_action(
1049 1049
 			'AHEE__EE_Capabilities__init_role_caps__complete',
1050
-            $capabilities_map
1050
+			$capabilities_map
1051 1051
 		);
1052 1052
 	}
1053 1053
 );
@@ -1067,9 +1067,9 @@  discard block
 block discarded – undo
1067 1067
 			'filter'
1068 1068
 		);
1069 1069
 		return apply_filters(
1070
-            'FHEE_EE_Single_Page_Checkout__save_registration_items__find_existing_attendee',
1071
-            $existing_attendee, $registration, $attendee_data
1072
-        );
1070
+			'FHEE_EE_Single_Page_Checkout__save_registration_items__find_existing_attendee',
1071
+			$existing_attendee, $registration, $attendee_data
1072
+		);
1073 1073
 	},
1074 1074
 	10,3
1075 1075
 );
@@ -1082,88 +1082,88 @@  discard block
 block discarded – undo
1082 1082
 class EE_Event_List_Query extends WP_Query
1083 1083
 {
1084 1084
 
1085
-    private $title;
1086
-
1087
-    private $css_class;
1088
-
1089
-    private $category_slug;
1090
-
1091
-    /**
1092
-     * EE_Event_List_Query constructor.
1093
-     *
1094
-     * @param array $args
1095
-     */
1096
-    public function __construct($args = array())
1097
-    {
1098
-        \EE_Error::doing_it_wrong(
1099
-            __METHOD__,
1100
-            __(
1101
-                'Usage is deprecated. Please use \EventEspresso\core\domain\services\wp_queries\EventListQuery instead.',
1102
-                'event_espresso'
1103
-            ),
1104
-            '4.9.27',
1105
-            '5.0.0'
1106
-        );
1107
-        $this->title = isset($args['title']) ? $args['title'] : '';
1108
-        $this->css_class = isset($args['css_class']) ? $args['css_class'] : '';
1109
-        $this->category_slug = isset($args['category_slug']) ? $args['category_slug'] : '';
1110
-        $limit = isset($args['limit']) && absint($args['limit']) ? $args['limit'] : 10;
1111
-        // the current "page" we are viewing
1112
-        $paged = max(1, get_query_var('paged'));
1113
-        // Force these args
1114
-        $args = array_merge(
1115
-            $args, array(
1116
-            'post_type'              => 'espresso_events',
1117
-            'posts_per_page'         => $limit,
1118
-            'update_post_term_cache' => false,
1119
-            'update_post_meta_cache' => false,
1120
-            'paged'                  => $paged,
1121
-            'offset'                 => ($paged - 1) * $limit
1122
-        )
1123
-        );
1124
-        // run the query
1125
-        parent::__construct($args);
1126
-    }
1127
-
1128
-
1129
-
1130
-    /**
1131
-     * event_list_title
1132
-     *
1133
-     * @param string $event_list_title
1134
-     * @return string
1135
-     */
1136
-    public function event_list_title($event_list_title = '')
1137
-    {
1138
-        if (! empty($this->title)) {
1139
-            return $this->title;
1140
-        }
1141
-        return $event_list_title;
1142
-    }
1143
-
1144
-
1145
-
1146
-    /**
1147
-     * event_list_css
1148
-     *
1149
-     * @param string $event_list_css
1150
-     * @return string
1151
-     */
1152
-    public function event_list_css($event_list_css = '')
1153
-    {
1154
-        $event_list_css .= ! empty($event_list_css)
1155
-            ? ' '
1156
-            : '';
1157
-        $event_list_css .= ! empty($this->css_class)
1158
-            ? $this->css_class
1159
-            : '';
1160
-        $event_list_css .= ! empty($event_list_css)
1161
-            ? ' '
1162
-            : '';
1163
-        $event_list_css .= ! empty($this->category_slug)
1164
-            ? $this->category_slug
1165
-            : '';
1166
-        return $event_list_css;
1167
-    }
1085
+	private $title;
1086
+
1087
+	private $css_class;
1088
+
1089
+	private $category_slug;
1090
+
1091
+	/**
1092
+	 * EE_Event_List_Query constructor.
1093
+	 *
1094
+	 * @param array $args
1095
+	 */
1096
+	public function __construct($args = array())
1097
+	{
1098
+		\EE_Error::doing_it_wrong(
1099
+			__METHOD__,
1100
+			__(
1101
+				'Usage is deprecated. Please use \EventEspresso\core\domain\services\wp_queries\EventListQuery instead.',
1102
+				'event_espresso'
1103
+			),
1104
+			'4.9.27',
1105
+			'5.0.0'
1106
+		);
1107
+		$this->title = isset($args['title']) ? $args['title'] : '';
1108
+		$this->css_class = isset($args['css_class']) ? $args['css_class'] : '';
1109
+		$this->category_slug = isset($args['category_slug']) ? $args['category_slug'] : '';
1110
+		$limit = isset($args['limit']) && absint($args['limit']) ? $args['limit'] : 10;
1111
+		// the current "page" we are viewing
1112
+		$paged = max(1, get_query_var('paged'));
1113
+		// Force these args
1114
+		$args = array_merge(
1115
+			$args, array(
1116
+			'post_type'              => 'espresso_events',
1117
+			'posts_per_page'         => $limit,
1118
+			'update_post_term_cache' => false,
1119
+			'update_post_meta_cache' => false,
1120
+			'paged'                  => $paged,
1121
+			'offset'                 => ($paged - 1) * $limit
1122
+		)
1123
+		);
1124
+		// run the query
1125
+		parent::__construct($args);
1126
+	}
1127
+
1128
+
1129
+
1130
+	/**
1131
+	 * event_list_title
1132
+	 *
1133
+	 * @param string $event_list_title
1134
+	 * @return string
1135
+	 */
1136
+	public function event_list_title($event_list_title = '')
1137
+	{
1138
+		if (! empty($this->title)) {
1139
+			return $this->title;
1140
+		}
1141
+		return $event_list_title;
1142
+	}
1143
+
1144
+
1145
+
1146
+	/**
1147
+	 * event_list_css
1148
+	 *
1149
+	 * @param string $event_list_css
1150
+	 * @return string
1151
+	 */
1152
+	public function event_list_css($event_list_css = '')
1153
+	{
1154
+		$event_list_css .= ! empty($event_list_css)
1155
+			? ' '
1156
+			: '';
1157
+		$event_list_css .= ! empty($this->css_class)
1158
+			? $this->css_class
1159
+			: '';
1160
+		$event_list_css .= ! empty($event_list_css)
1161
+			? ' '
1162
+			: '';
1163
+		$event_list_css .= ! empty($this->category_slug)
1164
+			? $this->category_slug
1165
+			: '';
1166
+		return $event_list_css;
1167
+	}
1168 1168
 
1169 1169
 }
Please login to merge, or discard this patch.
Spacing   +178 added lines, -178 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
3
-	exit( 'No direct script access allowed' );
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3
+	exit('No direct script access allowed');
4 4
 }
5 5
 /**
6 6
  * ************************************************************************
@@ -43,8 +43,8 @@  discard block
 block discarded – undo
43 43
 	$action_or_filter = 'action'
44 44
 ) {
45 45
 	$action_or_filter = $action_or_filter === 'action'
46
-		? esc_html__( 'action', 'event_espresso' )
47
-		: esc_html__( 'filter', 'event_espresso' );
46
+		? esc_html__('action', 'event_espresso')
47
+		: esc_html__('filter', 'event_espresso');
48 48
 	EE_Error::doing_it_wrong(
49 49
 		$deprecated_filter,
50 50
 		sprintf(
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
  * @param \EE_Checkout $checkout
69 69
  * @return string
70 70
  */
71
-function ee_deprecated__registration_checkout__button_text( $submit_button_text, EE_Checkout $checkout ) {
71
+function ee_deprecated__registration_checkout__button_text($submit_button_text, EE_Checkout $checkout) {
72 72
 	// list of old filters
73 73
 	$deprecated_filters = array(
74 74
 		'update_registration_details' => true,
@@ -78,16 +78,16 @@  discard block
 block discarded – undo
78 78
 		'proceed_to' => true,
79 79
 	);
80 80
 	// loop thru and call doing_it_wrong() or remove any that aren't being used
81
-	foreach ( $deprecated_filters as $deprecated_filter => $on ) {
81
+	foreach ($deprecated_filters as $deprecated_filter => $on) {
82 82
 		// was this filter called ?
83
-		if ( has_action( 'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__' . $deprecated_filter )) {
83
+		if (has_action('FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__'.$deprecated_filter)) {
84 84
 			// only display doing_it_wrong() notice to Event Admins during non-AJAX requests
85
-			if ( EE_Registry::instance()->CAP->current_user_can( 'ee_read_ee', 'hide_doing_it_wrong_for_deprecated_SPCO_filter' ) && ! defined( 'DOING_AJAX' ) ) {
85
+			if (EE_Registry::instance()->CAP->current_user_can('ee_read_ee', 'hide_doing_it_wrong_for_deprecated_SPCO_filter') && ! defined('DOING_AJAX')) {
86 86
 				EE_Error::doing_it_wrong(
87
-					'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__' . $deprecated_filter,
87
+					'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__'.$deprecated_filter,
88 88
 					sprintf(
89
-						__( 'The %1$s filter is deprecated.  It *may* work as an attempt to build in backwards compatibility.  However, it is recommended to use the following new filter: %2$s"%3$s" found in "%4$s"', 'event_espresso' ),
90
-						'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__' . $deprecated_filter,
89
+						__('The %1$s filter is deprecated.  It *may* work as an attempt to build in backwards compatibility.  However, it is recommended to use the following new filter: %2$s"%3$s" found in "%4$s"', 'event_espresso'),
90
+						'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__'.$deprecated_filter,
91 91
 						'<br />',
92 92
 						'FHEE__EE_SPCO_Reg_Step__set_submit_button_text___submit_button_text',
93 93
 						'/modules/single_page_checkout/inc/EE_SPCO_Reg_Step.class.php'
@@ -96,24 +96,24 @@  discard block
 block discarded – undo
96 96
 				);
97 97
 			}
98 98
 		} else {
99
-			unset( $deprecated_filters[ $deprecated_filter ] );
99
+			unset($deprecated_filters[$deprecated_filter]);
100 100
 		}
101 101
 	}
102
-	if ( ! empty( $deprecated_filters )) {
103
-
104
-		if ( $checkout->current_step->slug() == 'attendee_information' && $checkout->revisit && isset( $deprecated_filters[ 'update_registration_details' ] )) {
105
-			$submit_button_text = apply_filters( 'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__update_registration_details', $submit_button_text );
106
-		} else if ( $checkout->current_step->slug() == 'payment_options' && $checkout->revisit && isset( $deprecated_filters[ 'process_payment' ] ) ) {
107
-			$submit_button_text = apply_filters( 'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__process_payment', $submit_button_text );
108
-		} else if ( $checkout->next_step instanceof EE_SPCO_Reg_Step && $checkout->next_step->slug() == 'finalize_registration' && isset( $deprecated_filters[ 'finalize_registration' ] ) ) {
109
-			$submit_button_text = apply_filters( 'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__finalize_registration', $submit_button_text );
102
+	if ( ! empty($deprecated_filters)) {
103
+
104
+		if ($checkout->current_step->slug() == 'attendee_information' && $checkout->revisit && isset($deprecated_filters['update_registration_details'])) {
105
+			$submit_button_text = apply_filters('FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__update_registration_details', $submit_button_text);
106
+		} else if ($checkout->current_step->slug() == 'payment_options' && $checkout->revisit && isset($deprecated_filters['process_payment'])) {
107
+			$submit_button_text = apply_filters('FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__process_payment', $submit_button_text);
108
+		} else if ($checkout->next_step instanceof EE_SPCO_Reg_Step && $checkout->next_step->slug() == 'finalize_registration' && isset($deprecated_filters['finalize_registration'])) {
109
+			$submit_button_text = apply_filters('FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__finalize_registration', $submit_button_text);
110 110
 		}
111
-		if ( $checkout->next_step instanceof EE_SPCO_Reg_Step ) {
112
-			if ( $checkout->payment_required() && $checkout->next_step->slug() == 'payment_options' && isset( $deprecated_filters[ 'and_proceed_to_payment' ] ) ) {
113
-				$submit_button_text .= apply_filters( 'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__and_proceed_to_payment', $submit_button_text );
111
+		if ($checkout->next_step instanceof EE_SPCO_Reg_Step) {
112
+			if ($checkout->payment_required() && $checkout->next_step->slug() == 'payment_options' && isset($deprecated_filters['and_proceed_to_payment'])) {
113
+				$submit_button_text .= apply_filters('FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__and_proceed_to_payment', $submit_button_text);
114 114
 			}
115
-			if ( $checkout->next_step->slug() != 'finalize_registration' && ! $checkout->revisit && isset( $deprecated_filters[ 'proceed_to' ] ) ) {
116
-				$submit_button_text = apply_filters( 'FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__proceed_to', $submit_button_text ) . $checkout->next_step->name();
115
+			if ($checkout->next_step->slug() != 'finalize_registration' && ! $checkout->revisit && isset($deprecated_filters['proceed_to'])) {
116
+				$submit_button_text = apply_filters('FHEE__EED_Single_Page_Checkout__registration_checkout__button_text__proceed_to', $submit_button_text).$checkout->next_step->name();
117 117
 			}
118 118
 		}
119 119
 
@@ -121,7 +121,7 @@  discard block
 block discarded – undo
121 121
 	return $submit_button_text;
122 122
 
123 123
 }
124
-add_filter( 'FHEE__EE_SPCO_Reg_Step__set_submit_button_text___submit_button_text', 'ee_deprecated__registration_checkout__button_text', 10, 2 );
124
+add_filter('FHEE__EE_SPCO_Reg_Step__set_submit_button_text___submit_button_text', 'ee_deprecated__registration_checkout__button_text', 10, 2);
125 125
 
126 126
 
127 127
 
@@ -132,16 +132,16 @@  discard block
 block discarded – undo
132 132
  * @param \EE_Checkout $checkout
133 133
  * @param boolean $status_updates
134 134
  */
135
-function ee_deprecated_finalize_transaction( EE_Checkout $checkout, $status_updates ) {
135
+function ee_deprecated_finalize_transaction(EE_Checkout $checkout, $status_updates) {
136 136
 	$action_ref = NULL;
137
-	$action_ref = has_action( 'AHEE__EE_Transaction__finalize__new_transaction' ) ? 'AHEE__EE_Transaction__finalize__new_transaction' : $action_ref;
138
-	$action_ref = has_action( 'AHEE__EE_Transaction__finalize__all_transaction' ) ? 'AHEE__EE_Transaction__finalize__all_transaction' : $action_ref;
139
-	if ( $action_ref ) {
137
+	$action_ref = has_action('AHEE__EE_Transaction__finalize__new_transaction') ? 'AHEE__EE_Transaction__finalize__new_transaction' : $action_ref;
138
+	$action_ref = has_action('AHEE__EE_Transaction__finalize__all_transaction') ? 'AHEE__EE_Transaction__finalize__all_transaction' : $action_ref;
139
+	if ($action_ref) {
140 140
 
141 141
 		EE_Error::doing_it_wrong(
142 142
 			$action_ref,
143 143
 			sprintf(
144
-				__( 'This action is deprecated.  It *may* work as an attempt to build in backwards compatibility.  However, it is recommended to use one of the following new actions: %1$s"%3$s" found in "%2$s" %1$s"%4$s" found in "%2$s" %1$s"%5$s" found in "%2$s" %1$s"%6$s" found in "%2$s"', 'event_espresso' ),
144
+				__('This action is deprecated.  It *may* work as an attempt to build in backwards compatibility.  However, it is recommended to use one of the following new actions: %1$s"%3$s" found in "%2$s" %1$s"%4$s" found in "%2$s" %1$s"%5$s" found in "%2$s" %1$s"%6$s" found in "%2$s"', 'event_espresso'),
145 145
 				'<br />',
146 146
 				'/core/business/EE_Transaction_Processor.class.php',
147 147
 				'AHEE__EE_Transaction_Processor__finalize',
@@ -151,39 +151,39 @@  discard block
 block discarded – undo
151 151
 			),
152 152
 			'4.6.0'
153 153
 		);
154
-		switch ( $action_ref ) {
154
+		switch ($action_ref) {
155 155
 			case 'AHEE__EE_Transaction__finalize__new_transaction' :
156
-				do_action( 'AHEE__EE_Transaction__finalize__new_transaction', $checkout->transaction, $checkout->admin_request );
156
+				do_action('AHEE__EE_Transaction__finalize__new_transaction', $checkout->transaction, $checkout->admin_request);
157 157
 				break;
158 158
 			case 'AHEE__EE_Transaction__finalize__all_transaction' :
159
-				do_action( 'AHEE__EE_Transaction__finalize__new_transaction', $checkout->transaction, array( 'new_reg' => ! $checkout->revisit, 'to_approved' => $status_updates ), $checkout->admin_request );
159
+				do_action('AHEE__EE_Transaction__finalize__new_transaction', $checkout->transaction, array('new_reg' => ! $checkout->revisit, 'to_approved' => $status_updates), $checkout->admin_request);
160 160
 				break;
161 161
 		}
162 162
 	}
163 163
 }
164
-add_action( 'AHEE__EE_SPCO_Reg_Step_Finalize_Registration__process_reg_step__completed', 'ee_deprecated_finalize_transaction', 10, 2 );
164
+add_action('AHEE__EE_SPCO_Reg_Step_Finalize_Registration__process_reg_step__completed', 'ee_deprecated_finalize_transaction', 10, 2);
165 165
 /**
166 166
  * ee_deprecated_finalize_registration
167 167
  *
168 168
  * @param EE_Registration $registration
169 169
  */
170
-function ee_deprecated_finalize_registration( EE_Registration $registration ) {
171
-	$action_ref = has_action( 'AHEE__EE_Registration__finalize__update_and_new_reg' ) ? 'AHEE__EE_Registration__finalize__update_and_new_reg' : NULL;
172
-	if ( $action_ref ) {
170
+function ee_deprecated_finalize_registration(EE_Registration $registration) {
171
+	$action_ref = has_action('AHEE__EE_Registration__finalize__update_and_new_reg') ? 'AHEE__EE_Registration__finalize__update_and_new_reg' : NULL;
172
+	if ($action_ref) {
173 173
 		EE_Error::doing_it_wrong(
174 174
 			$action_ref,
175 175
 			sprintf(
176
-				__( 'This action is deprecated.  It *may* work as an attempt to build in backwards compatibility.  However, it is recommended to use the following new action: %1$s"%3$s" found in "%2$s"', 'event_espresso' ),
176
+				__('This action is deprecated.  It *may* work as an attempt to build in backwards compatibility.  However, it is recommended to use the following new action: %1$s"%3$s" found in "%2$s"', 'event_espresso'),
177 177
 				'<br />',
178 178
 				'/core/business/EE_Registration_Processor.class.php',
179 179
 				'AHEE__EE_Registration_Processor__trigger_registration_status_changed_hook'
180 180
 			),
181 181
 			'4.6.0'
182 182
 		);
183
-		do_action( 'AHEE__EE_Registration__finalize__update_and_new_reg', $registration, ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX )));
183
+		do_action('AHEE__EE_Registration__finalize__update_and_new_reg', $registration, (is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX)));
184 184
 	}
185 185
 }
186
-add_action( 'AHEE__EE_Registration_Processor__trigger_registration_update_notifications', 'ee_deprecated_finalize_registration', 10, 1 );
186
+add_action('AHEE__EE_Registration_Processor__trigger_registration_update_notifications', 'ee_deprecated_finalize_registration', 10, 1);
187 187
 
188 188
 
189 189
 
@@ -191,7 +191,7 @@  discard block
 block discarded – undo
191 191
  * Called after EED_Module::set_hooks() and EED_Module::set_admin_hooks() was called.
192 192
  * Checks if any deprecated hooks were hooked-into and provide doing_it_wrong messages appropriately.
193 193
  */
194
-function ee_deprecated_hooks(){
194
+function ee_deprecated_hooks() {
195 195
 	/**
196 196
 	 * @var $hooks array where keys are hook names, and their values are array{
197 197
 	 *			@type string $version  when deprecated
@@ -202,25 +202,25 @@  discard block
 block discarded – undo
202 202
 	$hooks = array(
203 203
 		'AHEE__EE_System___do_setup_validations' => array(
204 204
 			'version' => '4.6.0',
205
-			'alternative' => __( 'Instead use "AHEE__EEH_Activation__validate_messages_system" which is called after validating messages (done on every new install, upgrade, reactivation, and downgrade)', 'event_espresso' ),
205
+			'alternative' => __('Instead use "AHEE__EEH_Activation__validate_messages_system" which is called after validating messages (done on every new install, upgrade, reactivation, and downgrade)', 'event_espresso'),
206 206
 			'still_works' => FALSE
207 207
 		)
208 208
 	);
209
-	foreach( $hooks as $name => $deprecation_info ){
210
-		if( has_action( $name ) ){
209
+	foreach ($hooks as $name => $deprecation_info) {
210
+		if (has_action($name)) {
211 211
 			EE_Error::doing_it_wrong(
212 212
 				$name,
213 213
 				sprintf(
214
-					__('This filter is deprecated. %1$s%2$s','event_espresso'),
215
-					$deprecation_info[ 'still_works' ] ?  __('It *may* work as an attempt to build in backwards compatibility.', 'event_espresso') : __( 'It has been completely removed.', 'event_espresso' ),
216
-					isset( $deprecation_info[ 'alternative' ] ) ? $deprecation_info[ 'alternative' ] : __( 'Please read the current EE4 documentation further or contact Support.', 'event_espresso' )
214
+					__('This filter is deprecated. %1$s%2$s', 'event_espresso'),
215
+					$deprecation_info['still_works'] ? __('It *may* work as an attempt to build in backwards compatibility.', 'event_espresso') : __('It has been completely removed.', 'event_espresso'),
216
+					isset($deprecation_info['alternative']) ? $deprecation_info['alternative'] : __('Please read the current EE4 documentation further or contact Support.', 'event_espresso')
217 217
 				),
218
-				isset( $deprecation_info[ 'version' ] ) ? $deprecation_info[ 'version' ] : __( 'recently', 'event_espresso' )
218
+				isset($deprecation_info['version']) ? $deprecation_info['version'] : __('recently', 'event_espresso')
219 219
 			);
220 220
 		}
221 221
 	}
222 222
 }
223
-add_action( 'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons', 'ee_deprecated_hooks' );
223
+add_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons', 'ee_deprecated_hooks');
224 224
 
225 225
 
226 226
 
@@ -231,9 +231,9 @@  discard block
 block discarded – undo
231 231
  * @return boolean
232 232
  */
233 233
 function ee_deprecated_using_old_registration_admin_custom_questions_form_hooks() {
234
-	$in_use =  has_filter( 'FHEE__Registrations_Admin_Page___update_attendee_registration_form__qstns' )
235
-			|| has_action( 'AHEE__Registrations_Admin_Page___save_attendee_registration_form__after_reg_and_attendee_save' );
236
-	if( $in_use ) {
234
+	$in_use = has_filter('FHEE__Registrations_Admin_Page___update_attendee_registration_form__qstns')
235
+			|| has_action('AHEE__Registrations_Admin_Page___save_attendee_registration_form__after_reg_and_attendee_save');
236
+	if ($in_use) {
237 237
 		$msg = __(
238 238
 			'We detected you are using the filter FHEE__Registrations_Admin_Page___update_attendee_registration_form__qstns or AHEE__Registrations_Admin_Page___save_attendee_registration_form__after_reg_and_attendee_save.'
239 239
 			. 'Both of these have been deprecated and should not be used anymore. You should instead use FHEE__EE_Form_Section_Proper___construct__options_array to customize the contents of the form,'
@@ -242,18 +242,18 @@  discard block
 block discarded – undo
242 242
 			'event_espresso' )
243 243
 		;
244 244
 		EE_Error::doing_it_wrong(
245
-			__CLASS__ . '::' . __FUNCTION__,
245
+			__CLASS__.'::'.__FUNCTION__,
246 246
 			$msg,
247 247
 			'4.8.32.rc.000'
248 248
 		);
249 249
 		//it seems the doing_it_wrong messages get output during some hidden html tags, so add an error to make sure this gets noticed
250
-		if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
251
-			EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
250
+		if (is_admin() && ! defined('DOING_AJAX')) {
251
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
252 252
 		}
253 253
 	}
254 254
 	return $in_use;
255 255
 }
256
-add_action( 'AHEE__Registrations_Admin_Page___registration_details_metabox__start', 'ee_deprecated_using_old_registration_admin_custom_questions_form_hooks' );
256
+add_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', 'ee_deprecated_using_old_registration_admin_custom_questions_form_hooks');
257 257
 
258 258
 /**
259 259
  * @deprecated since 4.8.32.rc.000 because it has issues on https://events.codebasehq.com/projects/event-espresso/tickets/9165
@@ -262,34 +262,34 @@  discard block
 block discarded – undo
262 262
  * @param EE_Admin_Page $admin_page
263 263
  * @return void
264 264
  */
265
-function ee_deprecated_update_attendee_registration_form_old( $admin_page ) {
265
+function ee_deprecated_update_attendee_registration_form_old($admin_page) {
266 266
 	//check if the old hooks are in use. If not, do the default
267
-	if( ! ee_deprecated_using_old_registration_admin_custom_questions_form_hooks()
268
-		|| ! $admin_page instanceof EE_Admin_Page ) {
267
+	if ( ! ee_deprecated_using_old_registration_admin_custom_questions_form_hooks()
268
+		|| ! $admin_page instanceof EE_Admin_Page) {
269 269
 		return;
270 270
 	}
271 271
 	$req_data = $admin_page->get_request_data();
272
-	$qstns = isset( $req_data['qstn'] ) ? $req_data['qstn'] : FALSE;
273
-	$REG_ID = isset( $req_data['_REG_ID'] ) ? absint( $req_data['_REG_ID'] ) : FALSE;
274
-	$qstns = apply_filters( 'FHEE__Registrations_Admin_Page___update_attendee_registration_form__qstns', $qstns );
275
-	if ( ! $REG_ID || ! $qstns ) {
276
-		EE_Error::add_error( __('An error occurred. No registration ID and/or registration questions were received.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
272
+	$qstns = isset($req_data['qstn']) ? $req_data['qstn'] : FALSE;
273
+	$REG_ID = isset($req_data['_REG_ID']) ? absint($req_data['_REG_ID']) : FALSE;
274
+	$qstns = apply_filters('FHEE__Registrations_Admin_Page___update_attendee_registration_form__qstns', $qstns);
275
+	if ( ! $REG_ID || ! $qstns) {
276
+		EE_Error::add_error(__('An error occurred. No registration ID and/or registration questions were received.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
277 277
 	}
278 278
 	$success = TRUE;
279 279
 
280 280
 	// allow others to get in on this awesome fun   :D
281
-	do_action( 'AHEE__Registrations_Admin_Page___save_attendee_registration_form__after_reg_and_attendee_save', $REG_ID, $qstns );
281
+	do_action('AHEE__Registrations_Admin_Page___save_attendee_registration_form__after_reg_and_attendee_save', $REG_ID, $qstns);
282 282
 	// loop thru questions... FINALLY!!!
283 283
 
284
-	foreach ( $qstns as $QST_ID => $qstn ) {
284
+	foreach ($qstns as $QST_ID => $qstn) {
285 285
 		//if $qstn isn't an array then it doesn't already have an answer, so let's create the answer
286
-		if ( !is_array($qstn) ) {
287
-			$success = $this->_save_new_answer( $REG_ID, $QST_ID, $qstn);
286
+		if ( ! is_array($qstn)) {
287
+			$success = $this->_save_new_answer($REG_ID, $QST_ID, $qstn);
288 288
 			continue;
289 289
 		}
290 290
 
291 291
 
292
-		foreach ( $qstn as $ANS_ID => $ANS_value ) {
292
+		foreach ($qstn as $ANS_ID => $ANS_value) {
293 293
 			//get answer
294 294
 			$query_params = array(
295 295
 				0 => array(
@@ -300,7 +300,7 @@  discard block
 block discarded – undo
300 300
 				);
301 301
 			$answer = EEM_Answer::instance()->get_one($query_params);
302 302
 			//this MAY be an array but NOT have an answer because its multi select.  If so then we need to create the answer
303
-			if ( ! $answer instanceof EE_Answer ) {
303
+			if ( ! $answer instanceof EE_Answer) {
304 304
 				$set_values = array(
305 305
 					'QST_ID' => $QST_ID,
306 306
 					'REG_ID' => $REG_ID,
@@ -315,11 +315,11 @@  discard block
 block discarded – undo
315 315
 		}
316 316
 	}
317 317
 	$what = __('Registration Form', 'event_espresso');
318
-	$route = $REG_ID ? array( 'action' => 'view_registration', '_REG_ID' => $REG_ID ) : array( 'action' => 'default' );
319
-	$admin_page->redirect_after_action( $success, $what, __('updated', 'event_espresso'), $route );
318
+	$route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID) : array('action' => 'default');
319
+	$admin_page->redirect_after_action($success, $what, __('updated', 'event_espresso'), $route);
320 320
 	exit;
321 321
 }
322
-add_action( 'AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', 'ee_deprecated_update_attendee_registration_form_old', 10, 1 );
322
+add_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', 'ee_deprecated_update_attendee_registration_form_old', 10, 1);
323 323
 /**
324 324
  * Render the registration admin page's custom questions area in the old fashion
325 325
  * and firing the old hooks. When this method is removed, we can probably also
@@ -332,31 +332,31 @@  discard block
 block discarded – undo
332 332
  * @return bool
333 333
  * @throws \EE_Error
334 334
  */
335
-function ee_deprecated_reg_questions_meta_box_old( $do_default_action, $admin_page, $registration ) {
335
+function ee_deprecated_reg_questions_meta_box_old($do_default_action, $admin_page, $registration) {
336 336
 	//check if the old hooks are in use. If not, do the default
337
-	if( ! ee_deprecated_using_old_registration_admin_custom_questions_form_hooks()
338
-		|| ! $admin_page instanceof EE_Admin_Page ) {
337
+	if ( ! ee_deprecated_using_old_registration_admin_custom_questions_form_hooks()
338
+		|| ! $admin_page instanceof EE_Admin_Page) {
339 339
 		return $do_default_action;
340 340
 	}
341
-	add_filter( 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', array( $admin_page, 'form_before_question_group' ), 10, 1 );
342
-	add_filter( 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', array( $admin_page, 'form_after_question_group' ), 10, 1 );
343
-	add_filter( 'FHEE__EEH_Form_Fields__label_html', array( $admin_page, 'form_form_field_label_wrap' ), 10, 1 );
344
-	add_filter( 'FHEE__EEH_Form_Fields__input_html', array( $admin_page, 'form_form_field_input__wrap' ), 10, 1 );
341
+	add_filter('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', array($admin_page, 'form_before_question_group'), 10, 1);
342
+	add_filter('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', array($admin_page, 'form_after_question_group'), 10, 1);
343
+	add_filter('FHEE__EEH_Form_Fields__label_html', array($admin_page, 'form_form_field_label_wrap'), 10, 1);
344
+	add_filter('FHEE__EEH_Form_Fields__input_html', array($admin_page, 'form_form_field_input__wrap'), 10, 1);
345 345
 
346
-	$question_groups = EEM_Event::instance()->assemble_array_of_groups_questions_and_options( $registration, $registration->get('EVT_ID') );
346
+	$question_groups = EEM_Event::instance()->assemble_array_of_groups_questions_and_options($registration, $registration->get('EVT_ID'));
347 347
 
348
-	EE_Registry::instance()->load_helper( 'Form_Fields' );
348
+	EE_Registry::instance()->load_helper('Form_Fields');
349 349
 	$template_args = array(
350
-		'att_questions' => EEH_Form_Fields::generate_question_groups_html( $question_groups ),
350
+		'att_questions' => EEH_Form_Fields::generate_question_groups_html($question_groups),
351 351
 		'reg_questions_form_action' => 'edit_registration',
352 352
 		'REG_ID' => $registration->ID()
353 353
 	);
354
-	$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
355
-	echo EEH_Template::display_template( $template_path, $template_args, TRUE );
354
+	$template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
355
+	echo EEH_Template::display_template($template_path, $template_args, TRUE);
356 356
 	//indicate that we should not do the default admin page code
357 357
 	return false;
358 358
 }
359
-add_action( 'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', 'ee_deprecated_reg_questions_meta_box_old', 10, 3 );
359
+add_action('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', 'ee_deprecated_reg_questions_meta_box_old', 10, 3);
360 360
 
361 361
 
362 362
 
@@ -397,9 +397,9 @@  discard block
 block discarded – undo
397 397
 			'4.9.0'
398 398
 		);
399 399
 		/** @var EE_Message_Resource_Manager $message_resource_manager */
400
-		$message_resource_manager = EE_Registry::instance()->load_lib( 'Message_Resource_Manager' );
401
-		$messenger = $message_resource_manager->get_messenger( $messenger_name );
402
-		$message_type = $message_resource_manager->get_message_type( $message_type_name );
400
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
401
+		$messenger = $message_resource_manager->get_messenger($messenger_name);
402
+		$message_type = $message_resource_manager->get_message_type($message_type_name);
403 403
 		return EE_Registry::instance()->load_lib(
404 404
 			'Messages_Template_Defaults',
405 405
 			array(
@@ -464,15 +464,15 @@  discard block
 block discarded – undo
464 464
 	/**
465 465
 	 * @param string $method
466 466
 	 */
467
-	public function _class_is_deprecated( $method ) {
467
+	public function _class_is_deprecated($method) {
468 468
 		EE_Error::doing_it_wrong(
469
-			'EE_messages::' . $method,
470
-			__( 'EE_messages has been deprecated.  Please use EE_Message_Resource_Manager instead.' ),
469
+			'EE_messages::'.$method,
470
+			__('EE_messages has been deprecated.  Please use EE_Message_Resource_Manager instead.'),
471 471
 			'4.9.0',
472 472
 			'4.10.0.p'
473 473
 		);
474 474
 		// Please use EE_Message_Resource_Manager instead
475
-		$this->_message_resource_manager = EE_Registry::instance()->load_lib( 'Message_Resource_Manager' );
475
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
476 476
 	}
477 477
 
478 478
 
@@ -482,10 +482,10 @@  discard block
 block discarded – undo
482 482
 	 * @param string $messenger_name
483 483
 	 * @return boolean TRUE if it was PREVIOUSLY active, and FALSE if it was previously inactive
484 484
 	 */
485
-	public function ensure_messenger_is_active( $messenger_name ) {
485
+	public function ensure_messenger_is_active($messenger_name) {
486 486
 		// EE_messages has been deprecated
487
-		$this->_class_is_deprecated( __FUNCTION__ );
488
-		return $this->_message_resource_manager->ensure_messenger_is_active( $messenger_name );
487
+		$this->_class_is_deprecated(__FUNCTION__);
488
+		return $this->_message_resource_manager->ensure_messenger_is_active($messenger_name);
489 489
 	}
490 490
 
491 491
 
@@ -497,10 +497,10 @@  discard block
 block discarded – undo
497 497
 	 * @return bool true if it got activated (or was active) and false if not.
498 498
 	 * @throws \EE_Error
499 499
 	 */
500
-	public function ensure_message_type_is_active( $message_type, $messenger ) {
500
+	public function ensure_message_type_is_active($message_type, $messenger) {
501 501
 		// EE_messages has been deprecated
502
-		$this->_class_is_deprecated( __FUNCTION__ );
503
-		return $this->_message_resource_manager->ensure_message_type_is_active( $message_type, $messenger );
502
+		$this->_class_is_deprecated(__FUNCTION__);
503
+		return $this->_message_resource_manager->ensure_message_type_is_active($message_type, $messenger);
504 504
 	}
505 505
 
506 506
 
@@ -513,10 +513,10 @@  discard block
 block discarded – undo
513 513
 	 *                                            they are already setup.)
514 514
 	 * @return boolean an array of generated templates or false if nothing generated/activated.
515 515
 	 */
516
-	public function activate_messenger( $messenger_name, $mts_to_activate = array() ) {
516
+	public function activate_messenger($messenger_name, $mts_to_activate = array()) {
517 517
 		// EE_messages has been deprecated
518
-		$this->_class_is_deprecated( __FUNCTION__ );
519
-		return $this->_message_resource_manager->activate_messenger( $messenger_name, $mts_to_activate );
518
+		$this->_class_is_deprecated(__FUNCTION__);
519
+		return $this->_message_resource_manager->activate_messenger($messenger_name, $mts_to_activate);
520 520
 	}
521 521
 
522 522
 
@@ -528,10 +528,10 @@  discard block
 block discarded – undo
528 528
 	 *
529 529
 	 * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
530 530
 	 */
531
-	public function is_generating_messenger_and_active( EE_messenger $messenger, EE_message_type $message_type ) {
531
+	public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type) {
532 532
 		// EE_messages has been deprecated
533
-		$this->_class_is_deprecated( __FUNCTION__ );
534
-		return $this->_message_resource_manager->is_generating_messenger_and_active( $messenger, $message_type );
533
+		$this->_class_is_deprecated(__FUNCTION__);
534
+		return $this->_message_resource_manager->is_generating_messenger_and_active($messenger, $message_type);
535 535
 	}
536 536
 
537 537
 
@@ -541,10 +541,10 @@  discard block
 block discarded – undo
541 541
 	 * @param string $messenger
542 542
 	 * @return EE_messenger | null
543 543
 	 */
544
-	public function get_messenger_if_active( $messenger ) {
544
+	public function get_messenger_if_active($messenger) {
545 545
 		// EE_messages has been deprecated
546
-		$this->_class_is_deprecated( __FUNCTION__ );
547
-		return $this->_message_resource_manager->get_active_messenger( $messenger );
546
+		$this->_class_is_deprecated(__FUNCTION__);
547
+		return $this->_message_resource_manager->get_active_messenger($messenger);
548 548
 	}
549 549
 
550 550
 
@@ -565,9 +565,9 @@  discard block
 block discarded – undo
565 565
 	 *                  'message_type' => null
566 566
 	 *                  )
567 567
 	 */
568
-	public function validate_for_use( EE_Message $message ) {
568
+	public function validate_for_use(EE_Message $message) {
569 569
 		// EE_messages has been deprecated
570
-		$this->_class_is_deprecated( __FUNCTION__ );
570
+		$this->_class_is_deprecated(__FUNCTION__);
571 571
 		return array(
572 572
 			'messenger'    => $message->messenger_object(),
573 573
 			'message_type' => $message->message_type_object(),
@@ -595,41 +595,41 @@  discard block
 block discarded – undo
595 595
 		$send = true
596 596
 	) {
597 597
 		// EE_messages has been deprecated
598
-		$this->_class_is_deprecated( __FUNCTION__ );
598
+		$this->_class_is_deprecated(__FUNCTION__);
599 599
 		/** @type EE_Messages_Processor $processor */
600
-		$processor = EE_Registry::instance()->load_lib( 'Messages_Processor' );
600
+		$processor = EE_Registry::instance()->load_lib('Messages_Processor');
601 601
 		$error = false;
602 602
 		//try to intelligently determine what method we'll call based on the incoming data.
603 603
 		//if generating and sending are different then generate and send immediately.
604
-		if ( ! empty( $sending_messenger ) && $sending_messenger != $generating_messenger && $send ) {
604
+		if ( ! empty($sending_messenger) && $sending_messenger != $generating_messenger && $send) {
605 605
 			//in the legacy system, when generating and sending were different, that means all the
606 606
 			//vars are already in the request object.  So let's just use that.
607 607
 			try {
608 608
 				/** @type EE_Message_To_Generate_From_Request $mtg */
609
-				$mtg = EE_Registry::instance()->load_lib( 'Message_To_Generate_From_Request' );
610
-				$processor->generate_and_send_now( $mtg );
611
-			} catch ( EE_Error $e ) {
609
+				$mtg = EE_Registry::instance()->load_lib('Message_To_Generate_From_Request');
610
+				$processor->generate_and_send_now($mtg);
611
+			} catch (EE_Error $e) {
612 612
 				$error_msg = __(
613 613
 					'Please note that a system message failed to send due to a technical issue.',
614 614
 					'event_espresso'
615 615
 				);
616 616
 				// add specific message for developers if WP_DEBUG in on
617
-				$error_msg .= '||' . $e->getMessage();
618
-				EE_Error::add_error( $error_msg, __FILE__, __FUNCTION__, __LINE__ );
617
+				$error_msg .= '||'.$e->getMessage();
618
+				EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
619 619
 				$error = true;
620 620
 			}
621 621
 		} else {
622
-			$processor->generate_for_all_active_messengers( $type, $vars, $send );
622
+			$processor->generate_for_all_active_messengers($type, $vars, $send);
623 623
 			//let's find out if there were any errors and how many successfully were queued.
624 624
 			$count_errors = $processor->get_queue()->count_STS_in_queue(
625
-				array( EEM_Message::status_failed, EEM_Message::status_debug_only )
625
+				array(EEM_Message::status_failed, EEM_Message::status_debug_only)
626 626
 			);
627
-			$count_queued = $processor->get_queue()->count_STS_in_queue( EEM_Message::status_incomplete );
628
-			$count_retry = $processor->get_queue()->count_STS_in_queue( EEM_Message::status_retry );
627
+			$count_queued = $processor->get_queue()->count_STS_in_queue(EEM_Message::status_incomplete);
628
+			$count_retry = $processor->get_queue()->count_STS_in_queue(EEM_Message::status_retry);
629 629
 			$count_errors = $count_errors + $count_retry;
630
-			if ( $count_errors > 0 ) {
630
+			if ($count_errors > 0) {
631 631
 				$error = true;
632
-				if ( $count_errors > 1 && $count_retry > 1 && $count_queued > 1 ) {
632
+				if ($count_errors > 1 && $count_retry > 1 && $count_queued > 1) {
633 633
 					$message = sprintf(
634 634
 						__(
635 635
 							'There were %d errors and %d messages successfully queued for generation and sending',
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
 						$count_errors,
639 639
 						$count_queued
640 640
 					);
641
-				} elseif ( $count_errors > 1 && $count_queued === 1 ) {
641
+				} elseif ($count_errors > 1 && $count_queued === 1) {
642 642
 					$message = sprintf(
643 643
 						__(
644 644
 							'There were %d errors and %d message successfully queued for generation.',
@@ -647,7 +647,7 @@  discard block
 block discarded – undo
647 647
 						$count_errors,
648 648
 						$count_queued
649 649
 					);
650
-				} elseif ( $count_errors === 1 && $count_queued > 1 ) {
650
+				} elseif ($count_errors === 1 && $count_queued > 1) {
651 651
 					$message = sprintf(
652 652
 						__(
653 653
 							'There was %d error and %d messages successfully queued for generation.',
@@ -665,9 +665,9 @@  discard block
 block discarded – undo
665 665
 						$count_errors
666 666
 					);
667 667
 				}
668
-				EE_Error::add_error( $message, __FILE__, __FUNCTION__, __LINE__ );
668
+				EE_Error::add_error($message, __FILE__, __FUNCTION__, __LINE__);
669 669
 			} else {
670
-				if ( $count_queued === 1 ) {
670
+				if ($count_queued === 1) {
671 671
 					$message = sprintf(
672 672
 						__(
673 673
 							'%d message successfully queued for generation.',
@@ -684,18 +684,18 @@  discard block
 block discarded – undo
684 684
 						$count_queued
685 685
 					);
686 686
 				}
687
-				EE_Error::add_success( $message );
687
+				EE_Error::add_success($message);
688 688
 			}
689 689
 		}
690 690
 		//if no error then return the generated message(s).
691
-		if ( ! $error && ! $send ) {
692
-			$generated_queue = $processor->generate_queue( false );
691
+		if ( ! $error && ! $send) {
692
+			$generated_queue = $processor->generate_queue(false);
693 693
 			//get message and return.
694 694
 			$generated_queue->get_message_repository()->rewind();
695 695
 			$messages = array();
696
-			while ( $generated_queue->get_message_repository()->valid() ) {
696
+			while ($generated_queue->get_message_repository()->valid()) {
697 697
 				$message = $generated_queue->get_message_repository()->current();
698
-				if ( $message instanceof EE_Message ) {
698
+				if ($message instanceof EE_Message) {
699 699
 					//set properties that might be expected by add-ons (backward compat)
700 700
 					$message->content = $message->content();
701 701
 					$message->template_pack = $message->get_template_pack();
@@ -720,10 +720,10 @@  discard block
 block discarded – undo
720 720
 	 * @param bool    $send      true we will do a test send using the messenger delivery, false we just do a regular preview
721 721
 	 * @return string          The body of the message.
722 722
 	 */
723
-	public function preview_message( $type, $context, $messenger, $send = false ) {
723
+	public function preview_message($type, $context, $messenger, $send = false) {
724 724
 		// EE_messages has been deprecated
725
-		$this->_class_is_deprecated( __FUNCTION__ );
726
-		return EED_Messages::preview_message( $type, $context, $messenger, $send );
725
+		$this->_class_is_deprecated(__FUNCTION__);
726
+		return EED_Messages::preview_message($type, $context, $messenger, $send);
727 727
 	}
728 728
 
729 729
 
@@ -737,14 +737,14 @@  discard block
 block discarded – undo
737 737
 	 *
738 738
 	 * @return bool          success or fail.
739 739
 	 */
740
-	public function send_message_with_messenger_only( $messenger, $message_type, $message ) {
740
+	public function send_message_with_messenger_only($messenger, $message_type, $message) {
741 741
 		// EE_messages has been deprecated
742
-		$this->_class_is_deprecated( __FUNCTION__ );
742
+		$this->_class_is_deprecated(__FUNCTION__);
743 743
 		//setup for sending to new method.
744 744
 		/** @type EE_Messages_Queue $queue */
745
-		$queue = EE_Registry::instance()->load_lib( 'Messages_Queue' );
745
+		$queue = EE_Registry::instance()->load_lib('Messages_Queue');
746 746
 		//make sure we have a proper message object
747
-		if ( ! $message instanceof EE_Message && is_object( $message ) && isset( $message->content ) ) {
747
+		if ( ! $message instanceof EE_Message && is_object($message) && isset($message->content)) {
748 748
 			$msg = EE_Message_Factory::create(
749 749
 				array(
750 750
 					'MSG_messenger'    => $messenger,
@@ -756,15 +756,15 @@  discard block
 block discarded – undo
756 756
 		} else {
757 757
 			$msg = $message;
758 758
 		}
759
-		if ( ! $msg instanceof EE_Message ) {
759
+		if ( ! $msg instanceof EE_Message) {
760 760
 			return false;
761 761
 		}
762 762
 		//make sure any content in a content property (if not empty) is set on the MSG_content.
763
-		if ( ! empty( $msg->content ) ) {
764
-			$msg->set( 'MSG_content', $msg->content );
763
+		if ( ! empty($msg->content)) {
764
+			$msg->set('MSG_content', $msg->content);
765 765
 		}
766
-		$queue->add( $msg );
767
-		return EED_Messages::send_message_with_messenger_only( $messenger, $message_type, $queue );
766
+		$queue->add($msg);
767
+		return EED_Messages::send_message_with_messenger_only($messenger, $message_type, $queue);
768 768
 	}
769 769
 
770 770
 
@@ -778,11 +778,11 @@  discard block
 block discarded – undo
778 778
 	 * @return array|object if creation is successful then we return an array of info, otherwise an error_object is returned.
779 779
 	 * @throws \EE_Error
780 780
 	 */
781
-	public function create_new_templates( $messenger, $message_type, $GRP_ID = 0, $is_global = false ) {
781
+	public function create_new_templates($messenger, $message_type, $GRP_ID = 0, $is_global = false) {
782 782
 		// EE_messages has been deprecated
783
-		$this->_class_is_deprecated( __FUNCTION__ );
784
-		EE_Registry::instance()->load_helper( 'MSG_Template' );
785
-		return EEH_MSG_Template::create_new_templates( $messenger, $message_type, $GRP_ID, $is_global );
783
+		$this->_class_is_deprecated(__FUNCTION__);
784
+		EE_Registry::instance()->load_helper('MSG_Template');
785
+		return EEH_MSG_Template::create_new_templates($messenger, $message_type, $GRP_ID, $is_global);
786 786
 	}
787 787
 
788 788
 
@@ -793,11 +793,11 @@  discard block
 block discarded – undo
793 793
 	 * @param  string $message_type_name name of EE_message_type
794 794
 	 * @return array
795 795
 	 */
796
-	public function get_fields( $messenger_name, $message_type_name ) {
796
+	public function get_fields($messenger_name, $message_type_name) {
797 797
 		// EE_messages has been deprecated
798
-		$this->_class_is_deprecated( __FUNCTION__ );
799
-		EE_Registry::instance()->load_helper( 'MSG_Template' );
800
-		return EEH_MSG_Template::get_fields( $messenger_name, $message_type_name );
798
+		$this->_class_is_deprecated(__FUNCTION__);
799
+		EE_Registry::instance()->load_helper('MSG_Template');
800
+		return EEH_MSG_Template::get_fields($messenger_name, $message_type_name);
801 801
 	}
802 802
 
803 803
 
@@ -811,13 +811,13 @@  discard block
 block discarded – undo
811 811
 	 * @return array                    multidimensional array of messenger and message_type objects
812 812
 	 *                                    (messengers index, and message_type index);
813 813
 	 */
814
-	public function get_installed( $type = 'all', $skip_cache = false ) {
814
+	public function get_installed($type = 'all', $skip_cache = false) {
815 815
 		// EE_messages has been deprecated
816
-		$this->_class_is_deprecated( __FUNCTION__ );
817
-		if ( $skip_cache ) {
816
+		$this->_class_is_deprecated(__FUNCTION__);
817
+		if ($skip_cache) {
818 818
 			$this->_message_resource_manager->reset_active_messengers_and_message_types();
819 819
 		}
820
-		switch ( $type ) {
820
+		switch ($type) {
821 821
 			case 'messengers' :
822 822
 				return array(
823 823
 					'messenger' => $this->_message_resource_manager->installed_messengers(),
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
 	 */
847 847
 	public function get_active_messengers() {
848 848
 		// EE_messages has been deprecated
849
-		$this->_class_is_deprecated( __FUNCTION__ );
849
+		$this->_class_is_deprecated(__FUNCTION__);
850 850
 		return $this->_message_resource_manager->active_messengers();
851 851
 	}
852 852
 
@@ -858,7 +858,7 @@  discard block
 block discarded – undo
858 858
 	 */
859 859
 	public function get_active_message_types() {
860 860
 		// EE_messages has been deprecated
861
-		$this->_class_is_deprecated( __FUNCTION__ );
861
+		$this->_class_is_deprecated(__FUNCTION__);
862 862
 		return $this->_message_resource_manager->list_of_active_message_types();
863 863
 	}
864 864
 
@@ -870,7 +870,7 @@  discard block
 block discarded – undo
870 870
 	 */
871 871
 	public function get_active_message_type_objects() {
872 872
 		// EE_messages has been deprecated
873
-		$this->_class_is_deprecated( __FUNCTION__ );
873
+		$this->_class_is_deprecated(__FUNCTION__);
874 874
 		return $this->_message_resource_manager->get_active_message_type_objects();
875 875
 	}
876 876
 
@@ -882,10 +882,10 @@  discard block
 block discarded – undo
882 882
 	 * @param string $messenger The messenger being checked
883 883
 	 * @return EE_message_type[]    (or empty array if none present)
884 884
 	 */
885
-	public function get_active_message_types_per_messenger( $messenger ) {
885
+	public function get_active_message_types_per_messenger($messenger) {
886 886
 		// EE_messages has been deprecated
887
-		$this->_class_is_deprecated( __FUNCTION__ );
888
-		return $this->_message_resource_manager->get_active_message_types_for_messenger( $messenger );
887
+		$this->_class_is_deprecated(__FUNCTION__);
888
+		return $this->_message_resource_manager->get_active_message_types_for_messenger($messenger);
889 889
 	}
890 890
 
891 891
 
@@ -896,10 +896,10 @@  discard block
 block discarded – undo
896 896
 	 * @param string $message_type The string should correspond to a message type.
897 897
 	 * @return EE_message_type|null
898 898
 	 */
899
-	public function get_active_message_type( $messenger, $message_type ) {
899
+	public function get_active_message_type($messenger, $message_type) {
900 900
 		// EE_messages has been deprecated
901
-		$this->_class_is_deprecated( __FUNCTION__ );
902
-		return $this->_message_resource_manager->get_active_message_type_for_messenger( $messenger, $message_type );
901
+		$this->_class_is_deprecated(__FUNCTION__);
902
+		return $this->_message_resource_manager->get_active_message_type_for_messenger($messenger, $message_type);
903 903
 	}
904 904
 
905 905
 
@@ -910,7 +910,7 @@  discard block
 block discarded – undo
910 910
 	 */
911 911
 	public function get_installed_message_types() {
912 912
 		// EE_messages has been deprecated
913
-		$this->_class_is_deprecated( __FUNCTION__ );
913
+		$this->_class_is_deprecated(__FUNCTION__);
914 914
 		return $this->_message_resource_manager->installed_message_types();
915 915
 	}
916 916
 
@@ -922,7 +922,7 @@  discard block
 block discarded – undo
922 922
 	 */
923 923
 	public function get_installed_messengers() {
924 924
 		// EE_messages has been deprecated
925
-		$this->_class_is_deprecated( __FUNCTION__ );
925
+		$this->_class_is_deprecated(__FUNCTION__);
926 926
 		return $this->_message_resource_manager->installed_messengers();
927 927
 	}
928 928
 
@@ -933,10 +933,10 @@  discard block
 block discarded – undo
933 933
 	 * @param   bool $slugs_only Whether to return an array of just slugs and labels (true) or all contexts indexed by message type.
934 934
 	 * @return array
935 935
 	 */
936
-	public function get_all_contexts( $slugs_only = true ) {
936
+	public function get_all_contexts($slugs_only = true) {
937 937
 		// EE_messages has been deprecated
938
-		$this->_class_is_deprecated( __FUNCTION__ );
939
-		return $this->_message_resource_manager->get_all_contexts( $slugs_only );
938
+		$this->_class_is_deprecated(__FUNCTION__);
939
+		return $this->_message_resource_manager->get_all_contexts($slugs_only);
940 940
 	}
941 941
 
942 942
 
@@ -995,7 +995,7 @@  discard block
 block discarded – undo
995 995
 add_filter(
996 996
 	'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__css',
997 997
 	function($event_list_iframe_css) {
998
-		if ( ! has_filter( 'FHEE__EventsArchiveIframe__event_list_iframe__css' )) {
998
+		if ( ! has_filter('FHEE__EventsArchiveIframe__event_list_iframe__css')) {
999 999
 			return $event_list_iframe_css;
1000 1000
 		}
1001 1001
 		deprecated_espresso_action_or_filter_doing_it_wrong(
@@ -1015,7 +1015,7 @@  discard block
 block discarded – undo
1015 1015
 add_filter(
1016 1016
 	'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js',
1017 1017
 	function($event_list_iframe_js) {
1018
-		if ( ! has_filter( 'FHEE__EED_Ticket_Selector__ticket_selector_iframe__js' )) {
1018
+		if ( ! has_filter('FHEE__EED_Ticket_Selector__ticket_selector_iframe__js')) {
1019 1019
 			return $event_list_iframe_js;
1020 1020
 		}
1021 1021
 		deprecated_espresso_action_or_filter_doing_it_wrong(
@@ -1035,7 +1035,7 @@  discard block
 block discarded – undo
1035 1035
 add_action(
1036 1036
 	'AHEE__EE_Capabilities__addCaps__complete',
1037 1037
 	function($capabilities_map) {
1038
-		if ( ! has_action( 'AHEE__EE_Capabilities__init_role_caps__complete' )) {
1038
+		if ( ! has_action('AHEE__EE_Capabilities__init_role_caps__complete')) {
1039 1039
 			return;
1040 1040
 		}
1041 1041
 		deprecated_espresso_action_or_filter_doing_it_wrong(
@@ -1055,7 +1055,7 @@  discard block
 block discarded – undo
1055 1055
 add_filter(
1056 1056
 	'FHEE_EventEspresso_core_services_commands_attendee_CreateAttendeeCommandHandler__findExistingAttendee__existing_attendee',
1057 1057
 	function($existing_attendee, $registration, $attendee_data) {
1058
-		if ( ! has_filter( 'FHEE_EE_Single_Page_Checkout__save_registration_items__find_existing_attendee' )) {
1058
+		if ( ! has_filter('FHEE_EE_Single_Page_Checkout__save_registration_items__find_existing_attendee')) {
1059 1059
 			return $existing_attendee;
1060 1060
 		}
1061 1061
 		deprecated_espresso_action_or_filter_doing_it_wrong(
@@ -1071,7 +1071,7 @@  discard block
 block discarded – undo
1071 1071
             $existing_attendee, $registration, $attendee_data
1072 1072
         );
1073 1073
 	},
1074
-	10,3
1074
+	10, 3
1075 1075
 );
1076 1076
 
1077 1077
 /**
@@ -1135,7 +1135,7 @@  discard block
 block discarded – undo
1135 1135
      */
1136 1136
     public function event_list_title($event_list_title = '')
1137 1137
     {
1138
-        if (! empty($this->title)) {
1138
+        if ( ! empty($this->title)) {
1139 1139
             return $this->title;
1140 1140
         }
1141 1141
         return $event_list_title;
Please login to merge, or discard this patch.
core/EE_Registry.core.php 2 patches
Indentation   +1428 added lines, -1428 removed lines patch added patch discarded remove patch
@@ -19,1464 +19,1464 @@
 block discarded – undo
19 19
 class EE_Registry implements ResettableInterface
20 20
 {
21 21
 
22
-    /**
23
-     *    EE_Registry Object
24
-     *
25
-     * @var EE_Registry $_instance
26
-     * @access    private
27
-     */
28
-    private static $_instance = null;
29
-
30
-    /**
31
-     * @var EE_Dependency_Map $_dependency_map
32
-     * @access    protected
33
-     */
34
-    protected $_dependency_map = null;
35
-
36
-    /**
37
-     * @var array $_class_abbreviations
38
-     * @access    protected
39
-     */
40
-    protected $_class_abbreviations = array();
41
-
42
-    /**
43
-     * @access public
44
-     * @var \EventEspresso\core\services\commands\CommandBusInterface $BUS
45
-     */
46
-    public $BUS;
47
-
48
-    /**
49
-     *    EE_Cart Object
50
-     *
51
-     * @access    public
52
-     * @var    EE_Cart $CART
53
-     */
54
-    public $CART = null;
55
-
56
-    /**
57
-     *    EE_Config Object
58
-     *
59
-     * @access    public
60
-     * @var    EE_Config $CFG
61
-     */
62
-    public $CFG = null;
63
-
64
-    /**
65
-     * EE_Network_Config Object
66
-     *
67
-     * @access public
68
-     * @var EE_Network_Config $NET_CFG
69
-     */
70
-    public $NET_CFG = null;
71
-
72
-    /**
73
-     *    StdClass object for storing library classes in
74
-     *
75
-     * @public LIB
76
-     * @var StdClass $LIB
77
-     */
78
-    public $LIB = null;
79
-
80
-    /**
81
-     *    EE_Request_Handler Object
82
-     *
83
-     * @access    public
84
-     * @var    EE_Request_Handler $REQ
85
-     */
86
-    public $REQ = null;
87
-
88
-    /**
89
-     *    EE_Session Object
90
-     *
91
-     * @access    public
92
-     * @var    EE_Session $SSN
93
-     */
94
-    public $SSN = null;
95
-
96
-    /**
97
-     * holds the ee capabilities object.
98
-     *
99
-     * @since 4.5.0
100
-     * @var EE_Capabilities
101
-     */
102
-    public $CAP = null;
103
-
104
-    /**
105
-     * holds the EE_Message_Resource_Manager object.
106
-     *
107
-     * @since 4.9.0
108
-     * @var EE_Message_Resource_Manager
109
-     */
110
-    public $MRM = null;
111
-
112
-
113
-    /**
114
-     * Holds the Assets Registry instance
115
-     * @var Registry
116
-     */
117
-    public $AssetsRegistry = null;
118
-
119
-    /**
120
-     *    $addons - StdClass object for holding addons which have registered themselves to work with EE core
121
-     *
122
-     * @access    public
123
-     * @var    EE_Addon[]
124
-     */
125
-    public $addons = null;
126
-
127
-    /**
128
-     *    $models
129
-     * @access    public
130
-     * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
131
-     */
132
-    public $models = array();
133
-
134
-    /**
135
-     *    $modules
136
-     * @access    public
137
-     * @var    EED_Module[] $modules
138
-     */
139
-    public $modules = null;
140
-
141
-    /**
142
-     *    $shortcodes
143
-     * @access    public
144
-     * @var    EES_Shortcode[] $shortcodes
145
-     */
146
-    public $shortcodes = null;
147
-
148
-    /**
149
-     *    $widgets
150
-     * @access    public
151
-     * @var    WP_Widget[] $widgets
152
-     */
153
-    public $widgets = null;
154
-
155
-    /**
156
-     * $non_abstract_db_models
157
-     * @access public
158
-     * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
159
-     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
160
-     * Keys are model "short names" (eg "Event") as used in model relations, and values are
161
-     * classnames (eg "EEM_Event")
162
-     */
163
-    public $non_abstract_db_models = array();
164
-
165
-
166
-    /**
167
-     *    $i18n_js_strings - internationalization for JS strings
168
-     *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
169
-     *    in js file:  var translatedString = eei18n.string_key;
170
-     *
171
-     * @access    public
172
-     * @var    array
173
-     */
174
-    public static $i18n_js_strings = array();
175
-
176
-
177
-    /**
178
-     *    $main_file - path to espresso.php
179
-     *
180
-     * @access    public
181
-     * @var    array
182
-     */
183
-    public $main_file;
184
-
185
-    /**
186
-     * array of ReflectionClass objects where the key is the class name
187
-     *
188
-     * @access    public
189
-     * @var ReflectionClass[]
190
-     */
191
-    public $_reflectors;
192
-
193
-    /**
194
-     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
195
-     *
196
-     * @access    protected
197
-     * @var boolean $_cache_on
198
-     */
199
-    protected $_cache_on = true;
200
-
201
-
202
-
203
-    /**
204
-     * @singleton method used to instantiate class object
205
-     * @access    public
206
-     * @param  \EE_Dependency_Map $dependency_map
207
-     * @return \EE_Registry instance
208
-     */
209
-    public static function instance(\EE_Dependency_Map $dependency_map = null)
210
-    {
211
-        // check if class object is instantiated
212
-        if ( ! self::$_instance instanceof EE_Registry) {
213
-            self::$_instance = new EE_Registry($dependency_map);
214
-        }
215
-        return self::$_instance;
216
-    }
217
-
218
-
219
-
220
-    /**
221
-     *protected constructor to prevent direct creation
222
-     *
223
-     * @Constructor
224
-     * @access protected
225
-     * @param  \EE_Dependency_Map $dependency_map
226
-     */
227
-    protected function __construct(\EE_Dependency_Map $dependency_map)
228
-    {
229
-        $this->_dependency_map = $dependency_map;
230
-        $this->LIB = new stdClass();
231
-        $this->addons = new stdClass();
232
-        $this->modules = new stdClass();
233
-        $this->shortcodes = new stdClass();
234
-        $this->widgets = new stdClass();
235
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
236
-    }
237
-
238
-
239
-
240
-    /**
241
-     * initialize
242
-     */
243
-    public function initialize()
244
-    {
245
-        $this->_class_abbreviations = apply_filters(
246
-            'FHEE__EE_Registry____construct___class_abbreviations',
247
-            array(
248
-                'EE_Config'                                       => 'CFG',
249
-                'EE_Session'                                      => 'SSN',
250
-                'EE_Capabilities'                                 => 'CAP',
251
-                'EE_Cart'                                         => 'CART',
252
-                'EE_Network_Config'                               => 'NET_CFG',
253
-                'EE_Request_Handler'                              => 'REQ',
254
-                'EE_Message_Resource_Manager'                     => 'MRM',
255
-                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
256
-                'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
257
-            )
258
-        );
259
-        $this->load_core('Base', array(), true);
260
-        // add our request and response objects to the cache
261
-        $request_loader = $this->_dependency_map->class_loader('EE_Request');
262
-        $this->_set_cached_class(
263
-            $request_loader(),
264
-            'EE_Request'
265
-        );
266
-        $response_loader = $this->_dependency_map->class_loader('EE_Response');
267
-        $this->_set_cached_class(
268
-            $response_loader(),
269
-            'EE_Response'
270
-        );
271
-        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
272
-    }
273
-
274
-
275
-
276
-    /**
277
-     *    init
278
-     *
279
-     * @access    public
280
-     * @return    void
281
-     */
282
-    public function init()
283
-    {
284
-        // Get current page protocol
285
-        $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
286
-        // Output admin-ajax.php URL with same protocol as current page
287
-        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
288
-        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
289
-    }
290
-
291
-
292
-
293
-    /**
294
-     * localize_i18n_js_strings
295
-     *
296
-     * @return string
297
-     */
298
-    public static function localize_i18n_js_strings()
299
-    {
300
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
301
-        foreach ($i18n_js_strings as $key => $value) {
302
-            if (is_scalar($value)) {
303
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
304
-            }
305
-        }
306
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
307
-    }
308
-
309
-
310
-
311
-    /**
312
-     * @param mixed string | EED_Module $module
313
-     */
314
-    public function add_module($module)
315
-    {
316
-        if ($module instanceof EED_Module) {
317
-            $module_class = get_class($module);
318
-            $this->modules->{$module_class} = $module;
319
-        } else {
320
-            if ( ! class_exists('EE_Module_Request_Router')) {
321
-                $this->load_core('Module_Request_Router');
322
-            }
323
-            $this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
324
-        }
325
-    }
326
-
327
-
328
-
329
-    /**
330
-     * @param string $module_name
331
-     * @return mixed EED_Module | NULL
332
-     */
333
-    public function get_module($module_name = '')
334
-    {
335
-        return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
336
-    }
337
-
338
-
339
-
340
-    /**
341
-     *    loads core classes - must be singletons
342
-     *
343
-     * @access    public
344
-     * @param string $class_name - simple class name ie: session
345
-     * @param mixed  $arguments
346
-     * @param bool   $load_only
347
-     * @return mixed
348
-     */
349
-    public function load_core($class_name, $arguments = array(), $load_only = false)
350
-    {
351
-        $core_paths = apply_filters(
352
-            'FHEE__EE_Registry__load_core__core_paths',
353
-            array(
354
-                EE_CORE,
355
-                EE_ADMIN,
356
-                EE_CPTS,
357
-                EE_CORE . 'data_migration_scripts' . DS,
358
-                EE_CORE . 'capabilities' . DS,
359
-                EE_CORE . 'request_stack' . DS,
360
-                EE_CORE . 'middleware' . DS,
361
-            )
362
-        );
363
-        // retrieve instantiated class
364
-        return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
365
-    }
366
-
367
-
368
-
369
-    /**
370
-     *    loads service classes
371
-     *
372
-     * @access    public
373
-     * @param string $class_name - simple class name ie: session
374
-     * @param mixed  $arguments
375
-     * @param bool   $load_only
376
-     * @return mixed
377
-     */
378
-    public function load_service($class_name, $arguments = array(), $load_only = false)
379
-    {
380
-        $service_paths = apply_filters(
381
-            'FHEE__EE_Registry__load_service__service_paths',
382
-            array(
383
-                EE_CORE . 'services' . DS,
384
-            )
385
-        );
386
-        // retrieve instantiated class
387
-        return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
388
-    }
389
-
390
-
391
-
392
-    /**
393
-     *    loads data_migration_scripts
394
-     *
395
-     * @access    public
396
-     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
397
-     * @param mixed  $arguments
398
-     * @return EE_Data_Migration_Script_Base|mixed
399
-     */
400
-    public function load_dms($class_name, $arguments = array())
401
-    {
402
-        // retrieve instantiated class
403
-        return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
404
-    }
405
-
406
-
407
-
408
-    /**
409
-     *    loads object creating classes - must be singletons
410
-     *
411
-     * @param string $class_name - simple class name ie: attendee
412
-     * @param mixed  $arguments  - an array of arguments to pass to the class
413
-     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
414
-     * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then set this to FALSE (ie. when instantiating model objects from client in a loop)
415
-     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
416
-     * @return EE_Base_Class | bool
417
-     */
418
-    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
419
-    {
420
-        $paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
421
-            EE_CORE,
422
-            EE_CLASSES,
423
-            EE_BUSINESS,
424
-        ));
425
-        // retrieve instantiated class
426
-        return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
427
-    }
428
-
429
-
430
-
431
-    /**
432
-     *    loads helper classes - must be singletons
433
-     *
434
-     * @param string $class_name - simple class name ie: price
435
-     * @param mixed  $arguments
436
-     * @param bool   $load_only
437
-     * @return EEH_Base | bool
438
-     */
439
-    public function load_helper($class_name, $arguments = array(), $load_only = true)
440
-    {
441
-        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
442
-        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
443
-        // retrieve instantiated class
444
-        return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
445
-    }
446
-
447
-
448
-
449
-    /**
450
-     *    loads core classes - must be singletons
451
-     *
452
-     * @access    public
453
-     * @param string $class_name - simple class name ie: session
454
-     * @param mixed  $arguments
455
-     * @param bool   $load_only
456
-     * @param bool   $cache      whether to cache the object or not.
457
-     * @return mixed
458
-     */
459
-    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
460
-    {
461
-        $paths = array(
462
-            EE_LIBRARIES,
463
-            EE_LIBRARIES . 'messages' . DS,
464
-            EE_LIBRARIES . 'shortcodes' . DS,
465
-            EE_LIBRARIES . 'qtips' . DS,
466
-            EE_LIBRARIES . 'payment_methods' . DS,
467
-        );
468
-        // retrieve instantiated class
469
-        return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
470
-    }
471
-
472
-
473
-
474
-    /**
475
-     *    loads model classes - must be singletons
476
-     *
477
-     * @param string $class_name - simple class name ie: price
478
-     * @param mixed  $arguments
479
-     * @param bool   $load_only
480
-     * @return EEM_Base | bool
481
-     */
482
-    public function load_model($class_name, $arguments = array(), $load_only = false)
483
-    {
484
-        $paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
485
-            EE_MODELS,
486
-            EE_CORE,
487
-        ));
488
-        // retrieve instantiated class
489
-        return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
490
-    }
491
-
492
-
493
-
494
-    /**
495
-     *    loads model classes - must be singletons
496
-     *
497
-     * @param string $class_name - simple class name ie: price
498
-     * @param mixed  $arguments
499
-     * @param bool   $load_only
500
-     * @return mixed | bool
501
-     */
502
-    public function load_model_class($class_name, $arguments = array(), $load_only = true)
503
-    {
504
-        $paths = array(
505
-            EE_MODELS . 'fields' . DS,
506
-            EE_MODELS . 'helpers' . DS,
507
-            EE_MODELS . 'relations' . DS,
508
-            EE_MODELS . 'strategies' . DS,
509
-        );
510
-        // retrieve instantiated class
511
-        return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
512
-    }
513
-
514
-
515
-
516
-    /**
517
-     * Determines if $model_name is the name of an actual EE model.
518
-     *
519
-     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
520
-     * @return boolean
521
-     */
522
-    public function is_model_name($model_name)
523
-    {
524
-        return isset($this->models[$model_name]) ? true : false;
525
-    }
526
-
527
-
528
-
529
-    /**
530
-     *    generic class loader
531
-     *
532
-     * @param string $path_to_file - directory path to file location, not including filename
533
-     * @param string $file_name    - file name  ie:  my_file.php, including extension
534
-     * @param string $type         - file type - core? class? helper? model?
535
-     * @param mixed  $arguments
536
-     * @param bool   $load_only
537
-     * @return mixed
538
-     */
539
-    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
540
-    {
541
-        // retrieve instantiated class
542
-        return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
543
-    }
544
-
545
-
546
-
547
-    /**
548
-     *    load_addon
549
-     *
550
-     * @param string $path_to_file - directory path to file location, not including filename
551
-     * @param string $class_name   - full class name  ie:  My_Class
552
-     * @param string $type         - file type - core? class? helper? model?
553
-     * @param mixed  $arguments
554
-     * @param bool   $load_only
555
-     * @return EE_Addon
556
-     */
557
-    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
558
-    {
559
-        // retrieve instantiated class
560
-        return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
561
-    }
562
-
563
-
564
-
565
-    /**
566
-     * instantiates, caches, and automatically resolves dependencies
567
-     * for classes that use a Fully Qualified Class Name.
568
-     * if the class is not capable of being loaded using PSR-4 autoloading,
569
-     * then you need to use one of the existing load_*() methods
570
-     * which can resolve the classname and filepath from the passed arguments
571
-     *
572
-     * @param bool|string $class_name   Fully Qualified Class Name
573
-     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
574
-     * @param bool        $cache        whether to cache the instantiated object for reuse
575
-     * @param bool        $from_db      some classes are instantiated from the db
576
-     *                                  and thus call a different method to instantiate
577
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
578
-     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
579
-     * @return mixed                    null = failure to load or instantiate class object.
580
-     *                                  object = class loaded and instantiated successfully.
581
-     *                                  bool = fail or success when $load_only is true
582
-     */
583
-    public function create(
584
-        $class_name = false,
585
-        $arguments = array(),
586
-        $cache = false,
587
-        $from_db = false,
588
-        $load_only = false,
589
-        $addon = false
590
-    ) {
591
-        $class_name = ltrim($class_name, '\\');
592
-        $class_name = $this->_dependency_map->get_alias($class_name);
593
-        if ( ! class_exists($class_name)) {
594
-            // maybe the class is registered with a preceding \
595
-            $class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
596
-            // still doesn't exist ?
597
-            if ( ! class_exists($class_name)) {
598
-                return null;
599
-            }
600
-        }
601
-        // if we're only loading the class and it already exists, then let's just return true immediately
602
-        if ($load_only) {
603
-            return true;
604
-        }
605
-        $addon = $addon ? 'addon' : '';
606
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
607
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
608
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
609
-        if ($this->_cache_on && $cache && ! $load_only) {
610
-            // return object if it's already cached
611
-            $cached_class = $this->_get_cached_class($class_name, $addon);
612
-            if ($cached_class !== null) {
613
-                return $cached_class;
614
-            }
615
-        }
616
-        // instantiate the requested object
617
-        $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
618
-        if ($this->_cache_on && $cache) {
619
-            // save it for later... kinda like gum  { : $
620
-            $this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
621
-        }
622
-        $this->_cache_on = true;
623
-        return $class_obj;
624
-    }
625
-
626
-
627
-
628
-    /**
629
-     * instantiates, caches, and injects dependencies for classes
630
-     *
631
-     * @param array       $file_paths   an array of paths to folders to look in
632
-     * @param string      $class_prefix EE  or EEM or... ???
633
-     * @param bool|string $class_name   $class name
634
-     * @param string      $type         file type - core? class? helper? model?
635
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
636
-     * @param bool        $from_db      some classes are instantiated from the db
637
-     *                                  and thus call a different method to instantiate
638
-     * @param bool        $cache        whether to cache the instantiated object for reuse
639
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
640
-     * @return null|object|bool         null = failure to load or instantiate class object.
641
-     *                                  object = class loaded and instantiated successfully.
642
-     *                                  bool = fail or success when $load_only is true
643
-     */
644
-    protected function _load(
645
-        $file_paths = array(),
646
-        $class_prefix = 'EE_',
647
-        $class_name = false,
648
-        $type = 'class',
649
-        $arguments = array(),
650
-        $from_db = false,
651
-        $cache = true,
652
-        $load_only = false
653
-    ) {
654
-        $class_name = ltrim($class_name, '\\');
655
-        // strip php file extension
656
-        $class_name = str_replace('.php', '', trim($class_name));
657
-        // does the class have a prefix ?
658
-        if ( ! empty($class_prefix) && $class_prefix != 'addon') {
659
-            // make sure $class_prefix is uppercase
660
-            $class_prefix = strtoupper(trim($class_prefix));
661
-            // add class prefix ONCE!!!
662
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
663
-        }
664
-        $class_name = $this->_dependency_map->get_alias($class_name);
665
-        $class_exists = class_exists($class_name);
666
-        // if we're only loading the class and it already exists, then let's just return true immediately
667
-        if ($load_only && $class_exists) {
668
-            return true;
669
-        }
670
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
671
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
672
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
673
-        if ($this->_cache_on && $cache && ! $load_only) {
674
-            // return object if it's already cached
675
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix);
676
-            if ($cached_class !== null) {
677
-                return $cached_class;
678
-            }
679
-        }
680
-        // if the class doesn't already exist.. then we need to try and find the file and load it
681
-        if ( ! $class_exists) {
682
-            // get full path to file
683
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
684
-            // load the file
685
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
686
-            // if loading failed, or we are only loading a file but NOT instantiating an object
687
-            if ( ! $loaded || $load_only) {
688
-                // return boolean if only loading, or null if an object was expected
689
-                return $load_only ? $loaded : null;
690
-            }
691
-        }
692
-        // instantiate the requested object
693
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
694
-        if ($this->_cache_on && $cache) {
695
-            // save it for later... kinda like gum  { : $
696
-            $this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
697
-        }
698
-        $this->_cache_on = true;
699
-        return $class_obj;
700
-    }
701
-
702
-
703
-
704
-
705
-    /**
706
-     * _get_cached_class
707
-     * attempts to find a cached version of the requested class
708
-     * by looking in the following places:
709
-     *        $this->{$class_abbreviation}            ie:    $this->CART
710
-     *        $this->{$class_name}                        ie:    $this->Some_Class
711
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
712
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
713
-     *
714
-     * @access protected
715
-     * @param string $class_name
716
-     * @param string $class_prefix
717
-     * @return mixed
718
-     */
719
-    protected function _get_cached_class($class_name, $class_prefix = '')
720
-    {
721
-        if ($class_name === 'EE_Registry') {
722
-            return $this;
723
-        }
724
-        // have to specify something, but not anything that will conflict
725
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
726
-            ? $this->_class_abbreviations[ $class_name ]
727
-            : 'FANCY_BATMAN_PANTS';
728
-        $class_name = str_replace('\\', '_', $class_name);
729
-        // check if class has already been loaded, and return it if it has been
730
-        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
731
-            return $this->{$class_abbreviation};
732
-        }
733
-        if (isset ($this->{$class_name})) {
734
-            return $this->{$class_name};
735
-        }
736
-        if (isset ($this->LIB->{$class_name})) {
737
-            return $this->LIB->{$class_name};
738
-        }
739
-        if ($class_prefix === 'addon' && isset ($this->addons->{$class_name})) {
740
-            return $this->addons->{$class_name};
741
-        }
742
-        return null;
743
-    }
744
-
745
-
746
-
747
-    /**
748
-     * removes a cached version of the requested class
749
-     *
750
-     * @param string $class_name
751
-     * @param boolean $addon
752
-     * @return boolean
753
-     */
754
-    public function clear_cached_class($class_name, $addon = false)
755
-    {
756
-        // have to specify something, but not anything that will conflict
757
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
758
-            ? $this->_class_abbreviations[ $class_name ]
759
-            : 'FANCY_BATMAN_PANTS';
760
-        $class_name = str_replace('\\', '_', $class_name);
761
-        // check if class has already been loaded, and return it if it has been
762
-        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
763
-            $this->{$class_abbreviation} = null;
764
-            return true;
765
-        }
766
-        if (isset($this->{$class_name})) {
767
-            $this->{$class_name} = null;
768
-            return true;
769
-        }
770
-        if (isset($this->LIB->{$class_name})) {
771
-            unset($this->LIB->{$class_name});
772
-            return true;
773
-        }
774
-        if ($addon && isset($this->addons->{$class_name})) {
775
-            unset($this->addons->{$class_name});
776
-            return true;
777
-        }
778
-        return false;
779
-    }
780
-
781
-
782
-    /**
783
-     * _resolve_path
784
-     * attempts to find a full valid filepath for the requested class.
785
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
786
-     * then returns that path if the target file has been found and is readable
787
-     *
788
-     * @access protected
789
-     * @param string $class_name
790
-     * @param string $type
791
-     * @param array  $file_paths
792
-     * @return string | bool
793
-     */
794
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
795
-    {
796
-        // make sure $file_paths is an array
797
-        $file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
798
-        // cycle thru paths
799
-        foreach ($file_paths as $key => $file_path) {
800
-            // convert all separators to proper DS, if no filepath, then use EE_CLASSES
801
-            $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
802
-            // prep file type
803
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
804
-            // build full file path
805
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
806
-            //does the file exist and can be read ?
807
-            if (is_readable($file_paths[$key])) {
808
-                return $file_paths[$key];
809
-            }
810
-        }
811
-        return false;
812
-    }
813
-
814
-
815
-
816
-    /**
817
-     * _require_file
818
-     * basically just performs a require_once()
819
-     * but with some error handling
820
-     *
821
-     * @access protected
822
-     * @param  string $path
823
-     * @param  string $class_name
824
-     * @param  string $type
825
-     * @param  array  $file_paths
826
-     * @return boolean
827
-     * @throws \EE_Error
828
-     */
829
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
830
-    {
831
-        // don't give up! you gotta...
832
-        try {
833
-            //does the file exist and can it be read ?
834
-            if ( ! $path) {
835
-                // so sorry, can't find the file
836
-                throw new EE_Error (
837
-                    sprintf(
838
-                        __('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
839
-                        trim($type, '.'),
840
-                        $class_name,
841
-                        '<br />' . implode(',<br />', $file_paths)
842
-                    )
843
-                );
844
-            }
845
-            // get the file
846
-            require_once($path);
847
-            // if the class isn't already declared somewhere
848
-            if (class_exists($class_name, false) === false) {
849
-                // so sorry, not a class
850
-                throw new EE_Error(
851
-                    sprintf(
852
-                        __('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
853
-                        $type,
854
-                        $path,
855
-                        $class_name
856
-                    )
857
-                );
858
-            }
859
-        } catch (EE_Error $e) {
860
-            $e->get_error();
861
-            return false;
862
-        }
863
-        return true;
864
-    }
865
-
866
-
867
-
868
-    /**
869
-     * _create_object
870
-     * Attempts to instantiate the requested class via any of the
871
-     * commonly used instantiation methods employed throughout EE.
872
-     * The priority for instantiation is as follows:
873
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
874
-     *        - model objects via their 'new_instance_from_db' method
875
-     *        - model objects via their 'new_instance' method
876
-     *        - "singleton" classes" via their 'instance' method
877
-     *    - standard instantiable classes via their __constructor
878
-     * Prior to instantiation, if the classname exists in the dependency_map,
879
-     * then the constructor for the requested class will be examined to determine
880
-     * if any dependencies exist, and if they can be injected.
881
-     * If so, then those classes will be added to the array of arguments passed to the constructor
882
-     *
883
-     * @access protected
884
-     * @param string $class_name
885
-     * @param array  $arguments
886
-     * @param string $type
887
-     * @param bool   $from_db
888
-     * @return null | object
889
-     * @throws \EE_Error
890
-     */
891
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
892
-    {
893
-        $class_obj = null;
894
-        $instantiation_mode = '0) none';
895
-        // don't give up! you gotta...
896
-        try {
897
-            // create reflection
898
-            $reflector = $this->get_ReflectionClass($class_name);
899
-            // make sure arguments are an array
900
-            $arguments = is_array($arguments) ? $arguments : array($arguments);
901
-            // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
902
-            // else wrap it in an additional array so that it doesn't get split into multiple parameters
903
-            $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
904
-                ? $arguments
905
-                : array($arguments);
906
-            // attempt to inject dependencies ?
907
-            if ($this->_dependency_map->has($class_name)) {
908
-                $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
909
-            }
910
-            // instantiate the class if possible
911
-            if ($reflector->isAbstract()) {
912
-                // nothing to instantiate, loading file was enough
913
-                // does not throw an exception so $instantiation_mode is unused
914
-                // $instantiation_mode = "1) no constructor abstract class";
915
-                $class_obj = true;
916
-            } else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
917
-                // no constructor = static methods only... nothing to instantiate, loading file was enough
918
-                $instantiation_mode = "2) no constructor but instantiable";
919
-                $class_obj = $reflector->newInstance();
920
-            } else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
921
-                $instantiation_mode = "3) new_instance_from_db()";
922
-                $class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
923
-            } else if (method_exists($class_name, 'new_instance')) {
924
-                $instantiation_mode = "4) new_instance()";
925
-                $class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
926
-            } else if (method_exists($class_name, 'instance')) {
927
-                $instantiation_mode = "5) instance()";
928
-                $class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
929
-            } else if ($reflector->isInstantiable()) {
930
-                $instantiation_mode = "6) constructor";
931
-                $class_obj = $reflector->newInstanceArgs($arguments);
932
-            } else {
933
-                // heh ? something's not right !
934
-                throw new EE_Error(
935
-                    sprintf(
936
-                        __('The %s file %s could not be instantiated.', 'event_espresso'),
937
-                        $type,
938
-                        $class_name
939
-                    )
940
-                );
941
-            }
942
-        } catch (Exception $e) {
943
-            if ( ! $e instanceof EE_Error) {
944
-                $e = new EE_Error(
945
-                    sprintf(
946
-                        __('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
947
-                        $class_name,
948
-                        '<br />',
949
-                        $e->getMessage(),
950
-                        $instantiation_mode
951
-                    )
952
-                );
953
-            }
954
-            $e->get_error();
955
-        }
956
-        return $class_obj;
957
-    }
958
-
959
-
960
-
961
-    /**
962
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
963
-     * @param array $array
964
-     * @return bool
965
-     */
966
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
967
-    {
968
-        return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
969
-    }
970
-
971
-
972
-
973
-    /**
974
-     * getReflectionClass
975
-     * checks if a ReflectionClass object has already been generated for a class
976
-     * and returns that instead of creating a new one
977
-     *
978
-     * @access public
979
-     * @param string $class_name
980
-     * @return ReflectionClass
981
-     */
982
-    public function get_ReflectionClass($class_name)
983
-    {
984
-        if (
985
-            ! isset($this->_reflectors[$class_name])
986
-            || ! $this->_reflectors[$class_name] instanceof ReflectionClass
987
-        ) {
988
-            $this->_reflectors[$class_name] = new ReflectionClass($class_name);
989
-        }
990
-        return $this->_reflectors[$class_name];
991
-    }
992
-
993
-
994
-
995
-    /**
996
-     * _resolve_dependencies
997
-     * examines the constructor for the requested class to determine
998
-     * if any dependencies exist, and if they can be injected.
999
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1000
-     * PLZ NOTE: this is achieved by type hinting the constructor params
1001
-     * For example:
1002
-     *        if attempting to load a class "Foo" with the following constructor:
1003
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
1004
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
1005
-     *        but only IF they are NOT already present in the incoming arguments array,
1006
-     *        and the correct classes can be loaded
1007
-     *
1008
-     * @access protected
1009
-     * @param ReflectionClass $reflector
1010
-     * @param string          $class_name
1011
-     * @param array           $arguments
1012
-     * @return array
1013
-     * @throws \ReflectionException
1014
-     */
1015
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
1016
-    {
1017
-        // let's examine the constructor
1018
-        $constructor = $reflector->getConstructor();
1019
-        // whu? huh? nothing?
1020
-        if ( ! $constructor) {
1021
-            return $arguments;
1022
-        }
1023
-        // get constructor parameters
1024
-        $params = $constructor->getParameters();
1025
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1026
-        $argument_keys = array_keys($arguments);
1027
-        // now loop thru all of the constructors expected parameters
1028
-        foreach ($params as $index => $param) {
1029
-            // is this a dependency for a specific class ?
1030
-            $param_class = $param->getClass() ? $param->getClass()->name : null;
1031
-            // BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1032
-            $param_class = $this->_dependency_map->has_alias($param_class, $class_name)
1033
-                ? $this->_dependency_map->get_alias($param_class, $class_name)
1034
-                : $param_class;
1035
-            if (
1036
-                // param is not even a class
1037
-                empty($param_class)
1038
-                // and something already exists in the incoming arguments for this param
1039
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1040
-            ) {
1041
-                // so let's skip this argument and move on to the next
1042
-                continue;
1043
-            }
1044
-            if (
1045
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1046
-                ! empty($param_class)
1047
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1048
-                && $arguments[$argument_keys[$index]] instanceof $param_class
1049
-            ) {
1050
-                // skip this argument and move on to the next
1051
-                continue;
1052
-            }
1053
-            if (
1054
-                // parameter is type hinted as a class, and should be injected
1055
-                ! empty($param_class)
1056
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1057
-            ) {
1058
-                $arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1059
-            } else {
1060
-                try {
1061
-                    $arguments[$index] = $param->getDefaultValue();
1062
-                } catch (ReflectionException $e) {
1063
-                    throw new ReflectionException(
1064
-                        sprintf(
1065
-                            __('%1$s for parameter "$%2$s"', 'event_espresso'),
1066
-                            $e->getMessage(),
1067
-                            $param->getName()
1068
-                        )
1069
-                    );
1070
-                }
1071
-            }
1072
-        }
1073
-        return $arguments;
1074
-    }
1075
-
1076
-
1077
-
1078
-    /**
1079
-     * @access protected
1080
-     * @param string $class_name
1081
-     * @param string $param_class
1082
-     * @param array  $arguments
1083
-     * @param mixed  $index
1084
-     * @return array
1085
-     */
1086
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1087
-    {
1088
-        $dependency = null;
1089
-        // should dependency be loaded from cache ?
1090
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1091
-                    !== EE_Dependency_Map::load_new_object
1092
-            ? true
1093
-            : false;
1094
-        // we might have a dependency...
1095
-        // let's MAYBE try and find it in our cache if that's what's been requested
1096
-        $cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1097
-        // and grab it if it exists
1098
-        if ($cached_class instanceof $param_class) {
1099
-            $dependency = $cached_class;
1100
-        } else if ($param_class !== $class_name) {
1101
-            // obtain the loader method from the dependency map
1102
-            $loader = $this->_dependency_map->class_loader($param_class);
1103
-            // is loader a custom closure ?
1104
-            if ($loader instanceof Closure) {
1105
-                $dependency = $loader();
1106
-            } else {
1107
-                // set the cache on property for the recursive loading call
1108
-                $this->_cache_on = $cache_on;
1109
-                // if not, then let's try and load it via the registry
1110
-                if ($loader && method_exists($this, $loader)) {
1111
-                    $dependency = $this->{$loader}($param_class);
1112
-                } else {
1113
-                    $dependency = $this->create($param_class, array(), $cache_on);
1114
-                }
1115
-            }
1116
-        }
1117
-        // did we successfully find the correct dependency ?
1118
-        if ($dependency instanceof $param_class) {
1119
-            // then let's inject it into the incoming array of arguments at the correct location
1120
-            if (isset($argument_keys[$index])) {
1121
-                $arguments[$argument_keys[$index]] = $dependency;
1122
-            } else {
1123
-                $arguments[$index] = $dependency;
1124
-            }
1125
-        }
1126
-        return $arguments;
1127
-    }
1128
-
1129
-
1130
-
1131
-    /**
1132
-     * _set_cached_class
1133
-     * attempts to cache the instantiated class locally
1134
-     * in one of the following places, in the following order:
1135
-     *        $this->{class_abbreviation}   ie:    $this->CART
1136
-     *        $this->{$class_name}          ie:    $this->Some_Class
1137
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1138
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1139
-     *
1140
-     * @access protected
1141
-     * @param object $class_obj
1142
-     * @param string $class_name
1143
-     * @param string $class_prefix
1144
-     * @param bool   $from_db
1145
-     * @return void
1146
-     */
1147
-    protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1148
-    {
1149
-        if ($class_name === 'EE_Registry' || empty($class_obj)) {
1150
-            return;
1151
-        }
1152
-        // return newly instantiated class
1153
-        if (isset($this->_class_abbreviations[$class_name])) {
1154
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
1155
-            $this->{$class_abbreviation} = $class_obj;
1156
-            return;
1157
-        }
1158
-        $class_name = str_replace('\\', '_', $class_name);
1159
-        if (property_exists($this, $class_name)) {
1160
-            $this->{$class_name} = $class_obj;
1161
-            return;
1162
-        }
1163
-        if ($class_prefix === 'addon') {
1164
-            $this->addons->{$class_name} = $class_obj;
1165
-            return;
1166
-        }
1167
-        if ( ! $from_db) {
1168
-            $this->LIB->{$class_name} = $class_obj;
1169
-        }
1170
-    }
1171
-
1172
-
1173
-
1174
-    /**
1175
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1176
-     *
1177
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1178
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1179
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1180
-     * @param array  $arguments
1181
-     * @return object
1182
-     */
1183
-    public static function factory($classname, $arguments = array())
1184
-    {
1185
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1186
-        if ($loader instanceof Closure) {
1187
-            return $loader($arguments);
1188
-        }
1189
-        if (method_exists(EE_Registry::instance(), $loader)) {
1190
-            return EE_Registry::instance()->{$loader}($classname, $arguments);
1191
-        }
1192
-        return null;
1193
-    }
1194
-
1195
-
1196
-
1197
-    /**
1198
-     * Gets the addon by its name/slug (not classname. For that, just
1199
-     * use the classname as the property name on EE_Config::instance()->addons)
1200
-     *
1201
-     * @param string $name
1202
-     * @return EE_Addon
1203
-     */
1204
-    public function get_addon_by_name($name)
1205
-    {
1206
-        foreach ($this->addons as $addon) {
1207
-            if ($addon->name() == $name) {
1208
-                return $addon;
1209
-            }
1210
-        }
1211
-        return null;
1212
-    }
1213
-
1214
-
1215
-
1216
-    /**
1217
-     * Gets an array of all the registered addons, where the keys are their names. (ie, what each returns for their name() function) They're already available on EE_Config::instance()->addons as properties, where each property's name is
1218
-     * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1219
-     *
1220
-     * @return EE_Addon[] where the KEYS are the addon's name()
1221
-     */
1222
-    public function get_addons_by_name()
1223
-    {
1224
-        $addons = array();
1225
-        foreach ($this->addons as $addon) {
1226
-            $addons[$addon->name()] = $addon;
1227
-        }
1228
-        return $addons;
1229
-    }
1230
-
1231
-
1232
-
1233
-    /**
1234
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1235
-     * a stale copy of it around
1236
-     *
1237
-     * @param string $model_name
1238
-     * @return \EEM_Base
1239
-     * @throws \EE_Error
1240
-     */
1241
-    public function reset_model($model_name)
1242
-    {
1243
-        $model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1244
-        if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1245
-            return null;
1246
-        }
1247
-        //get that model reset it and make sure we nuke the old reference to it
1248
-        if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1249
-            $this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1250
-        } else {
1251
-            throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1252
-        }
1253
-        return $this->LIB->{$model_class_name};
1254
-    }
1255
-
1256
-
1257
-
1258
-    /**
1259
-     * Resets the registry.
1260
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1261
-     * is used in a multisite install.  Here is a list of things that are NOT reset.
1262
-     * - $_dependency_map
1263
-     * - $_class_abbreviations
1264
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1265
-     * - $REQ:  Still on the same request so no need to change.
1266
-     * - $CAP: There is no site specific state in the EE_Capability class.
1267
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1268
-     *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1269
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1270
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1271
-     *             switch or on the restore.
1272
-     * - $modules
1273
-     * - $shortcodes
1274
-     * - $widgets
1275
-     *
1276
-     * @param boolean $hard             whether to reset data in the database too, or just refresh
1277
-     *                                  the Registry to its state at the beginning of the request
1278
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1279
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1280
-     *                                  currently reinstantiate the singletons at the moment)
1281
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1282
-     *                                  code instead can just change the model context to a different blog id if necessary
1283
-     * @return EE_Registry
1284
-     */
1285
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1286
-    {
1287
-        $instance = self::instance();
1288
-        $instance->_cache_on = true;
1289
-        // reset some "special" classes
1290
-        EEH_Activation::reset();
1291
-        $instance->CFG = $instance->CFG->reset($hard, $reinstantiate);
1292
-        $instance->CART = null;
1293
-        $instance->MRM = null;
1294
-        $instance->AssetsRegistry = null;
1295
-        $instance->AssetsRegistry = $instance->create('EventEspresso\core\services\assets\Registry');
1296
-        //messages reset
1297
-        EED_Messages::reset();
1298
-        //handle of objects cached on LIB
1299
-        foreach (array('LIB', 'modules', 'shortcodes') as $cache) {
1300
-            foreach ($instance->{$cache} as $class_name => $class) {
1301
-                if (EE_Registry::_reset_and_unset_object($class, $reset_models)) {
1302
-                    unset($instance->{$cache}->{$class_name});
1303
-                }
1304
-            }
1305
-        }
1306
-        return $instance;
1307
-    }
1308
-
1309
-
1310
-
1311
-    /**
1312
-     * if passed object implements ResettableInterface, then call it's reset() method
1313
-     * if passed object implements InterminableInterface, then return false,
1314
-     * to indicate that it should NOT be cleared from the Registry cache
1315
-     *
1316
-     * @param      $object
1317
-     * @param bool $reset_models
1318
-     * @return bool returns true if cached object should be unset
1319
-     */
1320
-    private static function _reset_and_unset_object($object, $reset_models)
1321
-    {
1322
-        static $count = 0;
1323
-        $count++;
1324
-        if ($object instanceof ResettableInterface) {
1325
-            if ($object instanceof EEM_Base) {
1326
-                if ($reset_models) {
1327
-                    $object->reset();
1328
-                    return true;
1329
-                }
1330
-                return false;
1331
-            }
1332
-            $object->reset();
1333
-            return true;
1334
-        }
1335
-        if ( ! $object instanceof InterminableInterface) {
1336
-            return true;
1337
-        }
1338
-        return false;
1339
-    }
1340
-
1341
-
1342
-
1343
-    /**
1344
-     * @override magic methods
1345
-     * @return void
1346
-     */
1347
-    public final function __destruct()
1348
-    {
1349
-    }
1350
-
1351
-
1352
-
1353
-    /**
1354
-     * @param $a
1355
-     * @param $b
1356
-     */
1357
-    public final function __call($a, $b)
1358
-    {
1359
-    }
1360
-
1361
-
1362
-
1363
-    /**
1364
-     * @param $a
1365
-     */
1366
-    public final function __get($a)
1367
-    {
1368
-    }
1369
-
1370
-
1371
-
1372
-    /**
1373
-     * @param $a
1374
-     * @param $b
1375
-     */
1376
-    public final function __set($a, $b)
1377
-    {
1378
-    }
1379
-
1380
-
1381
-
1382
-    /**
1383
-     * @param $a
1384
-     */
1385
-    public final function __isset($a)
1386
-    {
1387
-    }
22
+	/**
23
+	 *    EE_Registry Object
24
+	 *
25
+	 * @var EE_Registry $_instance
26
+	 * @access    private
27
+	 */
28
+	private static $_instance = null;
29
+
30
+	/**
31
+	 * @var EE_Dependency_Map $_dependency_map
32
+	 * @access    protected
33
+	 */
34
+	protected $_dependency_map = null;
35
+
36
+	/**
37
+	 * @var array $_class_abbreviations
38
+	 * @access    protected
39
+	 */
40
+	protected $_class_abbreviations = array();
41
+
42
+	/**
43
+	 * @access public
44
+	 * @var \EventEspresso\core\services\commands\CommandBusInterface $BUS
45
+	 */
46
+	public $BUS;
47
+
48
+	/**
49
+	 *    EE_Cart Object
50
+	 *
51
+	 * @access    public
52
+	 * @var    EE_Cart $CART
53
+	 */
54
+	public $CART = null;
55
+
56
+	/**
57
+	 *    EE_Config Object
58
+	 *
59
+	 * @access    public
60
+	 * @var    EE_Config $CFG
61
+	 */
62
+	public $CFG = null;
63
+
64
+	/**
65
+	 * EE_Network_Config Object
66
+	 *
67
+	 * @access public
68
+	 * @var EE_Network_Config $NET_CFG
69
+	 */
70
+	public $NET_CFG = null;
71
+
72
+	/**
73
+	 *    StdClass object for storing library classes in
74
+	 *
75
+	 * @public LIB
76
+	 * @var StdClass $LIB
77
+	 */
78
+	public $LIB = null;
79
+
80
+	/**
81
+	 *    EE_Request_Handler Object
82
+	 *
83
+	 * @access    public
84
+	 * @var    EE_Request_Handler $REQ
85
+	 */
86
+	public $REQ = null;
87
+
88
+	/**
89
+	 *    EE_Session Object
90
+	 *
91
+	 * @access    public
92
+	 * @var    EE_Session $SSN
93
+	 */
94
+	public $SSN = null;
95
+
96
+	/**
97
+	 * holds the ee capabilities object.
98
+	 *
99
+	 * @since 4.5.0
100
+	 * @var EE_Capabilities
101
+	 */
102
+	public $CAP = null;
103
+
104
+	/**
105
+	 * holds the EE_Message_Resource_Manager object.
106
+	 *
107
+	 * @since 4.9.0
108
+	 * @var EE_Message_Resource_Manager
109
+	 */
110
+	public $MRM = null;
111
+
112
+
113
+	/**
114
+	 * Holds the Assets Registry instance
115
+	 * @var Registry
116
+	 */
117
+	public $AssetsRegistry = null;
118
+
119
+	/**
120
+	 *    $addons - StdClass object for holding addons which have registered themselves to work with EE core
121
+	 *
122
+	 * @access    public
123
+	 * @var    EE_Addon[]
124
+	 */
125
+	public $addons = null;
126
+
127
+	/**
128
+	 *    $models
129
+	 * @access    public
130
+	 * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
131
+	 */
132
+	public $models = array();
133
+
134
+	/**
135
+	 *    $modules
136
+	 * @access    public
137
+	 * @var    EED_Module[] $modules
138
+	 */
139
+	public $modules = null;
140
+
141
+	/**
142
+	 *    $shortcodes
143
+	 * @access    public
144
+	 * @var    EES_Shortcode[] $shortcodes
145
+	 */
146
+	public $shortcodes = null;
147
+
148
+	/**
149
+	 *    $widgets
150
+	 * @access    public
151
+	 * @var    WP_Widget[] $widgets
152
+	 */
153
+	public $widgets = null;
154
+
155
+	/**
156
+	 * $non_abstract_db_models
157
+	 * @access public
158
+	 * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
159
+	 * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
160
+	 * Keys are model "short names" (eg "Event") as used in model relations, and values are
161
+	 * classnames (eg "EEM_Event")
162
+	 */
163
+	public $non_abstract_db_models = array();
164
+
165
+
166
+	/**
167
+	 *    $i18n_js_strings - internationalization for JS strings
168
+	 *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
169
+	 *    in js file:  var translatedString = eei18n.string_key;
170
+	 *
171
+	 * @access    public
172
+	 * @var    array
173
+	 */
174
+	public static $i18n_js_strings = array();
175
+
176
+
177
+	/**
178
+	 *    $main_file - path to espresso.php
179
+	 *
180
+	 * @access    public
181
+	 * @var    array
182
+	 */
183
+	public $main_file;
184
+
185
+	/**
186
+	 * array of ReflectionClass objects where the key is the class name
187
+	 *
188
+	 * @access    public
189
+	 * @var ReflectionClass[]
190
+	 */
191
+	public $_reflectors;
192
+
193
+	/**
194
+	 * boolean flag to indicate whether or not to load/save dependencies from/to the cache
195
+	 *
196
+	 * @access    protected
197
+	 * @var boolean $_cache_on
198
+	 */
199
+	protected $_cache_on = true;
200
+
201
+
202
+
203
+	/**
204
+	 * @singleton method used to instantiate class object
205
+	 * @access    public
206
+	 * @param  \EE_Dependency_Map $dependency_map
207
+	 * @return \EE_Registry instance
208
+	 */
209
+	public static function instance(\EE_Dependency_Map $dependency_map = null)
210
+	{
211
+		// check if class object is instantiated
212
+		if ( ! self::$_instance instanceof EE_Registry) {
213
+			self::$_instance = new EE_Registry($dependency_map);
214
+		}
215
+		return self::$_instance;
216
+	}
217
+
218
+
219
+
220
+	/**
221
+	 *protected constructor to prevent direct creation
222
+	 *
223
+	 * @Constructor
224
+	 * @access protected
225
+	 * @param  \EE_Dependency_Map $dependency_map
226
+	 */
227
+	protected function __construct(\EE_Dependency_Map $dependency_map)
228
+	{
229
+		$this->_dependency_map = $dependency_map;
230
+		$this->LIB = new stdClass();
231
+		$this->addons = new stdClass();
232
+		$this->modules = new stdClass();
233
+		$this->shortcodes = new stdClass();
234
+		$this->widgets = new stdClass();
235
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
236
+	}
237
+
238
+
239
+
240
+	/**
241
+	 * initialize
242
+	 */
243
+	public function initialize()
244
+	{
245
+		$this->_class_abbreviations = apply_filters(
246
+			'FHEE__EE_Registry____construct___class_abbreviations',
247
+			array(
248
+				'EE_Config'                                       => 'CFG',
249
+				'EE_Session'                                      => 'SSN',
250
+				'EE_Capabilities'                                 => 'CAP',
251
+				'EE_Cart'                                         => 'CART',
252
+				'EE_Network_Config'                               => 'NET_CFG',
253
+				'EE_Request_Handler'                              => 'REQ',
254
+				'EE_Message_Resource_Manager'                     => 'MRM',
255
+				'EventEspresso\core\services\commands\CommandBus' => 'BUS',
256
+				'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
257
+			)
258
+		);
259
+		$this->load_core('Base', array(), true);
260
+		// add our request and response objects to the cache
261
+		$request_loader = $this->_dependency_map->class_loader('EE_Request');
262
+		$this->_set_cached_class(
263
+			$request_loader(),
264
+			'EE_Request'
265
+		);
266
+		$response_loader = $this->_dependency_map->class_loader('EE_Response');
267
+		$this->_set_cached_class(
268
+			$response_loader(),
269
+			'EE_Response'
270
+		);
271
+		add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
272
+	}
273
+
274
+
275
+
276
+	/**
277
+	 *    init
278
+	 *
279
+	 * @access    public
280
+	 * @return    void
281
+	 */
282
+	public function init()
283
+	{
284
+		// Get current page protocol
285
+		$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
286
+		// Output admin-ajax.php URL with same protocol as current page
287
+		self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
288
+		self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
289
+	}
290
+
291
+
292
+
293
+	/**
294
+	 * localize_i18n_js_strings
295
+	 *
296
+	 * @return string
297
+	 */
298
+	public static function localize_i18n_js_strings()
299
+	{
300
+		$i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
301
+		foreach ($i18n_js_strings as $key => $value) {
302
+			if (is_scalar($value)) {
303
+				$i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
304
+			}
305
+		}
306
+		return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
307
+	}
308
+
309
+
310
+
311
+	/**
312
+	 * @param mixed string | EED_Module $module
313
+	 */
314
+	public function add_module($module)
315
+	{
316
+		if ($module instanceof EED_Module) {
317
+			$module_class = get_class($module);
318
+			$this->modules->{$module_class} = $module;
319
+		} else {
320
+			if ( ! class_exists('EE_Module_Request_Router')) {
321
+				$this->load_core('Module_Request_Router');
322
+			}
323
+			$this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
324
+		}
325
+	}
326
+
327
+
328
+
329
+	/**
330
+	 * @param string $module_name
331
+	 * @return mixed EED_Module | NULL
332
+	 */
333
+	public function get_module($module_name = '')
334
+	{
335
+		return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
336
+	}
337
+
338
+
339
+
340
+	/**
341
+	 *    loads core classes - must be singletons
342
+	 *
343
+	 * @access    public
344
+	 * @param string $class_name - simple class name ie: session
345
+	 * @param mixed  $arguments
346
+	 * @param bool   $load_only
347
+	 * @return mixed
348
+	 */
349
+	public function load_core($class_name, $arguments = array(), $load_only = false)
350
+	{
351
+		$core_paths = apply_filters(
352
+			'FHEE__EE_Registry__load_core__core_paths',
353
+			array(
354
+				EE_CORE,
355
+				EE_ADMIN,
356
+				EE_CPTS,
357
+				EE_CORE . 'data_migration_scripts' . DS,
358
+				EE_CORE . 'capabilities' . DS,
359
+				EE_CORE . 'request_stack' . DS,
360
+				EE_CORE . 'middleware' . DS,
361
+			)
362
+		);
363
+		// retrieve instantiated class
364
+		return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
365
+	}
366
+
367
+
368
+
369
+	/**
370
+	 *    loads service classes
371
+	 *
372
+	 * @access    public
373
+	 * @param string $class_name - simple class name ie: session
374
+	 * @param mixed  $arguments
375
+	 * @param bool   $load_only
376
+	 * @return mixed
377
+	 */
378
+	public function load_service($class_name, $arguments = array(), $load_only = false)
379
+	{
380
+		$service_paths = apply_filters(
381
+			'FHEE__EE_Registry__load_service__service_paths',
382
+			array(
383
+				EE_CORE . 'services' . DS,
384
+			)
385
+		);
386
+		// retrieve instantiated class
387
+		return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
388
+	}
389
+
390
+
391
+
392
+	/**
393
+	 *    loads data_migration_scripts
394
+	 *
395
+	 * @access    public
396
+	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
397
+	 * @param mixed  $arguments
398
+	 * @return EE_Data_Migration_Script_Base|mixed
399
+	 */
400
+	public function load_dms($class_name, $arguments = array())
401
+	{
402
+		// retrieve instantiated class
403
+		return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
404
+	}
405
+
406
+
407
+
408
+	/**
409
+	 *    loads object creating classes - must be singletons
410
+	 *
411
+	 * @param string $class_name - simple class name ie: attendee
412
+	 * @param mixed  $arguments  - an array of arguments to pass to the class
413
+	 * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
414
+	 * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then set this to FALSE (ie. when instantiating model objects from client in a loop)
415
+	 * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
416
+	 * @return EE_Base_Class | bool
417
+	 */
418
+	public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
419
+	{
420
+		$paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
421
+			EE_CORE,
422
+			EE_CLASSES,
423
+			EE_BUSINESS,
424
+		));
425
+		// retrieve instantiated class
426
+		return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
427
+	}
428
+
429
+
430
+
431
+	/**
432
+	 *    loads helper classes - must be singletons
433
+	 *
434
+	 * @param string $class_name - simple class name ie: price
435
+	 * @param mixed  $arguments
436
+	 * @param bool   $load_only
437
+	 * @return EEH_Base | bool
438
+	 */
439
+	public function load_helper($class_name, $arguments = array(), $load_only = true)
440
+	{
441
+		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
442
+		$helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
443
+		// retrieve instantiated class
444
+		return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
445
+	}
446
+
447
+
448
+
449
+	/**
450
+	 *    loads core classes - must be singletons
451
+	 *
452
+	 * @access    public
453
+	 * @param string $class_name - simple class name ie: session
454
+	 * @param mixed  $arguments
455
+	 * @param bool   $load_only
456
+	 * @param bool   $cache      whether to cache the object or not.
457
+	 * @return mixed
458
+	 */
459
+	public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
460
+	{
461
+		$paths = array(
462
+			EE_LIBRARIES,
463
+			EE_LIBRARIES . 'messages' . DS,
464
+			EE_LIBRARIES . 'shortcodes' . DS,
465
+			EE_LIBRARIES . 'qtips' . DS,
466
+			EE_LIBRARIES . 'payment_methods' . DS,
467
+		);
468
+		// retrieve instantiated class
469
+		return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
470
+	}
471
+
472
+
473
+
474
+	/**
475
+	 *    loads model classes - must be singletons
476
+	 *
477
+	 * @param string $class_name - simple class name ie: price
478
+	 * @param mixed  $arguments
479
+	 * @param bool   $load_only
480
+	 * @return EEM_Base | bool
481
+	 */
482
+	public function load_model($class_name, $arguments = array(), $load_only = false)
483
+	{
484
+		$paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
485
+			EE_MODELS,
486
+			EE_CORE,
487
+		));
488
+		// retrieve instantiated class
489
+		return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
490
+	}
491
+
492
+
493
+
494
+	/**
495
+	 *    loads model classes - must be singletons
496
+	 *
497
+	 * @param string $class_name - simple class name ie: price
498
+	 * @param mixed  $arguments
499
+	 * @param bool   $load_only
500
+	 * @return mixed | bool
501
+	 */
502
+	public function load_model_class($class_name, $arguments = array(), $load_only = true)
503
+	{
504
+		$paths = array(
505
+			EE_MODELS . 'fields' . DS,
506
+			EE_MODELS . 'helpers' . DS,
507
+			EE_MODELS . 'relations' . DS,
508
+			EE_MODELS . 'strategies' . DS,
509
+		);
510
+		// retrieve instantiated class
511
+		return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
512
+	}
513
+
514
+
515
+
516
+	/**
517
+	 * Determines if $model_name is the name of an actual EE model.
518
+	 *
519
+	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
520
+	 * @return boolean
521
+	 */
522
+	public function is_model_name($model_name)
523
+	{
524
+		return isset($this->models[$model_name]) ? true : false;
525
+	}
526
+
527
+
528
+
529
+	/**
530
+	 *    generic class loader
531
+	 *
532
+	 * @param string $path_to_file - directory path to file location, not including filename
533
+	 * @param string $file_name    - file name  ie:  my_file.php, including extension
534
+	 * @param string $type         - file type - core? class? helper? model?
535
+	 * @param mixed  $arguments
536
+	 * @param bool   $load_only
537
+	 * @return mixed
538
+	 */
539
+	public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
540
+	{
541
+		// retrieve instantiated class
542
+		return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
543
+	}
544
+
545
+
546
+
547
+	/**
548
+	 *    load_addon
549
+	 *
550
+	 * @param string $path_to_file - directory path to file location, not including filename
551
+	 * @param string $class_name   - full class name  ie:  My_Class
552
+	 * @param string $type         - file type - core? class? helper? model?
553
+	 * @param mixed  $arguments
554
+	 * @param bool   $load_only
555
+	 * @return EE_Addon
556
+	 */
557
+	public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
558
+	{
559
+		// retrieve instantiated class
560
+		return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
561
+	}
562
+
563
+
564
+
565
+	/**
566
+	 * instantiates, caches, and automatically resolves dependencies
567
+	 * for classes that use a Fully Qualified Class Name.
568
+	 * if the class is not capable of being loaded using PSR-4 autoloading,
569
+	 * then you need to use one of the existing load_*() methods
570
+	 * which can resolve the classname and filepath from the passed arguments
571
+	 *
572
+	 * @param bool|string $class_name   Fully Qualified Class Name
573
+	 * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
574
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
575
+	 * @param bool        $from_db      some classes are instantiated from the db
576
+	 *                                  and thus call a different method to instantiate
577
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
578
+	 * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
579
+	 * @return mixed                    null = failure to load or instantiate class object.
580
+	 *                                  object = class loaded and instantiated successfully.
581
+	 *                                  bool = fail or success when $load_only is true
582
+	 */
583
+	public function create(
584
+		$class_name = false,
585
+		$arguments = array(),
586
+		$cache = false,
587
+		$from_db = false,
588
+		$load_only = false,
589
+		$addon = false
590
+	) {
591
+		$class_name = ltrim($class_name, '\\');
592
+		$class_name = $this->_dependency_map->get_alias($class_name);
593
+		if ( ! class_exists($class_name)) {
594
+			// maybe the class is registered with a preceding \
595
+			$class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
596
+			// still doesn't exist ?
597
+			if ( ! class_exists($class_name)) {
598
+				return null;
599
+			}
600
+		}
601
+		// if we're only loading the class and it already exists, then let's just return true immediately
602
+		if ($load_only) {
603
+			return true;
604
+		}
605
+		$addon = $addon ? 'addon' : '';
606
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
607
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
608
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
609
+		if ($this->_cache_on && $cache && ! $load_only) {
610
+			// return object if it's already cached
611
+			$cached_class = $this->_get_cached_class($class_name, $addon);
612
+			if ($cached_class !== null) {
613
+				return $cached_class;
614
+			}
615
+		}
616
+		// instantiate the requested object
617
+		$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
618
+		if ($this->_cache_on && $cache) {
619
+			// save it for later... kinda like gum  { : $
620
+			$this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
621
+		}
622
+		$this->_cache_on = true;
623
+		return $class_obj;
624
+	}
625
+
626
+
627
+
628
+	/**
629
+	 * instantiates, caches, and injects dependencies for classes
630
+	 *
631
+	 * @param array       $file_paths   an array of paths to folders to look in
632
+	 * @param string      $class_prefix EE  or EEM or... ???
633
+	 * @param bool|string $class_name   $class name
634
+	 * @param string      $type         file type - core? class? helper? model?
635
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
636
+	 * @param bool        $from_db      some classes are instantiated from the db
637
+	 *                                  and thus call a different method to instantiate
638
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
639
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
640
+	 * @return null|object|bool         null = failure to load or instantiate class object.
641
+	 *                                  object = class loaded and instantiated successfully.
642
+	 *                                  bool = fail or success when $load_only is true
643
+	 */
644
+	protected function _load(
645
+		$file_paths = array(),
646
+		$class_prefix = 'EE_',
647
+		$class_name = false,
648
+		$type = 'class',
649
+		$arguments = array(),
650
+		$from_db = false,
651
+		$cache = true,
652
+		$load_only = false
653
+	) {
654
+		$class_name = ltrim($class_name, '\\');
655
+		// strip php file extension
656
+		$class_name = str_replace('.php', '', trim($class_name));
657
+		// does the class have a prefix ?
658
+		if ( ! empty($class_prefix) && $class_prefix != 'addon') {
659
+			// make sure $class_prefix is uppercase
660
+			$class_prefix = strtoupper(trim($class_prefix));
661
+			// add class prefix ONCE!!!
662
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
663
+		}
664
+		$class_name = $this->_dependency_map->get_alias($class_name);
665
+		$class_exists = class_exists($class_name);
666
+		// if we're only loading the class and it already exists, then let's just return true immediately
667
+		if ($load_only && $class_exists) {
668
+			return true;
669
+		}
670
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
671
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
672
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
673
+		if ($this->_cache_on && $cache && ! $load_only) {
674
+			// return object if it's already cached
675
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix);
676
+			if ($cached_class !== null) {
677
+				return $cached_class;
678
+			}
679
+		}
680
+		// if the class doesn't already exist.. then we need to try and find the file and load it
681
+		if ( ! $class_exists) {
682
+			// get full path to file
683
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
684
+			// load the file
685
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
686
+			// if loading failed, or we are only loading a file but NOT instantiating an object
687
+			if ( ! $loaded || $load_only) {
688
+				// return boolean if only loading, or null if an object was expected
689
+				return $load_only ? $loaded : null;
690
+			}
691
+		}
692
+		// instantiate the requested object
693
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
694
+		if ($this->_cache_on && $cache) {
695
+			// save it for later... kinda like gum  { : $
696
+			$this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
697
+		}
698
+		$this->_cache_on = true;
699
+		return $class_obj;
700
+	}
701
+
702
+
703
+
704
+
705
+	/**
706
+	 * _get_cached_class
707
+	 * attempts to find a cached version of the requested class
708
+	 * by looking in the following places:
709
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
710
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
711
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
712
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
713
+	 *
714
+	 * @access protected
715
+	 * @param string $class_name
716
+	 * @param string $class_prefix
717
+	 * @return mixed
718
+	 */
719
+	protected function _get_cached_class($class_name, $class_prefix = '')
720
+	{
721
+		if ($class_name === 'EE_Registry') {
722
+			return $this;
723
+		}
724
+		// have to specify something, but not anything that will conflict
725
+		$class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
726
+			? $this->_class_abbreviations[ $class_name ]
727
+			: 'FANCY_BATMAN_PANTS';
728
+		$class_name = str_replace('\\', '_', $class_name);
729
+		// check if class has already been loaded, and return it if it has been
730
+		if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
731
+			return $this->{$class_abbreviation};
732
+		}
733
+		if (isset ($this->{$class_name})) {
734
+			return $this->{$class_name};
735
+		}
736
+		if (isset ($this->LIB->{$class_name})) {
737
+			return $this->LIB->{$class_name};
738
+		}
739
+		if ($class_prefix === 'addon' && isset ($this->addons->{$class_name})) {
740
+			return $this->addons->{$class_name};
741
+		}
742
+		return null;
743
+	}
744
+
745
+
746
+
747
+	/**
748
+	 * removes a cached version of the requested class
749
+	 *
750
+	 * @param string $class_name
751
+	 * @param boolean $addon
752
+	 * @return boolean
753
+	 */
754
+	public function clear_cached_class($class_name, $addon = false)
755
+	{
756
+		// have to specify something, but not anything that will conflict
757
+		$class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
758
+			? $this->_class_abbreviations[ $class_name ]
759
+			: 'FANCY_BATMAN_PANTS';
760
+		$class_name = str_replace('\\', '_', $class_name);
761
+		// check if class has already been loaded, and return it if it has been
762
+		if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
763
+			$this->{$class_abbreviation} = null;
764
+			return true;
765
+		}
766
+		if (isset($this->{$class_name})) {
767
+			$this->{$class_name} = null;
768
+			return true;
769
+		}
770
+		if (isset($this->LIB->{$class_name})) {
771
+			unset($this->LIB->{$class_name});
772
+			return true;
773
+		}
774
+		if ($addon && isset($this->addons->{$class_name})) {
775
+			unset($this->addons->{$class_name});
776
+			return true;
777
+		}
778
+		return false;
779
+	}
780
+
781
+
782
+	/**
783
+	 * _resolve_path
784
+	 * attempts to find a full valid filepath for the requested class.
785
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
786
+	 * then returns that path if the target file has been found and is readable
787
+	 *
788
+	 * @access protected
789
+	 * @param string $class_name
790
+	 * @param string $type
791
+	 * @param array  $file_paths
792
+	 * @return string | bool
793
+	 */
794
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
795
+	{
796
+		// make sure $file_paths is an array
797
+		$file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
798
+		// cycle thru paths
799
+		foreach ($file_paths as $key => $file_path) {
800
+			// convert all separators to proper DS, if no filepath, then use EE_CLASSES
801
+			$file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
802
+			// prep file type
803
+			$type = ! empty($type) ? trim($type, '.') . '.' : '';
804
+			// build full file path
805
+			$file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
806
+			//does the file exist and can be read ?
807
+			if (is_readable($file_paths[$key])) {
808
+				return $file_paths[$key];
809
+			}
810
+		}
811
+		return false;
812
+	}
813
+
814
+
815
+
816
+	/**
817
+	 * _require_file
818
+	 * basically just performs a require_once()
819
+	 * but with some error handling
820
+	 *
821
+	 * @access protected
822
+	 * @param  string $path
823
+	 * @param  string $class_name
824
+	 * @param  string $type
825
+	 * @param  array  $file_paths
826
+	 * @return boolean
827
+	 * @throws \EE_Error
828
+	 */
829
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
830
+	{
831
+		// don't give up! you gotta...
832
+		try {
833
+			//does the file exist and can it be read ?
834
+			if ( ! $path) {
835
+				// so sorry, can't find the file
836
+				throw new EE_Error (
837
+					sprintf(
838
+						__('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
839
+						trim($type, '.'),
840
+						$class_name,
841
+						'<br />' . implode(',<br />', $file_paths)
842
+					)
843
+				);
844
+			}
845
+			// get the file
846
+			require_once($path);
847
+			// if the class isn't already declared somewhere
848
+			if (class_exists($class_name, false) === false) {
849
+				// so sorry, not a class
850
+				throw new EE_Error(
851
+					sprintf(
852
+						__('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
853
+						$type,
854
+						$path,
855
+						$class_name
856
+					)
857
+				);
858
+			}
859
+		} catch (EE_Error $e) {
860
+			$e->get_error();
861
+			return false;
862
+		}
863
+		return true;
864
+	}
865
+
866
+
867
+
868
+	/**
869
+	 * _create_object
870
+	 * Attempts to instantiate the requested class via any of the
871
+	 * commonly used instantiation methods employed throughout EE.
872
+	 * The priority for instantiation is as follows:
873
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
874
+	 *        - model objects via their 'new_instance_from_db' method
875
+	 *        - model objects via their 'new_instance' method
876
+	 *        - "singleton" classes" via their 'instance' method
877
+	 *    - standard instantiable classes via their __constructor
878
+	 * Prior to instantiation, if the classname exists in the dependency_map,
879
+	 * then the constructor for the requested class will be examined to determine
880
+	 * if any dependencies exist, and if they can be injected.
881
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
882
+	 *
883
+	 * @access protected
884
+	 * @param string $class_name
885
+	 * @param array  $arguments
886
+	 * @param string $type
887
+	 * @param bool   $from_db
888
+	 * @return null | object
889
+	 * @throws \EE_Error
890
+	 */
891
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
892
+	{
893
+		$class_obj = null;
894
+		$instantiation_mode = '0) none';
895
+		// don't give up! you gotta...
896
+		try {
897
+			// create reflection
898
+			$reflector = $this->get_ReflectionClass($class_name);
899
+			// make sure arguments are an array
900
+			$arguments = is_array($arguments) ? $arguments : array($arguments);
901
+			// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
902
+			// else wrap it in an additional array so that it doesn't get split into multiple parameters
903
+			$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
904
+				? $arguments
905
+				: array($arguments);
906
+			// attempt to inject dependencies ?
907
+			if ($this->_dependency_map->has($class_name)) {
908
+				$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
909
+			}
910
+			// instantiate the class if possible
911
+			if ($reflector->isAbstract()) {
912
+				// nothing to instantiate, loading file was enough
913
+				// does not throw an exception so $instantiation_mode is unused
914
+				// $instantiation_mode = "1) no constructor abstract class";
915
+				$class_obj = true;
916
+			} else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
917
+				// no constructor = static methods only... nothing to instantiate, loading file was enough
918
+				$instantiation_mode = "2) no constructor but instantiable";
919
+				$class_obj = $reflector->newInstance();
920
+			} else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
921
+				$instantiation_mode = "3) new_instance_from_db()";
922
+				$class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
923
+			} else if (method_exists($class_name, 'new_instance')) {
924
+				$instantiation_mode = "4) new_instance()";
925
+				$class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
926
+			} else if (method_exists($class_name, 'instance')) {
927
+				$instantiation_mode = "5) instance()";
928
+				$class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
929
+			} else if ($reflector->isInstantiable()) {
930
+				$instantiation_mode = "6) constructor";
931
+				$class_obj = $reflector->newInstanceArgs($arguments);
932
+			} else {
933
+				// heh ? something's not right !
934
+				throw new EE_Error(
935
+					sprintf(
936
+						__('The %s file %s could not be instantiated.', 'event_espresso'),
937
+						$type,
938
+						$class_name
939
+					)
940
+				);
941
+			}
942
+		} catch (Exception $e) {
943
+			if ( ! $e instanceof EE_Error) {
944
+				$e = new EE_Error(
945
+					sprintf(
946
+						__('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
947
+						$class_name,
948
+						'<br />',
949
+						$e->getMessage(),
950
+						$instantiation_mode
951
+					)
952
+				);
953
+			}
954
+			$e->get_error();
955
+		}
956
+		return $class_obj;
957
+	}
958
+
959
+
960
+
961
+	/**
962
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
963
+	 * @param array $array
964
+	 * @return bool
965
+	 */
966
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
967
+	{
968
+		return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
969
+	}
970
+
971
+
972
+
973
+	/**
974
+	 * getReflectionClass
975
+	 * checks if a ReflectionClass object has already been generated for a class
976
+	 * and returns that instead of creating a new one
977
+	 *
978
+	 * @access public
979
+	 * @param string $class_name
980
+	 * @return ReflectionClass
981
+	 */
982
+	public function get_ReflectionClass($class_name)
983
+	{
984
+		if (
985
+			! isset($this->_reflectors[$class_name])
986
+			|| ! $this->_reflectors[$class_name] instanceof ReflectionClass
987
+		) {
988
+			$this->_reflectors[$class_name] = new ReflectionClass($class_name);
989
+		}
990
+		return $this->_reflectors[$class_name];
991
+	}
992
+
993
+
994
+
995
+	/**
996
+	 * _resolve_dependencies
997
+	 * examines the constructor for the requested class to determine
998
+	 * if any dependencies exist, and if they can be injected.
999
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1000
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
1001
+	 * For example:
1002
+	 *        if attempting to load a class "Foo" with the following constructor:
1003
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
1004
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
1005
+	 *        but only IF they are NOT already present in the incoming arguments array,
1006
+	 *        and the correct classes can be loaded
1007
+	 *
1008
+	 * @access protected
1009
+	 * @param ReflectionClass $reflector
1010
+	 * @param string          $class_name
1011
+	 * @param array           $arguments
1012
+	 * @return array
1013
+	 * @throws \ReflectionException
1014
+	 */
1015
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
1016
+	{
1017
+		// let's examine the constructor
1018
+		$constructor = $reflector->getConstructor();
1019
+		// whu? huh? nothing?
1020
+		if ( ! $constructor) {
1021
+			return $arguments;
1022
+		}
1023
+		// get constructor parameters
1024
+		$params = $constructor->getParameters();
1025
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1026
+		$argument_keys = array_keys($arguments);
1027
+		// now loop thru all of the constructors expected parameters
1028
+		foreach ($params as $index => $param) {
1029
+			// is this a dependency for a specific class ?
1030
+			$param_class = $param->getClass() ? $param->getClass()->name : null;
1031
+			// BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1032
+			$param_class = $this->_dependency_map->has_alias($param_class, $class_name)
1033
+				? $this->_dependency_map->get_alias($param_class, $class_name)
1034
+				: $param_class;
1035
+			if (
1036
+				// param is not even a class
1037
+				empty($param_class)
1038
+				// and something already exists in the incoming arguments for this param
1039
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1040
+			) {
1041
+				// so let's skip this argument and move on to the next
1042
+				continue;
1043
+			}
1044
+			if (
1045
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1046
+				! empty($param_class)
1047
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1048
+				&& $arguments[$argument_keys[$index]] instanceof $param_class
1049
+			) {
1050
+				// skip this argument and move on to the next
1051
+				continue;
1052
+			}
1053
+			if (
1054
+				// parameter is type hinted as a class, and should be injected
1055
+				! empty($param_class)
1056
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1057
+			) {
1058
+				$arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1059
+			} else {
1060
+				try {
1061
+					$arguments[$index] = $param->getDefaultValue();
1062
+				} catch (ReflectionException $e) {
1063
+					throw new ReflectionException(
1064
+						sprintf(
1065
+							__('%1$s for parameter "$%2$s"', 'event_espresso'),
1066
+							$e->getMessage(),
1067
+							$param->getName()
1068
+						)
1069
+					);
1070
+				}
1071
+			}
1072
+		}
1073
+		return $arguments;
1074
+	}
1075
+
1076
+
1077
+
1078
+	/**
1079
+	 * @access protected
1080
+	 * @param string $class_name
1081
+	 * @param string $param_class
1082
+	 * @param array  $arguments
1083
+	 * @param mixed  $index
1084
+	 * @return array
1085
+	 */
1086
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1087
+	{
1088
+		$dependency = null;
1089
+		// should dependency be loaded from cache ?
1090
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1091
+					!== EE_Dependency_Map::load_new_object
1092
+			? true
1093
+			: false;
1094
+		// we might have a dependency...
1095
+		// let's MAYBE try and find it in our cache if that's what's been requested
1096
+		$cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1097
+		// and grab it if it exists
1098
+		if ($cached_class instanceof $param_class) {
1099
+			$dependency = $cached_class;
1100
+		} else if ($param_class !== $class_name) {
1101
+			// obtain the loader method from the dependency map
1102
+			$loader = $this->_dependency_map->class_loader($param_class);
1103
+			// is loader a custom closure ?
1104
+			if ($loader instanceof Closure) {
1105
+				$dependency = $loader();
1106
+			} else {
1107
+				// set the cache on property for the recursive loading call
1108
+				$this->_cache_on = $cache_on;
1109
+				// if not, then let's try and load it via the registry
1110
+				if ($loader && method_exists($this, $loader)) {
1111
+					$dependency = $this->{$loader}($param_class);
1112
+				} else {
1113
+					$dependency = $this->create($param_class, array(), $cache_on);
1114
+				}
1115
+			}
1116
+		}
1117
+		// did we successfully find the correct dependency ?
1118
+		if ($dependency instanceof $param_class) {
1119
+			// then let's inject it into the incoming array of arguments at the correct location
1120
+			if (isset($argument_keys[$index])) {
1121
+				$arguments[$argument_keys[$index]] = $dependency;
1122
+			} else {
1123
+				$arguments[$index] = $dependency;
1124
+			}
1125
+		}
1126
+		return $arguments;
1127
+	}
1128
+
1129
+
1130
+
1131
+	/**
1132
+	 * _set_cached_class
1133
+	 * attempts to cache the instantiated class locally
1134
+	 * in one of the following places, in the following order:
1135
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1136
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1137
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1138
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1139
+	 *
1140
+	 * @access protected
1141
+	 * @param object $class_obj
1142
+	 * @param string $class_name
1143
+	 * @param string $class_prefix
1144
+	 * @param bool   $from_db
1145
+	 * @return void
1146
+	 */
1147
+	protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1148
+	{
1149
+		if ($class_name === 'EE_Registry' || empty($class_obj)) {
1150
+			return;
1151
+		}
1152
+		// return newly instantiated class
1153
+		if (isset($this->_class_abbreviations[$class_name])) {
1154
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
1155
+			$this->{$class_abbreviation} = $class_obj;
1156
+			return;
1157
+		}
1158
+		$class_name = str_replace('\\', '_', $class_name);
1159
+		if (property_exists($this, $class_name)) {
1160
+			$this->{$class_name} = $class_obj;
1161
+			return;
1162
+		}
1163
+		if ($class_prefix === 'addon') {
1164
+			$this->addons->{$class_name} = $class_obj;
1165
+			return;
1166
+		}
1167
+		if ( ! $from_db) {
1168
+			$this->LIB->{$class_name} = $class_obj;
1169
+		}
1170
+	}
1171
+
1172
+
1173
+
1174
+	/**
1175
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1176
+	 *
1177
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1178
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1179
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1180
+	 * @param array  $arguments
1181
+	 * @return object
1182
+	 */
1183
+	public static function factory($classname, $arguments = array())
1184
+	{
1185
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1186
+		if ($loader instanceof Closure) {
1187
+			return $loader($arguments);
1188
+		}
1189
+		if (method_exists(EE_Registry::instance(), $loader)) {
1190
+			return EE_Registry::instance()->{$loader}($classname, $arguments);
1191
+		}
1192
+		return null;
1193
+	}
1194
+
1195
+
1196
+
1197
+	/**
1198
+	 * Gets the addon by its name/slug (not classname. For that, just
1199
+	 * use the classname as the property name on EE_Config::instance()->addons)
1200
+	 *
1201
+	 * @param string $name
1202
+	 * @return EE_Addon
1203
+	 */
1204
+	public function get_addon_by_name($name)
1205
+	{
1206
+		foreach ($this->addons as $addon) {
1207
+			if ($addon->name() == $name) {
1208
+				return $addon;
1209
+			}
1210
+		}
1211
+		return null;
1212
+	}
1213
+
1214
+
1215
+
1216
+	/**
1217
+	 * Gets an array of all the registered addons, where the keys are their names. (ie, what each returns for their name() function) They're already available on EE_Config::instance()->addons as properties, where each property's name is
1218
+	 * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1219
+	 *
1220
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1221
+	 */
1222
+	public function get_addons_by_name()
1223
+	{
1224
+		$addons = array();
1225
+		foreach ($this->addons as $addon) {
1226
+			$addons[$addon->name()] = $addon;
1227
+		}
1228
+		return $addons;
1229
+	}
1230
+
1231
+
1232
+
1233
+	/**
1234
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1235
+	 * a stale copy of it around
1236
+	 *
1237
+	 * @param string $model_name
1238
+	 * @return \EEM_Base
1239
+	 * @throws \EE_Error
1240
+	 */
1241
+	public function reset_model($model_name)
1242
+	{
1243
+		$model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1244
+		if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1245
+			return null;
1246
+		}
1247
+		//get that model reset it and make sure we nuke the old reference to it
1248
+		if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1249
+			$this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1250
+		} else {
1251
+			throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1252
+		}
1253
+		return $this->LIB->{$model_class_name};
1254
+	}
1255
+
1256
+
1257
+
1258
+	/**
1259
+	 * Resets the registry.
1260
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1261
+	 * is used in a multisite install.  Here is a list of things that are NOT reset.
1262
+	 * - $_dependency_map
1263
+	 * - $_class_abbreviations
1264
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1265
+	 * - $REQ:  Still on the same request so no need to change.
1266
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1267
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1268
+	 *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1269
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1270
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1271
+	 *             switch or on the restore.
1272
+	 * - $modules
1273
+	 * - $shortcodes
1274
+	 * - $widgets
1275
+	 *
1276
+	 * @param boolean $hard             whether to reset data in the database too, or just refresh
1277
+	 *                                  the Registry to its state at the beginning of the request
1278
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1279
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1280
+	 *                                  currently reinstantiate the singletons at the moment)
1281
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1282
+	 *                                  code instead can just change the model context to a different blog id if necessary
1283
+	 * @return EE_Registry
1284
+	 */
1285
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1286
+	{
1287
+		$instance = self::instance();
1288
+		$instance->_cache_on = true;
1289
+		// reset some "special" classes
1290
+		EEH_Activation::reset();
1291
+		$instance->CFG = $instance->CFG->reset($hard, $reinstantiate);
1292
+		$instance->CART = null;
1293
+		$instance->MRM = null;
1294
+		$instance->AssetsRegistry = null;
1295
+		$instance->AssetsRegistry = $instance->create('EventEspresso\core\services\assets\Registry');
1296
+		//messages reset
1297
+		EED_Messages::reset();
1298
+		//handle of objects cached on LIB
1299
+		foreach (array('LIB', 'modules', 'shortcodes') as $cache) {
1300
+			foreach ($instance->{$cache} as $class_name => $class) {
1301
+				if (EE_Registry::_reset_and_unset_object($class, $reset_models)) {
1302
+					unset($instance->{$cache}->{$class_name});
1303
+				}
1304
+			}
1305
+		}
1306
+		return $instance;
1307
+	}
1308
+
1309
+
1310
+
1311
+	/**
1312
+	 * if passed object implements ResettableInterface, then call it's reset() method
1313
+	 * if passed object implements InterminableInterface, then return false,
1314
+	 * to indicate that it should NOT be cleared from the Registry cache
1315
+	 *
1316
+	 * @param      $object
1317
+	 * @param bool $reset_models
1318
+	 * @return bool returns true if cached object should be unset
1319
+	 */
1320
+	private static function _reset_and_unset_object($object, $reset_models)
1321
+	{
1322
+		static $count = 0;
1323
+		$count++;
1324
+		if ($object instanceof ResettableInterface) {
1325
+			if ($object instanceof EEM_Base) {
1326
+				if ($reset_models) {
1327
+					$object->reset();
1328
+					return true;
1329
+				}
1330
+				return false;
1331
+			}
1332
+			$object->reset();
1333
+			return true;
1334
+		}
1335
+		if ( ! $object instanceof InterminableInterface) {
1336
+			return true;
1337
+		}
1338
+		return false;
1339
+	}
1340
+
1341
+
1342
+
1343
+	/**
1344
+	 * @override magic methods
1345
+	 * @return void
1346
+	 */
1347
+	public final function __destruct()
1348
+	{
1349
+	}
1350
+
1351
+
1352
+
1353
+	/**
1354
+	 * @param $a
1355
+	 * @param $b
1356
+	 */
1357
+	public final function __call($a, $b)
1358
+	{
1359
+	}
1360
+
1361
+
1362
+
1363
+	/**
1364
+	 * @param $a
1365
+	 */
1366
+	public final function __get($a)
1367
+	{
1368
+	}
1369
+
1370
+
1371
+
1372
+	/**
1373
+	 * @param $a
1374
+	 * @param $b
1375
+	 */
1376
+	public final function __set($a, $b)
1377
+	{
1378
+	}
1379
+
1380
+
1381
+
1382
+	/**
1383
+	 * @param $a
1384
+	 */
1385
+	public final function __isset($a)
1386
+	{
1387
+	}
1388 1388
 
1389 1389
 
1390 1390
 
1391
-    /**
1392
-     * @param $a
1393
-     */
1394
-    public final function __unset($a)
1395
-    {
1396
-    }
1391
+	/**
1392
+	 * @param $a
1393
+	 */
1394
+	public final function __unset($a)
1395
+	{
1396
+	}
1397 1397
 
1398 1398
 
1399 1399
 
1400
-    /**
1401
-     * @return array
1402
-     */
1403
-    public final function __sleep()
1404
-    {
1405
-        return array();
1406
-    }
1400
+	/**
1401
+	 * @return array
1402
+	 */
1403
+	public final function __sleep()
1404
+	{
1405
+		return array();
1406
+	}
1407 1407
 
1408 1408
 
1409 1409
 
1410
-    public final function __wakeup()
1411
-    {
1412
-    }
1410
+	public final function __wakeup()
1411
+	{
1412
+	}
1413 1413
 
1414 1414
 
1415 1415
 
1416
-    /**
1417
-     * @return string
1418
-     */
1419
-    public final function __toString()
1420
-    {
1421
-        return '';
1422
-    }
1416
+	/**
1417
+	 * @return string
1418
+	 */
1419
+	public final function __toString()
1420
+	{
1421
+		return '';
1422
+	}
1423 1423
 
1424 1424
 
1425 1425
 
1426
-    public final function __invoke()
1427
-    {
1428
-    }
1426
+	public final function __invoke()
1427
+	{
1428
+	}
1429 1429
 
1430 1430
 
1431 1431
 
1432
-    public final static function __set_state($array = array())
1433
-    {
1434
-        return EE_Registry::instance();
1435
-    }
1432
+	public final static function __set_state($array = array())
1433
+	{
1434
+		return EE_Registry::instance();
1435
+	}
1436 1436
 
1437 1437
 
1438 1438
 
1439
-    public final function __clone()
1440
-    {
1441
-    }
1439
+	public final function __clone()
1440
+	{
1441
+	}
1442 1442
 
1443 1443
 
1444 1444
 
1445
-    /**
1446
-     * @param $a
1447
-     * @param $b
1448
-     */
1449
-    public final static function __callStatic($a, $b)
1450
-    {
1451
-    }
1445
+	/**
1446
+	 * @param $a
1447
+	 * @param $b
1448
+	 */
1449
+	public final static function __callStatic($a, $b)
1450
+	{
1451
+	}
1452 1452
 
1453 1453
 
1454 1454
 
1455
-    /**
1456
-     * Gets all the custom post type models defined
1457
-     *
1458
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1459
-     */
1460
-    public function cpt_models()
1461
-    {
1462
-        $cpt_models = array();
1463
-        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1464
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1465
-                $cpt_models[$short_name] = $classname;
1466
-            }
1467
-        }
1468
-        return $cpt_models;
1469
-    }
1455
+	/**
1456
+	 * Gets all the custom post type models defined
1457
+	 *
1458
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1459
+	 */
1460
+	public function cpt_models()
1461
+	{
1462
+		$cpt_models = array();
1463
+		foreach ($this->non_abstract_db_models as $short_name => $classname) {
1464
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1465
+				$cpt_models[$short_name] = $classname;
1466
+			}
1467
+		}
1468
+		return $cpt_models;
1469
+	}
1470 1470
 
1471 1471
 
1472 1472
 
1473
-    /**
1474
-     * @return \EE_Config
1475
-     */
1476
-    public static function CFG()
1477
-    {
1478
-        return self::instance()->CFG;
1479
-    }
1473
+	/**
1474
+	 * @return \EE_Config
1475
+	 */
1476
+	public static function CFG()
1477
+	{
1478
+		return self::instance()->CFG;
1479
+	}
1480 1480
 
1481 1481
 
1482 1482
 }
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -297,13 +297,13 @@  discard block
 block discarded – undo
297 297
      */
298 298
     public static function localize_i18n_js_strings()
299 299
     {
300
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
300
+        $i18n_js_strings = (array) EE_Registry::$i18n_js_strings;
301 301
         foreach ($i18n_js_strings as $key => $value) {
302 302
             if (is_scalar($value)) {
303
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
303
+                $i18n_js_strings[$key] = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
304 304
             }
305 305
         }
306
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
306
+        return "/* <![CDATA[ */ var eei18n = ".wp_json_encode($i18n_js_strings).'; /* ]]> */';
307 307
     }
308 308
 
309 309
 
@@ -354,10 +354,10 @@  discard block
 block discarded – undo
354 354
                 EE_CORE,
355 355
                 EE_ADMIN,
356 356
                 EE_CPTS,
357
-                EE_CORE . 'data_migration_scripts' . DS,
358
-                EE_CORE . 'capabilities' . DS,
359
-                EE_CORE . 'request_stack' . DS,
360
-                EE_CORE . 'middleware' . DS,
357
+                EE_CORE.'data_migration_scripts'.DS,
358
+                EE_CORE.'capabilities'.DS,
359
+                EE_CORE.'request_stack'.DS,
360
+                EE_CORE.'middleware'.DS,
361 361
             )
362 362
         );
363 363
         // retrieve instantiated class
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
         $service_paths = apply_filters(
381 381
             'FHEE__EE_Registry__load_service__service_paths',
382 382
             array(
383
-                EE_CORE . 'services' . DS,
383
+                EE_CORE.'services'.DS,
384 384
             )
385 385
         );
386 386
         // retrieve instantiated class
@@ -460,10 +460,10 @@  discard block
 block discarded – undo
460 460
     {
461 461
         $paths = array(
462 462
             EE_LIBRARIES,
463
-            EE_LIBRARIES . 'messages' . DS,
464
-            EE_LIBRARIES . 'shortcodes' . DS,
465
-            EE_LIBRARIES . 'qtips' . DS,
466
-            EE_LIBRARIES . 'payment_methods' . DS,
463
+            EE_LIBRARIES.'messages'.DS,
464
+            EE_LIBRARIES.'shortcodes'.DS,
465
+            EE_LIBRARIES.'qtips'.DS,
466
+            EE_LIBRARIES.'payment_methods'.DS,
467 467
         );
468 468
         // retrieve instantiated class
469 469
         return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
@@ -502,10 +502,10 @@  discard block
 block discarded – undo
502 502
     public function load_model_class($class_name, $arguments = array(), $load_only = true)
503 503
     {
504 504
         $paths = array(
505
-            EE_MODELS . 'fields' . DS,
506
-            EE_MODELS . 'helpers' . DS,
507
-            EE_MODELS . 'relations' . DS,
508
-            EE_MODELS . 'strategies' . DS,
505
+            EE_MODELS.'fields'.DS,
506
+            EE_MODELS.'helpers'.DS,
507
+            EE_MODELS.'relations'.DS,
508
+            EE_MODELS.'strategies'.DS,
509 509
         );
510 510
         // retrieve instantiated class
511 511
         return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
         $class_name = $this->_dependency_map->get_alias($class_name);
593 593
         if ( ! class_exists($class_name)) {
594 594
             // maybe the class is registered with a preceding \
595
-            $class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
595
+            $class_name = strpos($class_name, '\\') !== 0 ? '\\'.$class_name : $class_name;
596 596
             // still doesn't exist ?
597 597
             if ( ! class_exists($class_name)) {
598 598
                 return null;
@@ -659,7 +659,7 @@  discard block
 block discarded – undo
659 659
             // make sure $class_prefix is uppercase
660 660
             $class_prefix = strtoupper(trim($class_prefix));
661 661
             // add class prefix ONCE!!!
662
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
662
+            $class_name = $class_prefix.str_replace($class_prefix, '', $class_name);
663 663
         }
664 664
         $class_name = $this->_dependency_map->get_alias($class_name);
665 665
         $class_exists = class_exists($class_name);
@@ -722,8 +722,8 @@  discard block
 block discarded – undo
722 722
             return $this;
723 723
         }
724 724
         // have to specify something, but not anything that will conflict
725
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
726
-            ? $this->_class_abbreviations[ $class_name ]
725
+        $class_abbreviation = isset($this->_class_abbreviations[$class_name])
726
+            ? $this->_class_abbreviations[$class_name]
727 727
             : 'FANCY_BATMAN_PANTS';
728 728
         $class_name = str_replace('\\', '_', $class_name);
729 729
         // check if class has already been loaded, and return it if it has been
@@ -754,8 +754,8 @@  discard block
 block discarded – undo
754 754
     public function clear_cached_class($class_name, $addon = false)
755 755
     {
756 756
         // have to specify something, but not anything that will conflict
757
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
758
-            ? $this->_class_abbreviations[ $class_name ]
757
+        $class_abbreviation = isset($this->_class_abbreviations[$class_name])
758
+            ? $this->_class_abbreviations[$class_name]
759 759
             : 'FANCY_BATMAN_PANTS';
760 760
         $class_name = str_replace('\\', '_', $class_name);
761 761
         // check if class has already been loaded, and return it if it has been
@@ -800,9 +800,9 @@  discard block
 block discarded – undo
800 800
             // convert all separators to proper DS, if no filepath, then use EE_CLASSES
801 801
             $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
802 802
             // prep file type
803
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
803
+            $type = ! empty($type) ? trim($type, '.').'.' : '';
804 804
             // build full file path
805
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
805
+            $file_paths[$key] = rtrim($file_path, DS).DS.$class_name.'.'.$type.'php';
806 806
             //does the file exist and can be read ?
807 807
             if (is_readable($file_paths[$key])) {
808 808
                 return $file_paths[$key];
@@ -833,12 +833,12 @@  discard block
 block discarded – undo
833 833
             //does the file exist and can it be read ?
834 834
             if ( ! $path) {
835 835
                 // so sorry, can't find the file
836
-                throw new EE_Error (
836
+                throw new EE_Error(
837 837
                     sprintf(
838 838
                         __('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
839 839
                         trim($type, '.'),
840 840
                         $class_name,
841
-                        '<br />' . implode(',<br />', $file_paths)
841
+                        '<br />'.implode(',<br />', $file_paths)
842 842
                     )
843 843
                 );
844 844
             }
Please login to merge, or discard this patch.
core/helpers/EEH_Activation.helper.php 1 patch
Indentation   +1652 added lines, -1652 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 use EventEspresso\core\interfaces\ResettableInterface;
3 3
 
4 4
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -17,243 +17,243 @@  discard block
 block discarded – undo
17 17
 class EEH_Activation implements ResettableInterface
18 18
 {
19 19
 
20
-    /**
21
-     * constant used to indicate a cron task is no longer in use
22
-     */
23
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
24
-
25
-    /**
26
-     * option name that will indicate whether or not we still
27
-     * need to create EE's folders in the uploads directory
28
-     * (because if EE was installed without file system access,
29
-     * we need to request credentials before we can create them)
30
-     */
31
-    const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
32
-
33
-    /**
34
-     * WP_User->ID
35
-     *
36
-     * @var int
37
-     */
38
-    private static $_default_creator_id;
39
-
40
-    /**
41
-     * indicates whether or not we've already verified core's default data during this request,
42
-     * because after migrations are done, any addons activated while in maintenance mode
43
-     * will want to setup their own default data, and they might hook into core's default data
44
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
45
-     * This prevents doing that for EVERY single addon.
46
-     *
47
-     * @var boolean
48
-     */
49
-    protected static $_initialized_db_content_already_in_this_request = false;
50
-
51
-    /**
52
-     * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
53
-     */
54
-    private static $table_analysis;
55
-
56
-    /**
57
-     * @var \EventEspresso\core\services\database\TableManager $table_manager
58
-     */
59
-    private static $table_manager;
60
-
61
-
62
-    /**
63
-     * @return \EventEspresso\core\services\database\TableAnalysis
64
-     */
65
-    public static function getTableAnalysis()
66
-    {
67
-        if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
68
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
69
-        }
70
-        return self::$table_analysis;
71
-    }
72
-
73
-
74
-    /**
75
-     * @return \EventEspresso\core\services\database\TableManager
76
-     */
77
-    public static function getTableManager()
78
-    {
79
-        if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
80
-            self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
81
-        }
82
-        return self::$table_manager;
83
-    }
84
-
85
-
86
-    /**
87
-     *    _ensure_table_name_has_prefix
88
-     *
89
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
90
-     * @access     public
91
-     * @static
92
-     * @param $table_name
93
-     * @return string
94
-     */
95
-    public static function ensure_table_name_has_prefix($table_name)
96
-    {
97
-        return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
98
-    }
99
-
100
-
101
-    /**
102
-     *    system_initialization
103
-     *    ensures the EE configuration settings are loaded with at least default options set
104
-     *    and that all critical EE pages have been generated with the appropriate shortcodes in place
105
-     *
106
-     * @access public
107
-     * @static
108
-     * @return void
109
-     */
110
-    public static function system_initialization()
111
-    {
112
-        EEH_Activation::reset_and_update_config();
113
-        //which is fired BEFORE activation of plugin anyways
114
-        EEH_Activation::verify_default_pages_exist();
115
-    }
116
-
117
-
118
-    /**
119
-     * Sets the database schema and creates folders. This should
120
-     * be called on plugin activation and reactivation
121
-     *
122
-     * @return boolean success, whether the database and folders are setup properly
123
-     * @throws \EE_Error
124
-     */
125
-    public static function initialize_db_and_folders()
126
-    {
127
-        $good_filesystem = EEH_Activation::create_upload_directories();
128
-        $good_db         = EEH_Activation::create_database_tables();
129
-        return $good_filesystem && $good_db;
130
-    }
131
-
132
-
133
-    /**
134
-     * assuming we have an up-to-date database schema, this will populate it
135
-     * with default and initial data. This should be called
136
-     * upon activation of a new plugin, reactivation, and at the end
137
-     * of running migration scripts
138
-     *
139
-     * @throws \EE_Error
140
-     */
141
-    public static function initialize_db_content()
142
-    {
143
-        //let's avoid doing all this logic repeatedly, especially when addons are requesting it
144
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
145
-            return;
146
-        }
147
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
148
-
149
-        EEH_Activation::initialize_system_questions();
150
-        EEH_Activation::insert_default_status_codes();
151
-        EEH_Activation::generate_default_message_templates();
152
-        EEH_Activation::create_no_ticket_prices_array();
153
-
154
-        EEH_Activation::validate_messages_system();
155
-        EEH_Activation::insert_default_payment_methods();
156
-        //in case we've
157
-        EEH_Activation::remove_cron_tasks();
158
-        EEH_Activation::create_cron_tasks();
159
-        // remove all TXN locks since that is being done via extra meta now
160
-        delete_option('ee_locked_transactions');
161
-        //also, check for CAF default db content
162
-        do_action('AHEE__EEH_Activation__initialize_db_content');
163
-        //also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
164
-        //which users really won't care about on initial activation
165
-        EE_Error::overwrite_success();
166
-    }
167
-
168
-
169
-    /**
170
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
171
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
172
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
173
-     * (null)
174
-     *
175
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
176
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
177
-     * @return array
178
-     * @throws \EE_Error
179
-     */
180
-    public static function get_cron_tasks($which_to_include)
181
-    {
182
-        $cron_tasks = apply_filters(
183
-            'FHEE__EEH_Activation__get_cron_tasks',
184
-            array(
185
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
20
+	/**
21
+	 * constant used to indicate a cron task is no longer in use
22
+	 */
23
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
24
+
25
+	/**
26
+	 * option name that will indicate whether or not we still
27
+	 * need to create EE's folders in the uploads directory
28
+	 * (because if EE was installed without file system access,
29
+	 * we need to request credentials before we can create them)
30
+	 */
31
+	const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
32
+
33
+	/**
34
+	 * WP_User->ID
35
+	 *
36
+	 * @var int
37
+	 */
38
+	private static $_default_creator_id;
39
+
40
+	/**
41
+	 * indicates whether or not we've already verified core's default data during this request,
42
+	 * because after migrations are done, any addons activated while in maintenance mode
43
+	 * will want to setup their own default data, and they might hook into core's default data
44
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
45
+	 * This prevents doing that for EVERY single addon.
46
+	 *
47
+	 * @var boolean
48
+	 */
49
+	protected static $_initialized_db_content_already_in_this_request = false;
50
+
51
+	/**
52
+	 * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
53
+	 */
54
+	private static $table_analysis;
55
+
56
+	/**
57
+	 * @var \EventEspresso\core\services\database\TableManager $table_manager
58
+	 */
59
+	private static $table_manager;
60
+
61
+
62
+	/**
63
+	 * @return \EventEspresso\core\services\database\TableAnalysis
64
+	 */
65
+	public static function getTableAnalysis()
66
+	{
67
+		if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
68
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
69
+		}
70
+		return self::$table_analysis;
71
+	}
72
+
73
+
74
+	/**
75
+	 * @return \EventEspresso\core\services\database\TableManager
76
+	 */
77
+	public static function getTableManager()
78
+	{
79
+		if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
80
+			self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
81
+		}
82
+		return self::$table_manager;
83
+	}
84
+
85
+
86
+	/**
87
+	 *    _ensure_table_name_has_prefix
88
+	 *
89
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
90
+	 * @access     public
91
+	 * @static
92
+	 * @param $table_name
93
+	 * @return string
94
+	 */
95
+	public static function ensure_table_name_has_prefix($table_name)
96
+	{
97
+		return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
98
+	}
99
+
100
+
101
+	/**
102
+	 *    system_initialization
103
+	 *    ensures the EE configuration settings are loaded with at least default options set
104
+	 *    and that all critical EE pages have been generated with the appropriate shortcodes in place
105
+	 *
106
+	 * @access public
107
+	 * @static
108
+	 * @return void
109
+	 */
110
+	public static function system_initialization()
111
+	{
112
+		EEH_Activation::reset_and_update_config();
113
+		//which is fired BEFORE activation of plugin anyways
114
+		EEH_Activation::verify_default_pages_exist();
115
+	}
116
+
117
+
118
+	/**
119
+	 * Sets the database schema and creates folders. This should
120
+	 * be called on plugin activation and reactivation
121
+	 *
122
+	 * @return boolean success, whether the database and folders are setup properly
123
+	 * @throws \EE_Error
124
+	 */
125
+	public static function initialize_db_and_folders()
126
+	{
127
+		$good_filesystem = EEH_Activation::create_upload_directories();
128
+		$good_db         = EEH_Activation::create_database_tables();
129
+		return $good_filesystem && $good_db;
130
+	}
131
+
132
+
133
+	/**
134
+	 * assuming we have an up-to-date database schema, this will populate it
135
+	 * with default and initial data. This should be called
136
+	 * upon activation of a new plugin, reactivation, and at the end
137
+	 * of running migration scripts
138
+	 *
139
+	 * @throws \EE_Error
140
+	 */
141
+	public static function initialize_db_content()
142
+	{
143
+		//let's avoid doing all this logic repeatedly, especially when addons are requesting it
144
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
145
+			return;
146
+		}
147
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
148
+
149
+		EEH_Activation::initialize_system_questions();
150
+		EEH_Activation::insert_default_status_codes();
151
+		EEH_Activation::generate_default_message_templates();
152
+		EEH_Activation::create_no_ticket_prices_array();
153
+
154
+		EEH_Activation::validate_messages_system();
155
+		EEH_Activation::insert_default_payment_methods();
156
+		//in case we've
157
+		EEH_Activation::remove_cron_tasks();
158
+		EEH_Activation::create_cron_tasks();
159
+		// remove all TXN locks since that is being done via extra meta now
160
+		delete_option('ee_locked_transactions');
161
+		//also, check for CAF default db content
162
+		do_action('AHEE__EEH_Activation__initialize_db_content');
163
+		//also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
164
+		//which users really won't care about on initial activation
165
+		EE_Error::overwrite_success();
166
+	}
167
+
168
+
169
+	/**
170
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
171
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
172
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
173
+	 * (null)
174
+	 *
175
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
176
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
177
+	 * @return array
178
+	 * @throws \EE_Error
179
+	 */
180
+	public static function get_cron_tasks($which_to_include)
181
+	{
182
+		$cron_tasks = apply_filters(
183
+			'FHEE__EEH_Activation__get_cron_tasks',
184
+			array(
185
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
186 186
 //				'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
187
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
188
-                //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
189
-                'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
190
-            )
191
-        );
192
-        if ($which_to_include === 'old') {
193
-            $cron_tasks = array_filter(
194
-                $cron_tasks,
195
-                function ($value) {
196
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
197
-                }
198
-            );
199
-        } elseif ($which_to_include === 'current') {
200
-            $cron_tasks = array_filter($cron_tasks);
201
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
202
-            throw new EE_Error(
203
-                sprintf(
204
-                    __(
205
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
206
-                        'event_espresso'
207
-                    ),
208
-                    $which_to_include
209
-                )
210
-            );
211
-        }
212
-        return $cron_tasks;
213
-    }
214
-
215
-
216
-    /**
217
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
218
-     *
219
-     * @throws \EE_Error
220
-     */
221
-    public static function create_cron_tasks()
222
-    {
223
-
224
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
225
-            if (! wp_next_scheduled($hook_name)) {
226
-                /**
227
-                 * This allows client code to define the initial start timestamp for this schedule.
228
-                 */
229
-                if (is_array($frequency)
230
-                    && count($frequency) === 2
231
-                    && isset($frequency[0], $frequency[1])
232
-                ) {
233
-                    $start_timestamp = $frequency[0];
234
-                    $frequency = $frequency[1];
235
-                } else {
236
-                    $start_timestamp = time();
237
-                }
238
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
239
-            }
240
-        }
241
-
242
-    }
243
-
244
-
245
-    /**
246
-     * Remove the currently-existing and now-removed cron tasks.
247
-     *
248
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
249
-     * @throws \EE_Error
250
-     */
251
-    public static function remove_cron_tasks($remove_all = true)
252
-    {
253
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
254
-        $crons                = _get_cron_array();
255
-        $crons                = is_array($crons) ? $crons : array();
256
-        /* reminder of what $crons look like:
187
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
188
+				//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
189
+				'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
190
+			)
191
+		);
192
+		if ($which_to_include === 'old') {
193
+			$cron_tasks = array_filter(
194
+				$cron_tasks,
195
+				function ($value) {
196
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
197
+				}
198
+			);
199
+		} elseif ($which_to_include === 'current') {
200
+			$cron_tasks = array_filter($cron_tasks);
201
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
202
+			throw new EE_Error(
203
+				sprintf(
204
+					__(
205
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
206
+						'event_espresso'
207
+					),
208
+					$which_to_include
209
+				)
210
+			);
211
+		}
212
+		return $cron_tasks;
213
+	}
214
+
215
+
216
+	/**
217
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
218
+	 *
219
+	 * @throws \EE_Error
220
+	 */
221
+	public static function create_cron_tasks()
222
+	{
223
+
224
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
225
+			if (! wp_next_scheduled($hook_name)) {
226
+				/**
227
+				 * This allows client code to define the initial start timestamp for this schedule.
228
+				 */
229
+				if (is_array($frequency)
230
+					&& count($frequency) === 2
231
+					&& isset($frequency[0], $frequency[1])
232
+				) {
233
+					$start_timestamp = $frequency[0];
234
+					$frequency = $frequency[1];
235
+				} else {
236
+					$start_timestamp = time();
237
+				}
238
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
239
+			}
240
+		}
241
+
242
+	}
243
+
244
+
245
+	/**
246
+	 * Remove the currently-existing and now-removed cron tasks.
247
+	 *
248
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
249
+	 * @throws \EE_Error
250
+	 */
251
+	public static function remove_cron_tasks($remove_all = true)
252
+	{
253
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
254
+		$crons                = _get_cron_array();
255
+		$crons                = is_array($crons) ? $crons : array();
256
+		/* reminder of what $crons look like:
257 257
          * Top-level keys are timestamps, and their values are arrays.
258 258
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
259 259
          * and their values are arrays.
@@ -270,912 +270,912 @@  discard block
 block discarded – undo
270 270
          *					...
271 271
          *      ...
272 272
          */
273
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
274
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
275
-            if (is_array($hooks_to_fire_at_time)) {
276
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
277
-                    if (isset($ee_cron_tasks_to_remove[$hook_name])
278
-                        && is_array($ee_cron_tasks_to_remove[$hook_name])
279
-                    ) {
280
-                        unset($crons[$timestamp][$hook_name]);
281
-                    }
282
-                }
283
-                //also take care of any empty cron timestamps.
284
-                if (empty($hooks_to_fire_at_time)) {
285
-                    unset($crons[$timestamp]);
286
-                }
287
-            }
288
-        }
289
-        _set_cron_array($crons);
290
-    }
291
-
292
-
293
-    /**
294
-     *    CPT_initialization
295
-     *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
296
-     *
297
-     * @access public
298
-     * @static
299
-     * @return void
300
-     */
301
-    public static function CPT_initialization()
302
-    {
303
-        // register Custom Post Types
304
-        EE_Registry::instance()->load_core('Register_CPTs');
305
-        flush_rewrite_rules();
306
-    }
307
-
308
-
309
-
310
-    /**
311
-     *    reset_and_update_config
312
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
313
-     * If there is old calendar config data saved, then it will get converted on activation.
314
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
315
-     *
316
-     * @access public
317
-     * @static
318
-     * @return void
319
-     */
320
-    public static function reset_and_update_config()
321
-    {
322
-        do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
323
-        add_filter(
324
-            'FHEE__EE_Config___load_core_config__config_settings',
325
-            array('EEH_Activation', 'migrate_old_config_data'),
326
-            10,
327
-            3
328
-        );
329
-        //EE_Config::reset();
330
-        if (! EE_Config::logging_enabled()) {
331
-            delete_option(EE_Config::LOG_NAME);
332
-        }
333
-    }
334
-
335
-
336
-    /**
337
-     *    load_calendar_config
338
-     *
339
-     * @access    public
340
-     * @return    void
341
-     */
342
-    public static function load_calendar_config()
343
-    {
344
-        // grab array of all plugin folders and loop thru it
345
-        $plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
346
-        if (empty($plugins)) {
347
-            return;
348
-        }
349
-        foreach ($plugins as $plugin_path) {
350
-            // grab plugin folder name from path
351
-            $plugin = basename($plugin_path);
352
-            // drill down to Espresso plugins
353
-            // then to calendar related plugins
354
-            if (
355
-                strpos($plugin, 'espresso') !== false
356
-                || strpos($plugin, 'Espresso') !== false
357
-                || strpos($plugin, 'ee4') !== false
358
-                || strpos($plugin, 'EE4') !== false
359
-                || strpos($plugin, 'calendar') !== false
360
-            ) {
361
-                // this is what we are looking for
362
-                $calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
363
-                // does it exist in this folder ?
364
-                if (is_readable($calendar_config)) {
365
-                    // YEAH! let's load it
366
-                    require_once($calendar_config);
367
-                }
368
-            }
369
-        }
370
-    }
371
-
372
-
373
-
374
-    /**
375
-     *    _migrate_old_config_data
376
-     *
377
-     * @access    public
378
-     * @param array|stdClass $settings
379
-     * @param string         $config
380
-     * @param \EE_Config     $EE_Config
381
-     * @return \stdClass
382
-     */
383
-    public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
384
-    {
385
-        $convert_from_array = array('addons');
386
-        // in case old settings were saved as an array
387
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
388
-            // convert existing settings to an object
389
-            $config_array = $settings;
390
-            $settings = new stdClass();
391
-            foreach ($config_array as $key => $value) {
392
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
393
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
394
-                } else {
395
-                    $settings->{$key} = $value;
396
-                }
397
-            }
398
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
399
-        }
400
-        return $settings;
401
-    }
402
-
403
-
404
-    /**
405
-     * deactivate_event_espresso
406
-     *
407
-     * @access public
408
-     * @static
409
-     * @return void
410
-     */
411
-    public static function deactivate_event_espresso()
412
-    {
413
-        // check permissions
414
-        if (current_user_can('activate_plugins')) {
415
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
416
-        }
417
-    }
418
-
419
-
420
-
421
-
422
-
423
-    /**
424
-     * verify_default_pages_exist
425
-     *
426
-     * @access public
427
-     * @static
428
-     * @return void
429
-     */
430
-    public static function verify_default_pages_exist()
431
-    {
432
-        $critical_page_problem = false;
433
-        $critical_pages = array(
434
-            array(
435
-                'id'   => 'reg_page_id',
436
-                'name' => __('Registration Checkout', 'event_espresso'),
437
-                'post' => null,
438
-                'code' => 'ESPRESSO_CHECKOUT',
439
-            ),
440
-            array(
441
-                'id'   => 'txn_page_id',
442
-                'name' => __('Transactions', 'event_espresso'),
443
-                'post' => null,
444
-                'code' => 'ESPRESSO_TXN_PAGE',
445
-            ),
446
-            array(
447
-                'id'   => 'thank_you_page_id',
448
-                'name' => __('Thank You', 'event_espresso'),
449
-                'post' => null,
450
-                'code' => 'ESPRESSO_THANK_YOU',
451
-            ),
452
-            array(
453
-                'id'   => 'cancel_page_id',
454
-                'name' => __('Registration Cancelled', 'event_espresso'),
455
-                'post' => null,
456
-                'code' => 'ESPRESSO_CANCELLED',
457
-            ),
458
-        );
459
-        $EE_Core_Config = EE_Registry::instance()->CFG->core;
460
-        foreach ($critical_pages as $critical_page) {
461
-            // is critical page ID set in config ?
462
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
463
-                // attempt to find post by ID
464
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
465
-            }
466
-            // no dice?
467
-            if ($critical_page['post'] === null) {
468
-                // attempt to find post by title
469
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
470
-                // still nothing?
471
-                if ($critical_page['post'] === null) {
472
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
473
-                    // REALLY? Still nothing ??!?!?
474
-                    if ($critical_page['post'] === null) {
475
-                        $msg = __(
476
-                            'The Event Espresso critical page configuration settings could not be updated.',
477
-                            'event_espresso'
478
-                        );
479
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
480
-                        break;
481
-                    }
482
-                }
483
-            }
484
-            // check that Post ID matches critical page ID in config
485
-            if (
486
-                isset($critical_page['post']->ID)
487
-                && $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
488
-            ) {
489
-                //update Config with post ID
490
-                $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
491
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
492
-                    $msg = __(
493
-                        'The Event Espresso critical page configuration settings could not be updated.',
494
-                        'event_espresso'
495
-                    );
496
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
497
-                }
498
-            }
499
-            $critical_page_problem =
500
-                ! isset($critical_page['post']->post_status)
501
-                || $critical_page['post']->post_status !== 'publish'
502
-                || strpos($critical_page['post']->post_content, $critical_page['code']) === false
503
-                    ? true
504
-                    : $critical_page_problem;
505
-        }
506
-        if ($critical_page_problem) {
507
-            $msg = sprintf(
508
-                __(
509
-                    'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
510
-                    'event_espresso'
511
-                ),
512
-                '<a href="'
513
-                . admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
514
-                . '">'
515
-                . __('Event Espresso Critical Pages Settings', 'event_espresso')
516
-                . '</a>'
517
-            );
518
-            EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
519
-        }
520
-        if (EE_Error::has_notices()) {
521
-            EE_Error::get_notices(false, true, true);
522
-        }
523
-    }
524
-
525
-
526
-
527
-    /**
528
-     * Returns the first post which uses the specified shortcode
529
-     *
530
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
531
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
532
-     *                             "[ESPRESSO_THANK_YOU"
533
-     *                             (we don't search for the closing shortcode bracket because they might have added
534
-     *                             parameter to the shortcode
535
-     * @return WP_Post or NULl
536
-     */
537
-    public static function get_page_by_ee_shortcode($ee_shortcode)
538
-    {
539
-        global $wpdb;
540
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
541
-        $post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
542
-        if ($post_id) {
543
-            return get_post($post_id);
544
-        } else {
545
-            return null;
546
-        }
547
-    }
548
-
549
-
550
-    /**
551
-     *    This function generates a post for critical espresso pages
552
-     *
553
-     * @access public
554
-     * @static
555
-     * @param array $critical_page
556
-     * @return array
557
-     */
558
-    public static function create_critical_page($critical_page)
559
-    {
560
-
561
-        $post_args = array(
562
-            'post_title'     => $critical_page['name'],
563
-            'post_status'    => 'publish',
564
-            'post_type'      => 'page',
565
-            'comment_status' => 'closed',
566
-            'post_content'   => '[' . $critical_page['code'] . ']',
567
-        );
568
-
569
-        $post_id = wp_insert_post($post_args);
570
-        if (! $post_id) {
571
-            $msg = sprintf(
572
-                __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
573
-                $critical_page['name']
574
-            );
575
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
576
-            return $critical_page;
577
-        }
578
-        // get newly created post's details
579
-        if (! $critical_page['post'] = get_post($post_id)) {
580
-            $msg = sprintf(
581
-                __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
582
-                $critical_page['name']
583
-            );
584
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
585
-        }
586
-
587
-        return $critical_page;
588
-
589
-    }
590
-
591
-
592
-
593
-
594
-    /**
595
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
596
-     * The role being used to check is filterable.
597
-     *
598
-     * @since  4.6.0
599
-     * @global WPDB $wpdb
600
-     * @return mixed null|int WP_user ID or NULL
601
-     */
602
-    public static function get_default_creator_id()
603
-    {
604
-        global $wpdb;
605
-        if ( ! empty(self::$_default_creator_id)) {
606
-            return self::$_default_creator_id;
607
-        }/**/
608
-        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
609
-        //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.
610
-        $pre_filtered_id = apply_filters(
611
-            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
612
-            false,
613
-            $role_to_check
614
-        );
615
-        if ($pre_filtered_id !== false) {
616
-            return (int)$pre_filtered_id;
617
-        }
618
-        $capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
619
-        $query = $wpdb->prepare(
620
-            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
621
-            '%' . $role_to_check . '%'
622
-        );
623
-        $user_id = $wpdb->get_var($query);
624
-        $user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
625
-        if ($user_id && (int)$user_id) {
626
-            self::$_default_creator_id = (int)$user_id;
627
-            return self::$_default_creator_id;
628
-        } else {
629
-            return null;
630
-        }
631
-    }
632
-
633
-
634
-
635
-    /**
636
-     * used by EE and EE addons during plugin activation to create tables.
637
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
638
-     * but includes extra logic regarding activations.
639
-     *
640
-     * @access public
641
-     * @static
642
-     * @param string  $table_name              without the $wpdb->prefix
643
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
644
-     *                                         table query)
645
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
646
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
647
-     *                                         and new once this function is done (ie, you really do want to CREATE a
648
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
649
-     *                                         you just want to verify the table exists and matches this definition
650
-     *                                         (and if it HAS data in it you want to leave it be)
651
-     * @return void
652
-     * @throws EE_Error if there are database errors
653
-     */
654
-    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
655
-    {
656
-        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
657
-            return;
658
-        }
659
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
660
-        if ( ! function_exists('dbDelta')) {
661
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
662
-        }
663
-        $tableAnalysis = \EEH_Activation::getTableAnalysis();
664
-        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
665
-        // do we need to first delete an existing version of this table ?
666
-        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
667
-            // ok, delete the table... but ONLY if it's empty
668
-            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
669
-            // table is NOT empty, are you SURE you want to delete this table ???
670
-            if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
671
-                \EEH_Activation::getTableManager()->dropTable($wp_table_name);
672
-            } else if ( ! $deleted_safely) {
673
-                // so we should be more cautious rather than just dropping tables so easily
674
-                error_log(
675
-                    sprintf(
676
-                        __(
677
-                            '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.',
678
-                            'event_espresso'
679
-                        ),
680
-                        $wp_table_name,
681
-                        '<br/>',
682
-                        'espresso_db_update'
683
-                    )
684
-                );
685
-            }
686
-        }
687
-        $engine = str_replace('ENGINE=', '', $engine);
688
-        \EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
689
-    }
690
-
691
-
692
-
693
-    /**
694
-     *    add_column_if_it_doesn't_exist
695
-     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
696
-     *
697
-     * @access     public
698
-     * @static
699
-     * @deprecated instead use TableManager::addColumn()
700
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
701
-     * @param string $column_name
702
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
703
-     *                            'VARCHAR(10)'
704
-     * @return bool|int
705
-     */
706
-    public static function add_column_if_it_doesnt_exist(
707
-        $table_name,
708
-        $column_name,
709
-        $column_info = 'INT UNSIGNED NOT NULL'
710
-    ) {
711
-        return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
712
-    }
713
-
714
-
715
-    /**
716
-     * get_fields_on_table
717
-     * Gets all the fields on the database table.
718
-     *
719
-     * @access     public
720
-     * @deprecated instead use TableManager::getTableColumns()
721
-     * @static
722
-     * @param string $table_name , without prefixed $wpdb->prefix
723
-     * @return array of database column names
724
-     */
725
-    public static function get_fields_on_table($table_name = null)
726
-    {
727
-        return \EEH_Activation::getTableManager()->getTableColumns($table_name);
728
-    }
729
-
730
-
731
-    /**
732
-     * db_table_is_empty
733
-     *
734
-     * @access     public\
735
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
736
-     * @static
737
-     * @param string $table_name
738
-     * @return bool
739
-     */
740
-    public static function db_table_is_empty($table_name)
741
-    {
742
-        return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
743
-    }
744
-
745
-
746
-    /**
747
-     * delete_db_table_if_empty
748
-     *
749
-     * @access public
750
-     * @static
751
-     * @param string $table_name
752
-     * @return bool | int
753
-     */
754
-    public static function delete_db_table_if_empty($table_name)
755
-    {
756
-        if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
757
-            return \EEH_Activation::getTableManager()->dropTable($table_name);
758
-        }
759
-        return false;
760
-    }
761
-
762
-
763
-    /**
764
-     * delete_unused_db_table
765
-     *
766
-     * @access     public
767
-     * @static
768
-     * @deprecated instead use TableManager::dropTable()
769
-     * @param string $table_name
770
-     * @return bool | int
771
-     */
772
-    public static function delete_unused_db_table($table_name)
773
-    {
774
-        return \EEH_Activation::getTableManager()->dropTable($table_name);
775
-    }
776
-
777
-
778
-    /**
779
-     * drop_index
780
-     *
781
-     * @access     public
782
-     * @static
783
-     * @deprecated instead use TableManager::dropIndex()
784
-     * @param string $table_name
785
-     * @param string $index_name
786
-     * @return bool | int
787
-     */
788
-    public static function drop_index($table_name, $index_name)
789
-    {
790
-        return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
791
-    }
792
-
793
-
794
-
795
-    /**
796
-     * create_database_tables
797
-     *
798
-     * @access public
799
-     * @static
800
-     * @throws EE_Error
801
-     * @return boolean success (whether database is setup properly or not)
802
-     */
803
-    public static function create_database_tables()
804
-    {
805
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
806
-        //find the migration script that sets the database to be compatible with the code
807
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
808
-        if ($dms_name) {
809
-            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
810
-            $current_data_migration_script->set_migrating(false);
811
-            $current_data_migration_script->schema_changes_before_migration();
812
-            $current_data_migration_script->schema_changes_after_migration();
813
-            if ($current_data_migration_script->get_errors()) {
814
-                if (WP_DEBUG) {
815
-                    foreach ($current_data_migration_script->get_errors() as $error) {
816
-                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
817
-                    }
818
-                } else {
819
-                    EE_Error::add_error(
820
-                        __(
821
-                            'There were errors creating the Event Espresso database tables and Event Espresso has been 
273
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
274
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
275
+			if (is_array($hooks_to_fire_at_time)) {
276
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
277
+					if (isset($ee_cron_tasks_to_remove[$hook_name])
278
+						&& is_array($ee_cron_tasks_to_remove[$hook_name])
279
+					) {
280
+						unset($crons[$timestamp][$hook_name]);
281
+					}
282
+				}
283
+				//also take care of any empty cron timestamps.
284
+				if (empty($hooks_to_fire_at_time)) {
285
+					unset($crons[$timestamp]);
286
+				}
287
+			}
288
+		}
289
+		_set_cron_array($crons);
290
+	}
291
+
292
+
293
+	/**
294
+	 *    CPT_initialization
295
+	 *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
296
+	 *
297
+	 * @access public
298
+	 * @static
299
+	 * @return void
300
+	 */
301
+	public static function CPT_initialization()
302
+	{
303
+		// register Custom Post Types
304
+		EE_Registry::instance()->load_core('Register_CPTs');
305
+		flush_rewrite_rules();
306
+	}
307
+
308
+
309
+
310
+	/**
311
+	 *    reset_and_update_config
312
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
313
+	 * If there is old calendar config data saved, then it will get converted on activation.
314
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
315
+	 *
316
+	 * @access public
317
+	 * @static
318
+	 * @return void
319
+	 */
320
+	public static function reset_and_update_config()
321
+	{
322
+		do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
323
+		add_filter(
324
+			'FHEE__EE_Config___load_core_config__config_settings',
325
+			array('EEH_Activation', 'migrate_old_config_data'),
326
+			10,
327
+			3
328
+		);
329
+		//EE_Config::reset();
330
+		if (! EE_Config::logging_enabled()) {
331
+			delete_option(EE_Config::LOG_NAME);
332
+		}
333
+	}
334
+
335
+
336
+	/**
337
+	 *    load_calendar_config
338
+	 *
339
+	 * @access    public
340
+	 * @return    void
341
+	 */
342
+	public static function load_calendar_config()
343
+	{
344
+		// grab array of all plugin folders and loop thru it
345
+		$plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
346
+		if (empty($plugins)) {
347
+			return;
348
+		}
349
+		foreach ($plugins as $plugin_path) {
350
+			// grab plugin folder name from path
351
+			$plugin = basename($plugin_path);
352
+			// drill down to Espresso plugins
353
+			// then to calendar related plugins
354
+			if (
355
+				strpos($plugin, 'espresso') !== false
356
+				|| strpos($plugin, 'Espresso') !== false
357
+				|| strpos($plugin, 'ee4') !== false
358
+				|| strpos($plugin, 'EE4') !== false
359
+				|| strpos($plugin, 'calendar') !== false
360
+			) {
361
+				// this is what we are looking for
362
+				$calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
363
+				// does it exist in this folder ?
364
+				if (is_readable($calendar_config)) {
365
+					// YEAH! let's load it
366
+					require_once($calendar_config);
367
+				}
368
+			}
369
+		}
370
+	}
371
+
372
+
373
+
374
+	/**
375
+	 *    _migrate_old_config_data
376
+	 *
377
+	 * @access    public
378
+	 * @param array|stdClass $settings
379
+	 * @param string         $config
380
+	 * @param \EE_Config     $EE_Config
381
+	 * @return \stdClass
382
+	 */
383
+	public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
384
+	{
385
+		$convert_from_array = array('addons');
386
+		// in case old settings were saved as an array
387
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
388
+			// convert existing settings to an object
389
+			$config_array = $settings;
390
+			$settings = new stdClass();
391
+			foreach ($config_array as $key => $value) {
392
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
393
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
394
+				} else {
395
+					$settings->{$key} = $value;
396
+				}
397
+			}
398
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
399
+		}
400
+		return $settings;
401
+	}
402
+
403
+
404
+	/**
405
+	 * deactivate_event_espresso
406
+	 *
407
+	 * @access public
408
+	 * @static
409
+	 * @return void
410
+	 */
411
+	public static function deactivate_event_espresso()
412
+	{
413
+		// check permissions
414
+		if (current_user_can('activate_plugins')) {
415
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
416
+		}
417
+	}
418
+
419
+
420
+
421
+
422
+
423
+	/**
424
+	 * verify_default_pages_exist
425
+	 *
426
+	 * @access public
427
+	 * @static
428
+	 * @return void
429
+	 */
430
+	public static function verify_default_pages_exist()
431
+	{
432
+		$critical_page_problem = false;
433
+		$critical_pages = array(
434
+			array(
435
+				'id'   => 'reg_page_id',
436
+				'name' => __('Registration Checkout', 'event_espresso'),
437
+				'post' => null,
438
+				'code' => 'ESPRESSO_CHECKOUT',
439
+			),
440
+			array(
441
+				'id'   => 'txn_page_id',
442
+				'name' => __('Transactions', 'event_espresso'),
443
+				'post' => null,
444
+				'code' => 'ESPRESSO_TXN_PAGE',
445
+			),
446
+			array(
447
+				'id'   => 'thank_you_page_id',
448
+				'name' => __('Thank You', 'event_espresso'),
449
+				'post' => null,
450
+				'code' => 'ESPRESSO_THANK_YOU',
451
+			),
452
+			array(
453
+				'id'   => 'cancel_page_id',
454
+				'name' => __('Registration Cancelled', 'event_espresso'),
455
+				'post' => null,
456
+				'code' => 'ESPRESSO_CANCELLED',
457
+			),
458
+		);
459
+		$EE_Core_Config = EE_Registry::instance()->CFG->core;
460
+		foreach ($critical_pages as $critical_page) {
461
+			// is critical page ID set in config ?
462
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
463
+				// attempt to find post by ID
464
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
465
+			}
466
+			// no dice?
467
+			if ($critical_page['post'] === null) {
468
+				// attempt to find post by title
469
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
470
+				// still nothing?
471
+				if ($critical_page['post'] === null) {
472
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
473
+					// REALLY? Still nothing ??!?!?
474
+					if ($critical_page['post'] === null) {
475
+						$msg = __(
476
+							'The Event Espresso critical page configuration settings could not be updated.',
477
+							'event_espresso'
478
+						);
479
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
480
+						break;
481
+					}
482
+				}
483
+			}
484
+			// check that Post ID matches critical page ID in config
485
+			if (
486
+				isset($critical_page['post']->ID)
487
+				&& $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
488
+			) {
489
+				//update Config with post ID
490
+				$EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
491
+				if (! EE_Config::instance()->update_espresso_config(false, false)) {
492
+					$msg = __(
493
+						'The Event Espresso critical page configuration settings could not be updated.',
494
+						'event_espresso'
495
+					);
496
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
497
+				}
498
+			}
499
+			$critical_page_problem =
500
+				! isset($critical_page['post']->post_status)
501
+				|| $critical_page['post']->post_status !== 'publish'
502
+				|| strpos($critical_page['post']->post_content, $critical_page['code']) === false
503
+					? true
504
+					: $critical_page_problem;
505
+		}
506
+		if ($critical_page_problem) {
507
+			$msg = sprintf(
508
+				__(
509
+					'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
510
+					'event_espresso'
511
+				),
512
+				'<a href="'
513
+				. admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
514
+				. '">'
515
+				. __('Event Espresso Critical Pages Settings', 'event_espresso')
516
+				. '</a>'
517
+			);
518
+			EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
519
+		}
520
+		if (EE_Error::has_notices()) {
521
+			EE_Error::get_notices(false, true, true);
522
+		}
523
+	}
524
+
525
+
526
+
527
+	/**
528
+	 * Returns the first post which uses the specified shortcode
529
+	 *
530
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
531
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
532
+	 *                             "[ESPRESSO_THANK_YOU"
533
+	 *                             (we don't search for the closing shortcode bracket because they might have added
534
+	 *                             parameter to the shortcode
535
+	 * @return WP_Post or NULl
536
+	 */
537
+	public static function get_page_by_ee_shortcode($ee_shortcode)
538
+	{
539
+		global $wpdb;
540
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
541
+		$post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
542
+		if ($post_id) {
543
+			return get_post($post_id);
544
+		} else {
545
+			return null;
546
+		}
547
+	}
548
+
549
+
550
+	/**
551
+	 *    This function generates a post for critical espresso pages
552
+	 *
553
+	 * @access public
554
+	 * @static
555
+	 * @param array $critical_page
556
+	 * @return array
557
+	 */
558
+	public static function create_critical_page($critical_page)
559
+	{
560
+
561
+		$post_args = array(
562
+			'post_title'     => $critical_page['name'],
563
+			'post_status'    => 'publish',
564
+			'post_type'      => 'page',
565
+			'comment_status' => 'closed',
566
+			'post_content'   => '[' . $critical_page['code'] . ']',
567
+		);
568
+
569
+		$post_id = wp_insert_post($post_args);
570
+		if (! $post_id) {
571
+			$msg = sprintf(
572
+				__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
573
+				$critical_page['name']
574
+			);
575
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
576
+			return $critical_page;
577
+		}
578
+		// get newly created post's details
579
+		if (! $critical_page['post'] = get_post($post_id)) {
580
+			$msg = sprintf(
581
+				__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
582
+				$critical_page['name']
583
+			);
584
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
585
+		}
586
+
587
+		return $critical_page;
588
+
589
+	}
590
+
591
+
592
+
593
+
594
+	/**
595
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
596
+	 * The role being used to check is filterable.
597
+	 *
598
+	 * @since  4.6.0
599
+	 * @global WPDB $wpdb
600
+	 * @return mixed null|int WP_user ID or NULL
601
+	 */
602
+	public static function get_default_creator_id()
603
+	{
604
+		global $wpdb;
605
+		if ( ! empty(self::$_default_creator_id)) {
606
+			return self::$_default_creator_id;
607
+		}/**/
608
+		$role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
609
+		//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.
610
+		$pre_filtered_id = apply_filters(
611
+			'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
612
+			false,
613
+			$role_to_check
614
+		);
615
+		if ($pre_filtered_id !== false) {
616
+			return (int)$pre_filtered_id;
617
+		}
618
+		$capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
619
+		$query = $wpdb->prepare(
620
+			"SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
621
+			'%' . $role_to_check . '%'
622
+		);
623
+		$user_id = $wpdb->get_var($query);
624
+		$user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
625
+		if ($user_id && (int)$user_id) {
626
+			self::$_default_creator_id = (int)$user_id;
627
+			return self::$_default_creator_id;
628
+		} else {
629
+			return null;
630
+		}
631
+	}
632
+
633
+
634
+
635
+	/**
636
+	 * used by EE and EE addons during plugin activation to create tables.
637
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
638
+	 * but includes extra logic regarding activations.
639
+	 *
640
+	 * @access public
641
+	 * @static
642
+	 * @param string  $table_name              without the $wpdb->prefix
643
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
644
+	 *                                         table query)
645
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
646
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
647
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
648
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
649
+	 *                                         you just want to verify the table exists and matches this definition
650
+	 *                                         (and if it HAS data in it you want to leave it be)
651
+	 * @return void
652
+	 * @throws EE_Error if there are database errors
653
+	 */
654
+	public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
655
+	{
656
+		if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
657
+			return;
658
+		}
659
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
660
+		if ( ! function_exists('dbDelta')) {
661
+			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
662
+		}
663
+		$tableAnalysis = \EEH_Activation::getTableAnalysis();
664
+		$wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
665
+		// do we need to first delete an existing version of this table ?
666
+		if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
667
+			// ok, delete the table... but ONLY if it's empty
668
+			$deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
669
+			// table is NOT empty, are you SURE you want to delete this table ???
670
+			if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
671
+				\EEH_Activation::getTableManager()->dropTable($wp_table_name);
672
+			} else if ( ! $deleted_safely) {
673
+				// so we should be more cautious rather than just dropping tables so easily
674
+				error_log(
675
+					sprintf(
676
+						__(
677
+							'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.',
678
+							'event_espresso'
679
+						),
680
+						$wp_table_name,
681
+						'<br/>',
682
+						'espresso_db_update'
683
+					)
684
+				);
685
+			}
686
+		}
687
+		$engine = str_replace('ENGINE=', '', $engine);
688
+		\EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
689
+	}
690
+
691
+
692
+
693
+	/**
694
+	 *    add_column_if_it_doesn't_exist
695
+	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
696
+	 *
697
+	 * @access     public
698
+	 * @static
699
+	 * @deprecated instead use TableManager::addColumn()
700
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
701
+	 * @param string $column_name
702
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
703
+	 *                            'VARCHAR(10)'
704
+	 * @return bool|int
705
+	 */
706
+	public static function add_column_if_it_doesnt_exist(
707
+		$table_name,
708
+		$column_name,
709
+		$column_info = 'INT UNSIGNED NOT NULL'
710
+	) {
711
+		return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
712
+	}
713
+
714
+
715
+	/**
716
+	 * get_fields_on_table
717
+	 * Gets all the fields on the database table.
718
+	 *
719
+	 * @access     public
720
+	 * @deprecated instead use TableManager::getTableColumns()
721
+	 * @static
722
+	 * @param string $table_name , without prefixed $wpdb->prefix
723
+	 * @return array of database column names
724
+	 */
725
+	public static function get_fields_on_table($table_name = null)
726
+	{
727
+		return \EEH_Activation::getTableManager()->getTableColumns($table_name);
728
+	}
729
+
730
+
731
+	/**
732
+	 * db_table_is_empty
733
+	 *
734
+	 * @access     public\
735
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
736
+	 * @static
737
+	 * @param string $table_name
738
+	 * @return bool
739
+	 */
740
+	public static function db_table_is_empty($table_name)
741
+	{
742
+		return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
743
+	}
744
+
745
+
746
+	/**
747
+	 * delete_db_table_if_empty
748
+	 *
749
+	 * @access public
750
+	 * @static
751
+	 * @param string $table_name
752
+	 * @return bool | int
753
+	 */
754
+	public static function delete_db_table_if_empty($table_name)
755
+	{
756
+		if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
757
+			return \EEH_Activation::getTableManager()->dropTable($table_name);
758
+		}
759
+		return false;
760
+	}
761
+
762
+
763
+	/**
764
+	 * delete_unused_db_table
765
+	 *
766
+	 * @access     public
767
+	 * @static
768
+	 * @deprecated instead use TableManager::dropTable()
769
+	 * @param string $table_name
770
+	 * @return bool | int
771
+	 */
772
+	public static function delete_unused_db_table($table_name)
773
+	{
774
+		return \EEH_Activation::getTableManager()->dropTable($table_name);
775
+	}
776
+
777
+
778
+	/**
779
+	 * drop_index
780
+	 *
781
+	 * @access     public
782
+	 * @static
783
+	 * @deprecated instead use TableManager::dropIndex()
784
+	 * @param string $table_name
785
+	 * @param string $index_name
786
+	 * @return bool | int
787
+	 */
788
+	public static function drop_index($table_name, $index_name)
789
+	{
790
+		return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
791
+	}
792
+
793
+
794
+
795
+	/**
796
+	 * create_database_tables
797
+	 *
798
+	 * @access public
799
+	 * @static
800
+	 * @throws EE_Error
801
+	 * @return boolean success (whether database is setup properly or not)
802
+	 */
803
+	public static function create_database_tables()
804
+	{
805
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
806
+		//find the migration script that sets the database to be compatible with the code
807
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
808
+		if ($dms_name) {
809
+			$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
810
+			$current_data_migration_script->set_migrating(false);
811
+			$current_data_migration_script->schema_changes_before_migration();
812
+			$current_data_migration_script->schema_changes_after_migration();
813
+			if ($current_data_migration_script->get_errors()) {
814
+				if (WP_DEBUG) {
815
+					foreach ($current_data_migration_script->get_errors() as $error) {
816
+						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
817
+					}
818
+				} else {
819
+					EE_Error::add_error(
820
+						__(
821
+							'There were errors creating the Event Espresso database tables and Event Espresso has been 
822 822
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
823
-                            'event_espresso'
824
-                        )
825
-                    );
826
-                }
827
-                return false;
828
-            }
829
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
830
-        } else {
831
-            EE_Error::add_error(
832
-                __(
833
-                    'Could not determine most up-to-date data migration script from which to pull database schema
823
+							'event_espresso'
824
+						)
825
+					);
826
+				}
827
+				return false;
828
+			}
829
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
830
+		} else {
831
+			EE_Error::add_error(
832
+				__(
833
+					'Could not determine most up-to-date data migration script from which to pull database schema
834 834
                      structure. So database is probably not setup properly',
835
-                    'event_espresso'
836
-                ),
837
-                __FILE__,
838
-                __FUNCTION__,
839
-                __LINE__
840
-            );
841
-            return false;
842
-        }
843
-        return true;
844
-    }
845
-
846
-
847
-
848
-    /**
849
-     * initialize_system_questions
850
-     *
851
-     * @access public
852
-     * @static
853
-     * @return void
854
-     */
855
-    public static function initialize_system_questions()
856
-    {
857
-        // QUESTION GROUPS
858
-        global $wpdb;
859
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
860
-        $SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
861
-        // what we have
862
-        $question_groups = $wpdb->get_col($SQL);
863
-        // check the response
864
-        $question_groups = is_array($question_groups) ? $question_groups : array();
865
-        // what we should have
866
-        $QSG_systems = array(1, 2);
867
-        // loop thru what we should have and compare to what we have
868
-        foreach ($QSG_systems as $QSG_system) {
869
-            // reset values array
870
-            $QSG_values = array();
871
-            // 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)
872
-            if (! in_array("$QSG_system", $question_groups)) {
873
-                // add it
874
-                switch ($QSG_system) {
875
-                    case 1:
876
-                        $QSG_values = array(
877
-                            'QSG_name'            => __('Personal Information', 'event_espresso'),
878
-                            'QSG_identifier'      => 'personal-information-' . time(),
879
-                            'QSG_desc'            => '',
880
-                            'QSG_order'           => 1,
881
-                            'QSG_show_group_name' => 1,
882
-                            'QSG_show_group_desc' => 1,
883
-                            'QSG_system'          => EEM_Question_Group::system_personal,
884
-                            'QSG_deleted'         => 0,
885
-                        );
886
-                        break;
887
-                    case 2:
888
-                        $QSG_values = array(
889
-                            'QSG_name'            => __('Address Information', 'event_espresso'),
890
-                            'QSG_identifier'      => 'address-information-' . time(),
891
-                            'QSG_desc'            => '',
892
-                            'QSG_order'           => 2,
893
-                            'QSG_show_group_name' => 1,
894
-                            'QSG_show_group_desc' => 1,
895
-                            'QSG_system'          => EEM_Question_Group::system_address,
896
-                            'QSG_deleted'         => 0,
897
-                        );
898
-                        break;
899
-                }
900
-                // make sure we have some values before inserting them
901
-                if (! empty($QSG_values)) {
902
-                    // insert system question
903
-                    $wpdb->insert(
904
-                        $table_name,
905
-                        $QSG_values,
906
-                        array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
907
-                    );
908
-                    $QSG_IDs[$QSG_system] = $wpdb->insert_id;
909
-                }
910
-            }
911
-        }
912
-        // QUESTIONS
913
-        global $wpdb;
914
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
915
-        $SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
916
-        // what we have
917
-        $questions = $wpdb->get_col($SQL);
918
-        // what we should have
919
-        $QST_systems = array(
920
-            'fname',
921
-            'lname',
922
-            'email',
923
-            'address',
924
-            'address2',
925
-            'city',
926
-            'country',
927
-            'state',
928
-            'zip',
929
-            'phone',
930
-        );
931
-        $order_for_group_1 = 1;
932
-        $order_for_group_2 = 1;
933
-        // loop thru what we should have and compare to what we have
934
-        foreach ($QST_systems as $QST_system) {
935
-            // reset values array
936
-            $QST_values = array();
937
-            // if we don't have what we should have
938
-            if (! in_array($QST_system, $questions)) {
939
-                // add it
940
-                switch ($QST_system) {
941
-                    case 'fname':
942
-                        $QST_values = array(
943
-                            'QST_display_text'  => __('First Name', 'event_espresso'),
944
-                            'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
945
-                            'QST_system'        => 'fname',
946
-                            'QST_type'          => 'TEXT',
947
-                            'QST_required'      => 1,
948
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
949
-                            'QST_order'         => 1,
950
-                            'QST_admin_only'    => 0,
951
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
952
-                            'QST_wp_user'       => self::get_default_creator_id(),
953
-                            'QST_deleted'       => 0,
954
-                        );
955
-                        break;
956
-                    case 'lname':
957
-                        $QST_values = array(
958
-                            'QST_display_text'  => __('Last Name', 'event_espresso'),
959
-                            'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
960
-                            'QST_system'        => 'lname',
961
-                            'QST_type'          => 'TEXT',
962
-                            'QST_required'      => 1,
963
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
964
-                            'QST_order'         => 2,
965
-                            'QST_admin_only'    => 0,
966
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
967
-                            'QST_wp_user'       => self::get_default_creator_id(),
968
-                            'QST_deleted'       => 0,
969
-                        );
970
-                        break;
971
-                    case 'email':
972
-                        $QST_values = array(
973
-                            'QST_display_text'  => __('Email Address', 'event_espresso'),
974
-                            'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
975
-                            'QST_system'        => 'email',
976
-                            'QST_type'          => 'EMAIL',
977
-                            'QST_required'      => 1,
978
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
979
-                            'QST_order'         => 3,
980
-                            'QST_admin_only'    => 0,
981
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
982
-                            'QST_wp_user'       => self::get_default_creator_id(),
983
-                            'QST_deleted'       => 0,
984
-                        );
985
-                        break;
986
-                    case 'address':
987
-                        $QST_values = array(
988
-                            'QST_display_text'  => __('Address', 'event_espresso'),
989
-                            'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
990
-                            'QST_system'        => 'address',
991
-                            'QST_type'          => 'TEXT',
992
-                            'QST_required'      => 0,
993
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
994
-                            'QST_order'         => 4,
995
-                            'QST_admin_only'    => 0,
996
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
997
-                            'QST_wp_user'       => self::get_default_creator_id(),
998
-                            'QST_deleted'       => 0,
999
-                        );
1000
-                        break;
1001
-                    case 'address2':
1002
-                        $QST_values = array(
1003
-                            'QST_display_text'  => __('Address2', 'event_espresso'),
1004
-                            'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1005
-                            'QST_system'        => 'address2',
1006
-                            'QST_type'          => 'TEXT',
1007
-                            'QST_required'      => 0,
1008
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1009
-                            'QST_order'         => 5,
1010
-                            'QST_admin_only'    => 0,
1011
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1012
-                            'QST_wp_user'       => self::get_default_creator_id(),
1013
-                            'QST_deleted'       => 0,
1014
-                        );
1015
-                        break;
1016
-                    case 'city':
1017
-                        $QST_values = array(
1018
-                            'QST_display_text'  => __('City', 'event_espresso'),
1019
-                            'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1020
-                            'QST_system'        => 'city',
1021
-                            'QST_type'          => 'TEXT',
1022
-                            'QST_required'      => 0,
1023
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1024
-                            'QST_order'         => 6,
1025
-                            'QST_admin_only'    => 0,
1026
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1027
-                            'QST_wp_user'       => self::get_default_creator_id(),
1028
-                            'QST_deleted'       => 0,
1029
-                        );
1030
-                        break;
1031
-                    case 'country':
1032
-                        $QST_values = array(
1033
-                            'QST_display_text'  => __('Country', 'event_espresso'),
1034
-                            'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1035
-                            'QST_system'        => 'country',
1036
-                            'QST_type'          => 'COUNTRY',
1037
-                            'QST_required'      => 0,
1038
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1039
-                            'QST_order'         => 7,
1040
-                            'QST_admin_only'    => 0,
1041
-                            'QST_wp_user'       => self::get_default_creator_id(),
1042
-                            'QST_deleted'       => 0,
1043
-                        );
1044
-                        break;
1045
-                    case 'state':
1046
-                        $QST_values = array(
1047
-                            'QST_display_text'  => __('State/Province', 'event_espresso'),
1048
-                            'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1049
-                            'QST_system'        => 'state',
1050
-                            'QST_type'          => 'STATE',
1051
-                            'QST_required'      => 0,
1052
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1053
-                            'QST_order'         => 8,
1054
-                            'QST_admin_only'    => 0,
1055
-                            'QST_wp_user'       => self::get_default_creator_id(),
1056
-                            'QST_deleted'       => 0,
1057
-                        );
1058
-                        break;
1059
-                    case 'zip':
1060
-                        $QST_values = array(
1061
-                            'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1062
-                            'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1063
-                            'QST_system'        => 'zip',
1064
-                            'QST_type'          => 'TEXT',
1065
-                            'QST_required'      => 0,
1066
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1067
-                            'QST_order'         => 9,
1068
-                            'QST_admin_only'    => 0,
1069
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1070
-                            'QST_wp_user'       => self::get_default_creator_id(),
1071
-                            'QST_deleted'       => 0,
1072
-                        );
1073
-                        break;
1074
-                    case 'phone':
1075
-                        $QST_values = array(
1076
-                            'QST_display_text'  => __('Phone Number', 'event_espresso'),
1077
-                            'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1078
-                            'QST_system'        => 'phone',
1079
-                            'QST_type'          => 'TEXT',
1080
-                            'QST_required'      => 0,
1081
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1082
-                            'QST_order'         => 10,
1083
-                            'QST_admin_only'    => 0,
1084
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1085
-                            'QST_wp_user'       => self::get_default_creator_id(),
1086
-                            'QST_deleted'       => 0,
1087
-                        );
1088
-                        break;
1089
-                }
1090
-                if (! empty($QST_values)) {
1091
-                    // insert system question
1092
-                    $wpdb->insert(
1093
-                        $table_name,
1094
-                        $QST_values,
1095
-                        array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1096
-                    );
1097
-                    $QST_ID = $wpdb->insert_id;
1098
-                    // QUESTION GROUP QUESTIONS
1099
-                    if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1100
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1101
-                    } else {
1102
-                        $system_question_we_want = EEM_Question_Group::system_address;
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
835
+					'event_espresso'
836
+				),
837
+				__FILE__,
838
+				__FUNCTION__,
839
+				__LINE__
840
+			);
841
+			return false;
842
+		}
843
+		return true;
844
+	}
845
+
846
+
847
+
848
+	/**
849
+	 * initialize_system_questions
850
+	 *
851
+	 * @access public
852
+	 * @static
853
+	 * @return void
854
+	 */
855
+	public static function initialize_system_questions()
856
+	{
857
+		// QUESTION GROUPS
858
+		global $wpdb;
859
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
860
+		$SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
861
+		// what we have
862
+		$question_groups = $wpdb->get_col($SQL);
863
+		// check the response
864
+		$question_groups = is_array($question_groups) ? $question_groups : array();
865
+		// what we should have
866
+		$QSG_systems = array(1, 2);
867
+		// loop thru what we should have and compare to what we have
868
+		foreach ($QSG_systems as $QSG_system) {
869
+			// reset values array
870
+			$QSG_values = array();
871
+			// 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)
872
+			if (! in_array("$QSG_system", $question_groups)) {
873
+				// add it
874
+				switch ($QSG_system) {
875
+					case 1:
876
+						$QSG_values = array(
877
+							'QSG_name'            => __('Personal Information', 'event_espresso'),
878
+							'QSG_identifier'      => 'personal-information-' . time(),
879
+							'QSG_desc'            => '',
880
+							'QSG_order'           => 1,
881
+							'QSG_show_group_name' => 1,
882
+							'QSG_show_group_desc' => 1,
883
+							'QSG_system'          => EEM_Question_Group::system_personal,
884
+							'QSG_deleted'         => 0,
885
+						);
886
+						break;
887
+					case 2:
888
+						$QSG_values = array(
889
+							'QSG_name'            => __('Address Information', 'event_espresso'),
890
+							'QSG_identifier'      => 'address-information-' . time(),
891
+							'QSG_desc'            => '',
892
+							'QSG_order'           => 2,
893
+							'QSG_show_group_name' => 1,
894
+							'QSG_show_group_desc' => 1,
895
+							'QSG_system'          => EEM_Question_Group::system_address,
896
+							'QSG_deleted'         => 0,
897
+						);
898
+						break;
899
+				}
900
+				// make sure we have some values before inserting them
901
+				if (! empty($QSG_values)) {
902
+					// insert system question
903
+					$wpdb->insert(
904
+						$table_name,
905
+						$QSG_values,
906
+						array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
907
+					);
908
+					$QSG_IDs[$QSG_system] = $wpdb->insert_id;
909
+				}
910
+			}
911
+		}
912
+		// QUESTIONS
913
+		global $wpdb;
914
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
915
+		$SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
916
+		// what we have
917
+		$questions = $wpdb->get_col($SQL);
918
+		// what we should have
919
+		$QST_systems = array(
920
+			'fname',
921
+			'lname',
922
+			'email',
923
+			'address',
924
+			'address2',
925
+			'city',
926
+			'country',
927
+			'state',
928
+			'zip',
929
+			'phone',
930
+		);
931
+		$order_for_group_1 = 1;
932
+		$order_for_group_2 = 1;
933
+		// loop thru what we should have and compare to what we have
934
+		foreach ($QST_systems as $QST_system) {
935
+			// reset values array
936
+			$QST_values = array();
937
+			// if we don't have what we should have
938
+			if (! in_array($QST_system, $questions)) {
939
+				// add it
940
+				switch ($QST_system) {
941
+					case 'fname':
942
+						$QST_values = array(
943
+							'QST_display_text'  => __('First Name', 'event_espresso'),
944
+							'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
945
+							'QST_system'        => 'fname',
946
+							'QST_type'          => 'TEXT',
947
+							'QST_required'      => 1,
948
+							'QST_required_text' => __('This field is required', 'event_espresso'),
949
+							'QST_order'         => 1,
950
+							'QST_admin_only'    => 0,
951
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
952
+							'QST_wp_user'       => self::get_default_creator_id(),
953
+							'QST_deleted'       => 0,
954
+						);
955
+						break;
956
+					case 'lname':
957
+						$QST_values = array(
958
+							'QST_display_text'  => __('Last Name', 'event_espresso'),
959
+							'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
960
+							'QST_system'        => 'lname',
961
+							'QST_type'          => 'TEXT',
962
+							'QST_required'      => 1,
963
+							'QST_required_text' => __('This field is required', 'event_espresso'),
964
+							'QST_order'         => 2,
965
+							'QST_admin_only'    => 0,
966
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
967
+							'QST_wp_user'       => self::get_default_creator_id(),
968
+							'QST_deleted'       => 0,
969
+						);
970
+						break;
971
+					case 'email':
972
+						$QST_values = array(
973
+							'QST_display_text'  => __('Email Address', 'event_espresso'),
974
+							'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
975
+							'QST_system'        => 'email',
976
+							'QST_type'          => 'EMAIL',
977
+							'QST_required'      => 1,
978
+							'QST_required_text' => __('This field is required', 'event_espresso'),
979
+							'QST_order'         => 3,
980
+							'QST_admin_only'    => 0,
981
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
982
+							'QST_wp_user'       => self::get_default_creator_id(),
983
+							'QST_deleted'       => 0,
984
+						);
985
+						break;
986
+					case 'address':
987
+						$QST_values = array(
988
+							'QST_display_text'  => __('Address', 'event_espresso'),
989
+							'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
990
+							'QST_system'        => 'address',
991
+							'QST_type'          => 'TEXT',
992
+							'QST_required'      => 0,
993
+							'QST_required_text' => __('This field is required', 'event_espresso'),
994
+							'QST_order'         => 4,
995
+							'QST_admin_only'    => 0,
996
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
997
+							'QST_wp_user'       => self::get_default_creator_id(),
998
+							'QST_deleted'       => 0,
999
+						);
1000
+						break;
1001
+					case 'address2':
1002
+						$QST_values = array(
1003
+							'QST_display_text'  => __('Address2', 'event_espresso'),
1004
+							'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1005
+							'QST_system'        => 'address2',
1006
+							'QST_type'          => 'TEXT',
1007
+							'QST_required'      => 0,
1008
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1009
+							'QST_order'         => 5,
1010
+							'QST_admin_only'    => 0,
1011
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1012
+							'QST_wp_user'       => self::get_default_creator_id(),
1013
+							'QST_deleted'       => 0,
1014
+						);
1015
+						break;
1016
+					case 'city':
1017
+						$QST_values = array(
1018
+							'QST_display_text'  => __('City', 'event_espresso'),
1019
+							'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1020
+							'QST_system'        => 'city',
1021
+							'QST_type'          => 'TEXT',
1022
+							'QST_required'      => 0,
1023
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1024
+							'QST_order'         => 6,
1025
+							'QST_admin_only'    => 0,
1026
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1027
+							'QST_wp_user'       => self::get_default_creator_id(),
1028
+							'QST_deleted'       => 0,
1029
+						);
1030
+						break;
1031
+					case 'country':
1032
+						$QST_values = array(
1033
+							'QST_display_text'  => __('Country', 'event_espresso'),
1034
+							'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1035
+							'QST_system'        => 'country',
1036
+							'QST_type'          => 'COUNTRY',
1037
+							'QST_required'      => 0,
1038
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1039
+							'QST_order'         => 7,
1040
+							'QST_admin_only'    => 0,
1041
+							'QST_wp_user'       => self::get_default_creator_id(),
1042
+							'QST_deleted'       => 0,
1043
+						);
1044
+						break;
1045
+					case 'state':
1046
+						$QST_values = array(
1047
+							'QST_display_text'  => __('State/Province', 'event_espresso'),
1048
+							'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1049
+							'QST_system'        => 'state',
1050
+							'QST_type'          => 'STATE',
1051
+							'QST_required'      => 0,
1052
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1053
+							'QST_order'         => 8,
1054
+							'QST_admin_only'    => 0,
1055
+							'QST_wp_user'       => self::get_default_creator_id(),
1056
+							'QST_deleted'       => 0,
1057
+						);
1058
+						break;
1059
+					case 'zip':
1060
+						$QST_values = array(
1061
+							'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1062
+							'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1063
+							'QST_system'        => 'zip',
1064
+							'QST_type'          => 'TEXT',
1065
+							'QST_required'      => 0,
1066
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1067
+							'QST_order'         => 9,
1068
+							'QST_admin_only'    => 0,
1069
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1070
+							'QST_wp_user'       => self::get_default_creator_id(),
1071
+							'QST_deleted'       => 0,
1072
+						);
1073
+						break;
1074
+					case 'phone':
1075
+						$QST_values = array(
1076
+							'QST_display_text'  => __('Phone Number', 'event_espresso'),
1077
+							'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1078
+							'QST_system'        => 'phone',
1079
+							'QST_type'          => 'TEXT',
1080
+							'QST_required'      => 0,
1081
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1082
+							'QST_order'         => 10,
1083
+							'QST_admin_only'    => 0,
1084
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1085
+							'QST_wp_user'       => self::get_default_creator_id(),
1086
+							'QST_deleted'       => 0,
1087
+						);
1088
+						break;
1089
+				}
1090
+				if (! empty($QST_values)) {
1091
+					// insert system question
1092
+					$wpdb->insert(
1093
+						$table_name,
1094
+						$QST_values,
1095
+						array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1096
+					);
1097
+					$QST_ID = $wpdb->insert_id;
1098
+					// QUESTION GROUP QUESTIONS
1099
+					if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1100
+						$system_question_we_want = EEM_Question_Group::system_personal;
1101
+					} else {
1102
+						$system_question_we_want = EEM_Question_Group::system_address;
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
-                                'error');
1124
-                            continue;
1125
-                        }
1126
-                    }
1127
-                    // add system questions to groups
1128
-                    $wpdb->insert(
1129
-                        \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1130
-                        array(
1131
-                            'QSG_ID'    => $QSG_ID,
1132
-                            'QST_ID'    => $QST_ID,
1133
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1134
-                        ),
1135
-                        array('%d', '%d', '%d')
1136
-                    );
1137
-                }
1138
-            }
1139
-        }
1140
-    }
1141
-
1142
-
1143
-    /**
1144
-     * Makes sure the default payment method (Invoice) is active.
1145
-     * This used to be done automatically as part of constructing the old gateways config
1146
-     *
1147
-     * @throws \EE_Error
1148
-     */
1149
-    public static function insert_default_payment_methods()
1150
-    {
1151
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1152
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1153
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1154
-        } else {
1155
-            EEM_Payment_Method::instance()->verify_button_urls();
1156
-        }
1157
-    }
1158
-
1159
-    /**
1160
-     * insert_default_status_codes
1161
-     *
1162
-     * @access public
1163
-     * @static
1164
-     * @return void
1165
-     */
1166
-    public static function insert_default_status_codes()
1167
-    {
1168
-
1169
-        global $wpdb;
1170
-
1171
-        if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1172
-
1173
-            $table_name = EEM_Status::instance()->table();
1174
-
1175
-            $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' );";
1176
-            $wpdb->query($SQL);
1177
-
1178
-            $SQL = "INSERT INTO $table_name
1120
+										'event_espresso'
1121
+									),
1122
+									$QST_ID),
1123
+								'error');
1124
+							continue;
1125
+						}
1126
+					}
1127
+					// add system questions to groups
1128
+					$wpdb->insert(
1129
+						\EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1130
+						array(
1131
+							'QSG_ID'    => $QSG_ID,
1132
+							'QST_ID'    => $QST_ID,
1133
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1134
+						),
1135
+						array('%d', '%d', '%d')
1136
+					);
1137
+				}
1138
+			}
1139
+		}
1140
+	}
1141
+
1142
+
1143
+	/**
1144
+	 * Makes sure the default payment method (Invoice) is active.
1145
+	 * This used to be done automatically as part of constructing the old gateways config
1146
+	 *
1147
+	 * @throws \EE_Error
1148
+	 */
1149
+	public static function insert_default_payment_methods()
1150
+	{
1151
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1152
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1153
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1154
+		} else {
1155
+			EEM_Payment_Method::instance()->verify_button_urls();
1156
+		}
1157
+	}
1158
+
1159
+	/**
1160
+	 * insert_default_status_codes
1161
+	 *
1162
+	 * @access public
1163
+	 * @static
1164
+	 * @return void
1165
+	 */
1166
+	public static function insert_default_status_codes()
1167
+	{
1168
+
1169
+		global $wpdb;
1170
+
1171
+		if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1172
+
1173
+			$table_name = EEM_Status::instance()->table();
1174
+
1175
+			$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' );";
1176
+			$wpdb->query($SQL);
1177
+
1178
+			$SQL = "INSERT INTO $table_name
1179 1179
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1180 1180
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1181 1181
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1215,521 +1215,521 @@  discard block
 block discarded – undo
1215 1215
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1216 1216
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1217 1217
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1218
-            $wpdb->query($SQL);
1219
-
1220
-        }
1221
-
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     * create_upload_directories
1227
-     * Creates folders in the uploads directory to facilitate addons and templates
1228
-     *
1229
-     * @access public
1230
-     * @static
1231
-     * @return boolean success of verifying upload directories exist
1232
-     */
1233
-    public static function create_upload_directories()
1234
-    {
1235
-        // Create the required folders
1236
-        $folders = array(
1237
-            EVENT_ESPRESSO_TEMPLATE_DIR,
1238
-            EVENT_ESPRESSO_GATEWAY_DIR,
1239
-            EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1240
-            EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1241
-            EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1242
-        );
1243
-        foreach ($folders as $folder) {
1244
-            try {
1245
-                EEH_File::ensure_folder_exists_and_is_writable($folder);
1246
-                @ chmod($folder, 0755);
1247
-            } catch (EE_Error $e) {
1248
-                EE_Error::add_error(
1249
-                    sprintf(
1250
-                        __('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1251
-                        $folder,
1252
-                        '<br />' . $e->getMessage()
1253
-                    ),
1254
-                    __FILE__, __FUNCTION__, __LINE__
1255
-                );
1256
-                //indicate we'll need to fix this later
1257
-                update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1258
-                return false;
1259
-            }
1260
-        }
1261
-        //just add the .htaccess file to the logs directory to begin with. Even if logging
1262
-        //is disabled, there might be activation errors recorded in there
1263
-        EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1264
-        //remember EE's folders are all good
1265
-        delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1266
-        return true;
1267
-    }
1268
-
1269
-    /**
1270
-     * Whether the upload directories need to be fixed or not.
1271
-     * If EE is installed but filesystem access isn't initially available,
1272
-     * we need to get the user's filesystem credentials and THEN create them,
1273
-     * so there might be period of time when EE is installed but its
1274
-     * upload directories aren't available. This indicates such a state
1275
-     *
1276
-     * @return boolean
1277
-     */
1278
-    public static function upload_directories_incomplete()
1279
-    {
1280
-        return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1281
-    }
1282
-
1283
-
1284
-    /**
1285
-     * generate_default_message_templates
1286
-     *
1287
-     * @static
1288
-     * @throws EE_Error
1289
-     * @return bool     true means new templates were created.
1290
-     *                  false means no templates were created.
1291
-     *                  This is NOT an error flag. To check for errors you will want
1292
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1293
-     */
1294
-    public static function generate_default_message_templates()
1295
-    {
1296
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1297
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1298
-        /*
1218
+			$wpdb->query($SQL);
1219
+
1220
+		}
1221
+
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 * create_upload_directories
1227
+	 * Creates folders in the uploads directory to facilitate addons and templates
1228
+	 *
1229
+	 * @access public
1230
+	 * @static
1231
+	 * @return boolean success of verifying upload directories exist
1232
+	 */
1233
+	public static function create_upload_directories()
1234
+	{
1235
+		// Create the required folders
1236
+		$folders = array(
1237
+			EVENT_ESPRESSO_TEMPLATE_DIR,
1238
+			EVENT_ESPRESSO_GATEWAY_DIR,
1239
+			EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1240
+			EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1241
+			EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1242
+		);
1243
+		foreach ($folders as $folder) {
1244
+			try {
1245
+				EEH_File::ensure_folder_exists_and_is_writable($folder);
1246
+				@ chmod($folder, 0755);
1247
+			} catch (EE_Error $e) {
1248
+				EE_Error::add_error(
1249
+					sprintf(
1250
+						__('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1251
+						$folder,
1252
+						'<br />' . $e->getMessage()
1253
+					),
1254
+					__FILE__, __FUNCTION__, __LINE__
1255
+				);
1256
+				//indicate we'll need to fix this later
1257
+				update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1258
+				return false;
1259
+			}
1260
+		}
1261
+		//just add the .htaccess file to the logs directory to begin with. Even if logging
1262
+		//is disabled, there might be activation errors recorded in there
1263
+		EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1264
+		//remember EE's folders are all good
1265
+		delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1266
+		return true;
1267
+	}
1268
+
1269
+	/**
1270
+	 * Whether the upload directories need to be fixed or not.
1271
+	 * If EE is installed but filesystem access isn't initially available,
1272
+	 * we need to get the user's filesystem credentials and THEN create them,
1273
+	 * so there might be period of time when EE is installed but its
1274
+	 * upload directories aren't available. This indicates such a state
1275
+	 *
1276
+	 * @return boolean
1277
+	 */
1278
+	public static function upload_directories_incomplete()
1279
+	{
1280
+		return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1281
+	}
1282
+
1283
+
1284
+	/**
1285
+	 * generate_default_message_templates
1286
+	 *
1287
+	 * @static
1288
+	 * @throws EE_Error
1289
+	 * @return bool     true means new templates were created.
1290
+	 *                  false means no templates were created.
1291
+	 *                  This is NOT an error flag. To check for errors you will want
1292
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1293
+	 */
1294
+	public static function generate_default_message_templates()
1295
+	{
1296
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1297
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1298
+		/*
1299 1299
          * This first method is taking care of ensuring any default messengers
1300 1300
          * that should be made active and have templates generated are done.
1301 1301
          */
1302
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1303
-            $message_resource_manager
1304
-        );
1305
-        /**
1306
-         * This method is verifying there are no NEW default message types
1307
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1308
-         */
1309
-        $new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1310
-            $message_resource_manager
1311
-        );
1312
-        //after all is done, let's persist these changes to the db.
1313
-        $message_resource_manager->update_has_activated_messengers_option();
1314
-        $message_resource_manager->update_active_messengers_option();
1315
-        // will return true if either of these are true.  Otherwise will return false.
1316
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1317
-    }
1318
-
1319
-
1320
-
1321
-    /**
1322
-     * @param \EE_Message_Resource_Manager $message_resource_manager
1323
-     * @return array|bool
1324
-     * @throws \EE_Error
1325
-     */
1326
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1327
-        EE_Message_Resource_Manager $message_resource_manager
1328
-    ) {
1329
-        /** @type EE_messenger[] $active_messengers */
1330
-        $active_messengers = $message_resource_manager->active_messengers();
1331
-        $installed_message_types = $message_resource_manager->installed_message_types();
1332
-        $templates_created = false;
1333
-        foreach ($active_messengers as $active_messenger) {
1334
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1335
-            $default_message_type_names_to_activate = array();
1336
-            // looping through each default message type reported by the messenger
1337
-            // and setup the actual message types to activate.
1338
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1339
-                // if already active or has already been activated before we skip
1340
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1341
-                // we also skip if the message type is not installed.
1342
-                if (
1343
-                    $message_resource_manager->has_message_type_been_activated_for_messenger(
1344
-                        $default_message_type_name_for_messenger,
1345
-                        $active_messenger->name
1346
-                    )
1347
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1348
-                        $active_messenger->name,
1349
-                        $default_message_type_name_for_messenger
1350
-                    )
1351
-                    || ! isset($installed_message_types[$default_message_type_name_for_messenger])
1352
-                ) {
1353
-                    continue;
1354
-                }
1355
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1356
-            }
1357
-            //let's activate!
1358
-            $message_resource_manager->ensure_message_types_are_active(
1359
-                $default_message_type_names_to_activate,
1360
-                $active_messenger->name,
1361
-                false
1362
-            );
1363
-            //activate the templates for these message types
1364
-            if ( ! empty($default_message_type_names_to_activate)) {
1365
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1366
-                    $active_messenger->name,
1367
-                    $default_message_type_names_for_messenger,
1368
-                    '',
1369
-                    true
1370
-                );
1371
-            }
1372
-        }
1373
-        return $templates_created;
1374
-    }
1375
-
1376
-
1377
-
1378
-    /**
1379
-     * This will activate and generate default messengers and default message types for those messengers.
1380
-     *
1381
-     * @param EE_message_Resource_Manager $message_resource_manager
1382
-     * @return array|bool  True means there were default messengers and message type templates generated.
1383
-     *                     False means that there were no templates generated
1384
-     *                     (which could simply mean there are no default message types for a messenger).
1385
-     * @throws EE_Error
1386
-     */
1387
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1388
-        EE_Message_Resource_Manager $message_resource_manager
1389
-    ) {
1390
-        /** @type EE_messenger[] $messengers_to_generate */
1391
-        $messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1392
-        $installed_message_types = $message_resource_manager->installed_message_types();
1393
-        $templates_generated = false;
1394
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1395
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1396
-            //verify the default message types match an installed message type.
1397
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1398
-                if (
1399
-                    ! isset($installed_message_types[$name])
1400
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1401
-                        $name,
1402
-                        $messenger_to_generate->name
1403
-                    )
1404
-                ) {
1405
-                    unset($default_message_type_names_for_messenger[$key]);
1406
-                }
1407
-            }
1408
-            // in previous iterations, the active_messengers option in the db
1409
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1410
-            // This comment is left here just in case we discover that we _do_ need to update before
1411
-            // passing off to create templates (after the refactor is done).
1412
-            // @todo remove this comment when determined not necessary.
1413
-            $message_resource_manager->activate_messenger(
1414
-                $messenger_to_generate->name,
1415
-                $default_message_type_names_for_messenger,
1416
-                false
1417
-            );
1418
-            //create any templates needing created (or will reactivate templates already generated as necessary).
1419
-            if ( ! empty($default_message_type_names_for_messenger)) {
1420
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1421
-                    $messenger_to_generate->name,
1422
-                    $default_message_type_names_for_messenger,
1423
-                    '',
1424
-                    true
1425
-                );
1426
-            }
1427
-        }
1428
-        return $templates_generated;
1429
-    }
1430
-
1431
-
1432
-    /**
1433
-     * This returns the default messengers to generate templates for on activation of EE.
1434
-     * It considers:
1435
-     * - whether a messenger is already active in the db.
1436
-     * - whether a messenger has been made active at any time in the past.
1437
-     *
1438
-     * @static
1439
-     * @param  EE_Message_Resource_Manager $message_resource_manager
1440
-     * @return EE_messenger[]
1441
-     */
1442
-    protected static function _get_default_messengers_to_generate_on_activation(
1443
-        EE_Message_Resource_Manager $message_resource_manager
1444
-    ) {
1445
-        $active_messengers    = $message_resource_manager->active_messengers();
1446
-        $installed_messengers = $message_resource_manager->installed_messengers();
1447
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1448
-
1449
-        $messengers_to_generate = array();
1450
-        foreach ($installed_messengers as $installed_messenger) {
1451
-            //if installed messenger is a messenger that should be activated on install
1452
-            //and is not already active
1453
-            //and has never been activated
1454
-            if (
1455
-                ! $installed_messenger->activate_on_install
1456
-                || isset($active_messengers[$installed_messenger->name])
1457
-                || isset($has_activated[$installed_messenger->name])
1458
-            ) {
1459
-                continue;
1460
-            }
1461
-            $messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1462
-        }
1463
-        return $messengers_to_generate;
1464
-    }
1465
-
1466
-
1467
-    /**
1468
-     * This simply validates active message types to ensure they actually match installed
1469
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1470
-     * rows are set inactive.
1471
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1472
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1473
-     * are still handled in here.
1474
-     *
1475
-     * @since 4.3.1
1476
-     * @return void
1477
-     */
1478
-    public static function validate_messages_system()
1479
-    {
1480
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1481
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1482
-        $message_resource_manager->validate_active_message_types_are_installed();
1483
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1484
-    }
1485
-
1486
-
1487
-    /**
1488
-     * create_no_ticket_prices_array
1489
-     *
1490
-     * @access public
1491
-     * @static
1492
-     * @return void
1493
-     */
1494
-    public static function create_no_ticket_prices_array()
1495
-    {
1496
-        // this creates an array for tracking events that have no active ticket prices created
1497
-        // this allows us to warn admins of the situation so that it can be corrected
1498
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1499
-        if (! $espresso_no_ticket_prices) {
1500
-            add_option('ee_no_ticket_prices', array(), '', false);
1501
-        }
1502
-    }
1503
-
1504
-
1505
-    /**
1506
-     * plugin_deactivation
1507
-     *
1508
-     * @access public
1509
-     * @static
1510
-     * @return void
1511
-     */
1512
-    public static function plugin_deactivation()
1513
-    {
1514
-    }
1515
-
1516
-
1517
-    /**
1518
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1519
-     * (like post meta or term relations)
1520
-     *
1521
-     * @global wpdb $wpdb
1522
-     * @throws \EE_Error
1523
-     */
1524
-    public static function delete_all_espresso_cpt_data()
1525
-    {
1526
-        global $wpdb;
1527
-        //get all the CPT post_types
1528
-        $ee_post_types = array();
1529
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1530
-            if (method_exists($model_name, 'instance')) {
1531
-                $model_obj = call_user_func(array($model_name, 'instance'));
1532
-                if ($model_obj instanceof EEM_CPT_Base) {
1533
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1534
-                }
1535
-            }
1536
-        }
1537
-        //get all our CPTs
1538
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1539
-        $cpt_ids = $wpdb->get_col($query);
1540
-        //delete each post meta and term relations too
1541
-        foreach ($cpt_ids as $post_id) {
1542
-            wp_delete_post($post_id, true);
1543
-        }
1544
-    }
1545
-
1546
-    /**
1547
-     * Deletes all EE custom tables
1548
-     *
1549
-     * @return array
1550
-     */
1551
-    public static function drop_espresso_tables()
1552
-    {
1553
-        $tables = array();
1554
-        // load registry
1555
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1556
-            if (method_exists($model_name, 'instance')) {
1557
-                $model_obj = call_user_func(array($model_name, 'instance'));
1558
-                if ($model_obj instanceof EEM_Base) {
1559
-                    foreach ($model_obj->get_tables() as $table) {
1560
-                        if (strpos($table->get_table_name(), 'esp_')
1561
-                            &&
1562
-                            (
1563
-                                is_main_site()//main site? nuke them all
1564
-                                || ! $table->is_global()//not main site,but not global either. nuke it
1565
-                            )
1566
-                        ) {
1567
-                            $tables[$table->get_table_name()] = $table->get_table_name();
1568
-                        }
1569
-                    }
1570
-                }
1571
-            }
1572
-        }
1573
-
1574
-        //there are some tables whose models were removed.
1575
-        //they should be removed when removing all EE core's data
1576
-        $tables_without_models = array(
1577
-            'esp_promotion',
1578
-            'esp_promotion_applied',
1579
-            'esp_promotion_object',
1580
-            'esp_promotion_rule',
1581
-            'esp_rule',
1582
-        );
1583
-        foreach ($tables_without_models as $table) {
1584
-            $tables[$table] = $table;
1585
-        }
1586
-        return \EEH_Activation::getTableManager()->dropTables($tables);
1587
-    }
1588
-
1589
-
1590
-
1591
-    /**
1592
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1593
-     * each table name provided has a wpdb prefix attached, and that it exists.
1594
-     * Returns the list actually deleted
1595
-     *
1596
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1597
-     * @global WPDB $wpdb
1598
-     * @param array $table_names
1599
-     * @return array of table names which we deleted
1600
-     */
1601
-    public static function drop_tables($table_names)
1602
-    {
1603
-        return \EEH_Activation::getTableManager()->dropTables($table_names);
1604
-    }
1605
-
1606
-
1607
-
1608
-    /**
1609
-     * plugin_uninstall
1610
-     *
1611
-     * @access public
1612
-     * @static
1613
-     * @param bool $remove_all
1614
-     * @return void
1615
-     */
1616
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1617
-    {
1618
-        global $wpdb;
1619
-        self::drop_espresso_tables();
1620
-        $wp_options_to_delete = array(
1621
-            'ee_no_ticket_prices'                => true,
1622
-            'ee_active_messengers'               => true,
1623
-            'ee_has_activated_messenger'         => true,
1624
-            'ee_flush_rewrite_rules'             => true,
1625
-            'ee_config'                          => false,
1626
-            'ee_data_migration_current_db_state' => true,
1627
-            'ee_data_migration_mapping_'         => false,
1628
-            'ee_data_migration_script_'          => false,
1629
-            'ee_data_migrations'                 => true,
1630
-            'ee_dms_map'                         => false,
1631
-            'ee_notices'                         => true,
1632
-            'lang_file_check_'                   => false,
1633
-            'ee_maintenance_mode'                => true,
1634
-            'ee_ueip_optin'                      => true,
1635
-            'ee_ueip_has_notified'               => true,
1636
-            'ee_plugin_activation_errors'        => true,
1637
-            'ee_id_mapping_from'                 => false,
1638
-            'espresso_persistent_admin_notices'  => true,
1639
-            'ee_encryption_key'                  => true,
1640
-            'pue_force_upgrade_'                 => false,
1641
-            'pue_json_error_'                    => false,
1642
-            'pue_install_key_'                   => false,
1643
-            'pue_verification_error_'            => false,
1644
-            'pu_dismissed_upgrade_'              => false,
1645
-            'external_updates-'                  => false,
1646
-            'ee_extra_data'                      => true,
1647
-            'ee_ssn_'                            => false,
1648
-            'ee_rss_'                            => false,
1649
-            'ee_rte_n_tx_'                       => false,
1650
-            'ee_pers_admin_notices'              => true,
1651
-            'ee_job_parameters_'                 => false,
1652
-            'ee_upload_directories_incomplete'   => true,
1653
-            'ee_verified_db_collations'          => true,
1654
-        );
1655
-        if (is_main_site()) {
1656
-            $wp_options_to_delete['ee_network_config'] = true;
1657
-        }
1658
-        $undeleted_options = array();
1659
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1660
-            if ($no_wildcard) {
1661
-                if ( ! delete_option($option_name)) {
1662
-                    $undeleted_options[] = $option_name;
1663
-                }
1664
-            } else {
1665
-                $option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1666
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1667
-                    if ( ! delete_option($option_name_from_wildcard)) {
1668
-                        $undeleted_options[] = $option_name_from_wildcard;
1669
-                    }
1670
-                }
1671
-            }
1672
-        }
1673
-        //also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1674
-        remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1675
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1676
-            $db_update_sans_ee4 = array();
1677
-            foreach ($espresso_db_update as $version => $times_activated) {
1678
-                if ((string)$version[0] === '3') {//if its NON EE4
1679
-                    $db_update_sans_ee4[$version] = $times_activated;
1680
-                }
1681
-            }
1682
-            update_option('espresso_db_update', $db_update_sans_ee4);
1683
-        }
1684
-        $errors = '';
1685
-        if ( ! empty($undeleted_options)) {
1686
-            $errors .= sprintf(
1687
-                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1688
-                '<br/>',
1689
-                implode(',<br/>', $undeleted_options)
1690
-            );
1691
-        }
1692
-        if ( ! empty($errors)) {
1693
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1694
-        }
1695
-    }
1696
-
1697
-    /**
1698
-     * Gets the mysql error code from the last used query by wpdb
1699
-     *
1700
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1701
-     */
1702
-    public static function last_wpdb_error_code()
1703
-    {
1704
-        global $wpdb;
1705
-        if ($wpdb->use_mysqli) {
1706
-            return mysqli_errno($wpdb->dbh);
1707
-        } else {
1708
-            return mysql_errno($wpdb->dbh);
1709
-        }
1710
-    }
1711
-
1712
-    /**
1713
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1714
-     *
1715
-     * @global wpdb  $wpdb
1716
-     * @deprecated instead use TableAnalysis::tableExists()
1717
-     * @param string $table_name with or without $wpdb->prefix
1718
-     * @return boolean
1719
-     */
1720
-    public static function table_exists($table_name)
1721
-    {
1722
-        return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1723
-    }
1724
-
1725
-    /**
1726
-     * Resets the cache on EEH_Activation
1727
-     */
1728
-    public static function reset()
1729
-    {
1730
-        self::$_default_creator_id                             = null;
1731
-        self::$_initialized_db_content_already_in_this_request = false;
1732
-    }
1302
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1303
+			$message_resource_manager
1304
+		);
1305
+		/**
1306
+		 * This method is verifying there are no NEW default message types
1307
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1308
+		 */
1309
+		$new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1310
+			$message_resource_manager
1311
+		);
1312
+		//after all is done, let's persist these changes to the db.
1313
+		$message_resource_manager->update_has_activated_messengers_option();
1314
+		$message_resource_manager->update_active_messengers_option();
1315
+		// will return true if either of these are true.  Otherwise will return false.
1316
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1317
+	}
1318
+
1319
+
1320
+
1321
+	/**
1322
+	 * @param \EE_Message_Resource_Manager $message_resource_manager
1323
+	 * @return array|bool
1324
+	 * @throws \EE_Error
1325
+	 */
1326
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1327
+		EE_Message_Resource_Manager $message_resource_manager
1328
+	) {
1329
+		/** @type EE_messenger[] $active_messengers */
1330
+		$active_messengers = $message_resource_manager->active_messengers();
1331
+		$installed_message_types = $message_resource_manager->installed_message_types();
1332
+		$templates_created = false;
1333
+		foreach ($active_messengers as $active_messenger) {
1334
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1335
+			$default_message_type_names_to_activate = array();
1336
+			// looping through each default message type reported by the messenger
1337
+			// and setup the actual message types to activate.
1338
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1339
+				// if already active or has already been activated before we skip
1340
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1341
+				// we also skip if the message type is not installed.
1342
+				if (
1343
+					$message_resource_manager->has_message_type_been_activated_for_messenger(
1344
+						$default_message_type_name_for_messenger,
1345
+						$active_messenger->name
1346
+					)
1347
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1348
+						$active_messenger->name,
1349
+						$default_message_type_name_for_messenger
1350
+					)
1351
+					|| ! isset($installed_message_types[$default_message_type_name_for_messenger])
1352
+				) {
1353
+					continue;
1354
+				}
1355
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1356
+			}
1357
+			//let's activate!
1358
+			$message_resource_manager->ensure_message_types_are_active(
1359
+				$default_message_type_names_to_activate,
1360
+				$active_messenger->name,
1361
+				false
1362
+			);
1363
+			//activate the templates for these message types
1364
+			if ( ! empty($default_message_type_names_to_activate)) {
1365
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1366
+					$active_messenger->name,
1367
+					$default_message_type_names_for_messenger,
1368
+					'',
1369
+					true
1370
+				);
1371
+			}
1372
+		}
1373
+		return $templates_created;
1374
+	}
1375
+
1376
+
1377
+
1378
+	/**
1379
+	 * This will activate and generate default messengers and default message types for those messengers.
1380
+	 *
1381
+	 * @param EE_message_Resource_Manager $message_resource_manager
1382
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1383
+	 *                     False means that there were no templates generated
1384
+	 *                     (which could simply mean there are no default message types for a messenger).
1385
+	 * @throws EE_Error
1386
+	 */
1387
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1388
+		EE_Message_Resource_Manager $message_resource_manager
1389
+	) {
1390
+		/** @type EE_messenger[] $messengers_to_generate */
1391
+		$messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1392
+		$installed_message_types = $message_resource_manager->installed_message_types();
1393
+		$templates_generated = false;
1394
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1395
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1396
+			//verify the default message types match an installed message type.
1397
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1398
+				if (
1399
+					! isset($installed_message_types[$name])
1400
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1401
+						$name,
1402
+						$messenger_to_generate->name
1403
+					)
1404
+				) {
1405
+					unset($default_message_type_names_for_messenger[$key]);
1406
+				}
1407
+			}
1408
+			// in previous iterations, the active_messengers option in the db
1409
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1410
+			// This comment is left here just in case we discover that we _do_ need to update before
1411
+			// passing off to create templates (after the refactor is done).
1412
+			// @todo remove this comment when determined not necessary.
1413
+			$message_resource_manager->activate_messenger(
1414
+				$messenger_to_generate->name,
1415
+				$default_message_type_names_for_messenger,
1416
+				false
1417
+			);
1418
+			//create any templates needing created (or will reactivate templates already generated as necessary).
1419
+			if ( ! empty($default_message_type_names_for_messenger)) {
1420
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1421
+					$messenger_to_generate->name,
1422
+					$default_message_type_names_for_messenger,
1423
+					'',
1424
+					true
1425
+				);
1426
+			}
1427
+		}
1428
+		return $templates_generated;
1429
+	}
1430
+
1431
+
1432
+	/**
1433
+	 * This returns the default messengers to generate templates for on activation of EE.
1434
+	 * It considers:
1435
+	 * - whether a messenger is already active in the db.
1436
+	 * - whether a messenger has been made active at any time in the past.
1437
+	 *
1438
+	 * @static
1439
+	 * @param  EE_Message_Resource_Manager $message_resource_manager
1440
+	 * @return EE_messenger[]
1441
+	 */
1442
+	protected static function _get_default_messengers_to_generate_on_activation(
1443
+		EE_Message_Resource_Manager $message_resource_manager
1444
+	) {
1445
+		$active_messengers    = $message_resource_manager->active_messengers();
1446
+		$installed_messengers = $message_resource_manager->installed_messengers();
1447
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1448
+
1449
+		$messengers_to_generate = array();
1450
+		foreach ($installed_messengers as $installed_messenger) {
1451
+			//if installed messenger is a messenger that should be activated on install
1452
+			//and is not already active
1453
+			//and has never been activated
1454
+			if (
1455
+				! $installed_messenger->activate_on_install
1456
+				|| isset($active_messengers[$installed_messenger->name])
1457
+				|| isset($has_activated[$installed_messenger->name])
1458
+			) {
1459
+				continue;
1460
+			}
1461
+			$messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1462
+		}
1463
+		return $messengers_to_generate;
1464
+	}
1465
+
1466
+
1467
+	/**
1468
+	 * This simply validates active message types to ensure they actually match installed
1469
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1470
+	 * rows are set inactive.
1471
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1472
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1473
+	 * are still handled in here.
1474
+	 *
1475
+	 * @since 4.3.1
1476
+	 * @return void
1477
+	 */
1478
+	public static function validate_messages_system()
1479
+	{
1480
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1481
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1482
+		$message_resource_manager->validate_active_message_types_are_installed();
1483
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1484
+	}
1485
+
1486
+
1487
+	/**
1488
+	 * create_no_ticket_prices_array
1489
+	 *
1490
+	 * @access public
1491
+	 * @static
1492
+	 * @return void
1493
+	 */
1494
+	public static function create_no_ticket_prices_array()
1495
+	{
1496
+		// this creates an array for tracking events that have no active ticket prices created
1497
+		// this allows us to warn admins of the situation so that it can be corrected
1498
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1499
+		if (! $espresso_no_ticket_prices) {
1500
+			add_option('ee_no_ticket_prices', array(), '', false);
1501
+		}
1502
+	}
1503
+
1504
+
1505
+	/**
1506
+	 * plugin_deactivation
1507
+	 *
1508
+	 * @access public
1509
+	 * @static
1510
+	 * @return void
1511
+	 */
1512
+	public static function plugin_deactivation()
1513
+	{
1514
+	}
1515
+
1516
+
1517
+	/**
1518
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1519
+	 * (like post meta or term relations)
1520
+	 *
1521
+	 * @global wpdb $wpdb
1522
+	 * @throws \EE_Error
1523
+	 */
1524
+	public static function delete_all_espresso_cpt_data()
1525
+	{
1526
+		global $wpdb;
1527
+		//get all the CPT post_types
1528
+		$ee_post_types = array();
1529
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1530
+			if (method_exists($model_name, 'instance')) {
1531
+				$model_obj = call_user_func(array($model_name, 'instance'));
1532
+				if ($model_obj instanceof EEM_CPT_Base) {
1533
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1534
+				}
1535
+			}
1536
+		}
1537
+		//get all our CPTs
1538
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1539
+		$cpt_ids = $wpdb->get_col($query);
1540
+		//delete each post meta and term relations too
1541
+		foreach ($cpt_ids as $post_id) {
1542
+			wp_delete_post($post_id, true);
1543
+		}
1544
+	}
1545
+
1546
+	/**
1547
+	 * Deletes all EE custom tables
1548
+	 *
1549
+	 * @return array
1550
+	 */
1551
+	public static function drop_espresso_tables()
1552
+	{
1553
+		$tables = array();
1554
+		// load registry
1555
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1556
+			if (method_exists($model_name, 'instance')) {
1557
+				$model_obj = call_user_func(array($model_name, 'instance'));
1558
+				if ($model_obj instanceof EEM_Base) {
1559
+					foreach ($model_obj->get_tables() as $table) {
1560
+						if (strpos($table->get_table_name(), 'esp_')
1561
+							&&
1562
+							(
1563
+								is_main_site()//main site? nuke them all
1564
+								|| ! $table->is_global()//not main site,but not global either. nuke it
1565
+							)
1566
+						) {
1567
+							$tables[$table->get_table_name()] = $table->get_table_name();
1568
+						}
1569
+					}
1570
+				}
1571
+			}
1572
+		}
1573
+
1574
+		//there are some tables whose models were removed.
1575
+		//they should be removed when removing all EE core's data
1576
+		$tables_without_models = array(
1577
+			'esp_promotion',
1578
+			'esp_promotion_applied',
1579
+			'esp_promotion_object',
1580
+			'esp_promotion_rule',
1581
+			'esp_rule',
1582
+		);
1583
+		foreach ($tables_without_models as $table) {
1584
+			$tables[$table] = $table;
1585
+		}
1586
+		return \EEH_Activation::getTableManager()->dropTables($tables);
1587
+	}
1588
+
1589
+
1590
+
1591
+	/**
1592
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1593
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1594
+	 * Returns the list actually deleted
1595
+	 *
1596
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1597
+	 * @global WPDB $wpdb
1598
+	 * @param array $table_names
1599
+	 * @return array of table names which we deleted
1600
+	 */
1601
+	public static function drop_tables($table_names)
1602
+	{
1603
+		return \EEH_Activation::getTableManager()->dropTables($table_names);
1604
+	}
1605
+
1606
+
1607
+
1608
+	/**
1609
+	 * plugin_uninstall
1610
+	 *
1611
+	 * @access public
1612
+	 * @static
1613
+	 * @param bool $remove_all
1614
+	 * @return void
1615
+	 */
1616
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1617
+	{
1618
+		global $wpdb;
1619
+		self::drop_espresso_tables();
1620
+		$wp_options_to_delete = array(
1621
+			'ee_no_ticket_prices'                => true,
1622
+			'ee_active_messengers'               => true,
1623
+			'ee_has_activated_messenger'         => true,
1624
+			'ee_flush_rewrite_rules'             => true,
1625
+			'ee_config'                          => false,
1626
+			'ee_data_migration_current_db_state' => true,
1627
+			'ee_data_migration_mapping_'         => false,
1628
+			'ee_data_migration_script_'          => false,
1629
+			'ee_data_migrations'                 => true,
1630
+			'ee_dms_map'                         => false,
1631
+			'ee_notices'                         => true,
1632
+			'lang_file_check_'                   => false,
1633
+			'ee_maintenance_mode'                => true,
1634
+			'ee_ueip_optin'                      => true,
1635
+			'ee_ueip_has_notified'               => true,
1636
+			'ee_plugin_activation_errors'        => true,
1637
+			'ee_id_mapping_from'                 => false,
1638
+			'espresso_persistent_admin_notices'  => true,
1639
+			'ee_encryption_key'                  => true,
1640
+			'pue_force_upgrade_'                 => false,
1641
+			'pue_json_error_'                    => false,
1642
+			'pue_install_key_'                   => false,
1643
+			'pue_verification_error_'            => false,
1644
+			'pu_dismissed_upgrade_'              => false,
1645
+			'external_updates-'                  => false,
1646
+			'ee_extra_data'                      => true,
1647
+			'ee_ssn_'                            => false,
1648
+			'ee_rss_'                            => false,
1649
+			'ee_rte_n_tx_'                       => false,
1650
+			'ee_pers_admin_notices'              => true,
1651
+			'ee_job_parameters_'                 => false,
1652
+			'ee_upload_directories_incomplete'   => true,
1653
+			'ee_verified_db_collations'          => true,
1654
+		);
1655
+		if (is_main_site()) {
1656
+			$wp_options_to_delete['ee_network_config'] = true;
1657
+		}
1658
+		$undeleted_options = array();
1659
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1660
+			if ($no_wildcard) {
1661
+				if ( ! delete_option($option_name)) {
1662
+					$undeleted_options[] = $option_name;
1663
+				}
1664
+			} else {
1665
+				$option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1666
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1667
+					if ( ! delete_option($option_name_from_wildcard)) {
1668
+						$undeleted_options[] = $option_name_from_wildcard;
1669
+					}
1670
+				}
1671
+			}
1672
+		}
1673
+		//also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1674
+		remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1675
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1676
+			$db_update_sans_ee4 = array();
1677
+			foreach ($espresso_db_update as $version => $times_activated) {
1678
+				if ((string)$version[0] === '3') {//if its NON EE4
1679
+					$db_update_sans_ee4[$version] = $times_activated;
1680
+				}
1681
+			}
1682
+			update_option('espresso_db_update', $db_update_sans_ee4);
1683
+		}
1684
+		$errors = '';
1685
+		if ( ! empty($undeleted_options)) {
1686
+			$errors .= sprintf(
1687
+				__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1688
+				'<br/>',
1689
+				implode(',<br/>', $undeleted_options)
1690
+			);
1691
+		}
1692
+		if ( ! empty($errors)) {
1693
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1694
+		}
1695
+	}
1696
+
1697
+	/**
1698
+	 * Gets the mysql error code from the last used query by wpdb
1699
+	 *
1700
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1701
+	 */
1702
+	public static function last_wpdb_error_code()
1703
+	{
1704
+		global $wpdb;
1705
+		if ($wpdb->use_mysqli) {
1706
+			return mysqli_errno($wpdb->dbh);
1707
+		} else {
1708
+			return mysql_errno($wpdb->dbh);
1709
+		}
1710
+	}
1711
+
1712
+	/**
1713
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1714
+	 *
1715
+	 * @global wpdb  $wpdb
1716
+	 * @deprecated instead use TableAnalysis::tableExists()
1717
+	 * @param string $table_name with or without $wpdb->prefix
1718
+	 * @return boolean
1719
+	 */
1720
+	public static function table_exists($table_name)
1721
+	{
1722
+		return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1723
+	}
1724
+
1725
+	/**
1726
+	 * Resets the cache on EEH_Activation
1727
+	 */
1728
+	public static function reset()
1729
+	{
1730
+		self::$_default_creator_id                             = null;
1731
+		self::$_initialized_db_content_already_in_this_request = false;
1732
+	}
1733 1733
 }
1734 1734
 // End of file EEH_Activation.helper.php
1735 1735
 // Location: /helpers/EEH_Activation.core.php
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Indentation   +1498 added lines, -1498 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
 
7 7
 
8 8
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
9
-    exit('No direct script access allowed');
9
+	exit('No direct script access allowed');
10 10
 }
11 11
 
12 12
 
@@ -23,1503 +23,1503 @@  discard block
 block discarded – undo
23 23
 {
24 24
 
25 25
 
26
-    /**
27
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
28
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
29
-     */
30
-    const req_type_normal = 0;
31
-
32
-    /**
33
-     * Indicates this is a brand new installation of EE so we should install
34
-     * tables and default data etc
35
-     */
36
-    const req_type_new_activation = 1;
37
-
38
-    /**
39
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
40
-     * and we just exited maintenance mode). We MUST check the database is setup properly
41
-     * and that default data is setup too
42
-     */
43
-    const req_type_reactivation = 2;
44
-
45
-    /**
46
-     * indicates that EE has been upgraded since its previous request.
47
-     * We may have data migration scripts to call and will want to trigger maintenance mode
48
-     */
49
-    const req_type_upgrade = 3;
50
-
51
-    /**
52
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
53
-     */
54
-    const req_type_downgrade = 4;
55
-
56
-    /**
57
-     * @deprecated since version 4.6.0.dev.006
58
-     * Now whenever a new_activation is detected the request type is still just
59
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
60
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
61
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
62
-     * (Specifically, when the migration manager indicates migrations are finished
63
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
64
-     */
65
-    const req_type_activation_but_not_installed = 5;
66
-
67
-    /**
68
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
69
-     */
70
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
71
-
72
-
73
-    /**
74
-     * @var EE_System $_instance
75
-     */
76
-    private static $_instance;
77
-
78
-    /**
79
-     * @var EE_Registry $registry
80
-     */
81
-    protected $registry;
82
-
83
-    /**
84
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
85
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
86
-     *
87
-     * @var int $_req_type
88
-     */
89
-    private $_req_type;
90
-
91
-    /**
92
-     * Whether or not there was a non-micro version change in EE core version during this request
93
-     *
94
-     * @var boolean $_major_version_change
95
-     */
96
-    private $_major_version_change = false;
97
-
98
-
99
-
100
-    /**
101
-     * @singleton method used to instantiate class object
102
-     * @access    public
103
-     * @param  EE_Registry $Registry
104
-     * @return EE_System
105
-     */
106
-    public static function instance(EE_Registry $Registry = null)
107
-    {
108
-        // check if class object is instantiated
109
-        if ( ! self::$_instance instanceof EE_System) {
110
-            self::$_instance = new self($Registry);
111
-        }
112
-        return self::$_instance;
113
-    }
114
-
115
-
116
-
117
-    /**
118
-     * resets the instance and returns it
119
-     *
120
-     * @return EE_System
121
-     */
122
-    public static function reset()
123
-    {
124
-        self::$_instance->_req_type = null;
125
-        //make sure none of the old hooks are left hanging around
126
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
127
-        //we need to reset the migration manager in order for it to detect DMSs properly
128
-        EE_Data_Migration_Manager::reset();
129
-        self::instance()->detect_activations_or_upgrades();
130
-        self::instance()->perform_activations_upgrades_and_migrations();
131
-        return self::instance();
132
-    }
133
-
134
-
135
-
136
-    /**
137
-     *    sets hooks for running rest of system
138
-     *    provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
139
-     *    starting EE Addons from any other point may lead to problems
140
-     *
141
-     * @access private
142
-     * @param  EE_Registry $Registry
143
-     */
144
-    private function __construct(EE_Registry $Registry)
145
-    {
146
-        $this->registry = $Registry;
147
-        do_action('AHEE__EE_System__construct__begin', $this);
148
-        add_action(
149
-            'AHEE__EE_Bootstrap__load_espresso_addons',
150
-            array($this, 'loadCapabilities'),
151
-            5
152
-        );
153
-        add_action(
154
-            'AHEE__EE_Bootstrap__load_espresso_addons',
155
-            array($this, 'loadCommandBus'),
156
-            7
157
-        );
158
-        add_action(
159
-            'AHEE__EE_Bootstrap__load_espresso_addons',
160
-            array($this, 'loadPluginApi'),
161
-            9
162
-        );
163
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
164
-        add_action(
165
-            'AHEE__EE_Bootstrap__load_espresso_addons',
166
-            array($this, 'load_espresso_addons')
167
-        );
168
-        // when an ee addon is activated, we want to call the core hook(s) again
169
-        // because the newly-activated addon didn't get a chance to run at all
170
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
171
-        // detect whether install or upgrade
172
-        add_action(
173
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
174
-            array($this, 'detect_activations_or_upgrades'),
175
-            3
176
-        );
177
-        // load EE_Config, EE_Textdomain, etc
178
-        add_action(
179
-            'AHEE__EE_Bootstrap__load_core_configuration',
180
-            array($this, 'load_core_configuration'),
181
-            5
182
-        );
183
-        // load EE_Config, EE_Textdomain, etc
184
-        add_action(
185
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
186
-            array($this, 'register_shortcodes_modules_and_widgets'),
187
-            7
188
-        );
189
-        // you wanna get going? I wanna get going... let's get going!
190
-        add_action(
191
-            'AHEE__EE_Bootstrap__brew_espresso',
192
-            array($this, 'brew_espresso'),
193
-            9
194
-        );
195
-        //other housekeeping
196
-        //exclude EE critical pages from wp_list_pages
197
-        add_filter(
198
-            'wp_list_pages_excludes',
199
-            array($this, 'remove_pages_from_wp_list_pages'),
200
-            10
201
-        );
202
-        // ALL EE Addons should use the following hook point to attach their initial setup too
203
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
204
-        do_action('AHEE__EE_System__construct__complete', $this);
205
-    }
206
-
207
-
208
-
209
-    /**
210
-     * load and setup EE_Capabilities
211
-     *
212
-     * @return void
213
-     * @throws EE_Error
214
-     */
215
-    public function loadCapabilities()
216
-    {
217
-        $this->registry->load_core('EE_Capabilities');
218
-        add_action(
219
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
220
-            function() {
221
-                EE_Registry::instance()->load_lib('Payment_Method_Manager');
222
-            }
223
-        );
224
-    }
225
-
226
-
227
-
228
-    /**
229
-     * create and cache the CommandBus, and also add middleware
230
-     * The CapChecker middleware requires the use of EE_Capabilities
231
-     * which is why we need to load the CommandBus after Caps are set up
232
-     *
233
-     * @return void
234
-     * @throws EE_Error
235
-     */
236
-    public function loadCommandBus()
237
-    {
238
-        $this->registry->create(
239
-            'CommandBusInterface',
240
-            array(
241
-                null,
242
-                apply_filters(
243
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
244
-                    array(
245
-                        $this->registry->create('CapChecker'),
246
-                        $this->registry->create('AddActionHook'),
247
-                    )
248
-                ),
249
-            ),
250
-            true
251
-        );
252
-    }
253
-
254
-
255
-
256
-    /**
257
-     * @return void
258
-     * @throws EE_Error
259
-     */
260
-    public function loadPluginApi()
261
-    {
262
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
263
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
264
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
265
-    }
266
-
267
-
268
-
269
-    /**
270
-     * load_espresso_addons
271
-     * allow addons to load first so that they can set hooks for running DMS's, etc
272
-     * this is hooked into both:
273
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
274
-     *        which runs during the WP 'plugins_loaded' action at priority 5
275
-     *    and the WP 'activate_plugin' hook point
276
-     *
277
-     * @access public
278
-     * @return void
279
-     * @throws EE_Error
280
-     */
281
-    public function load_espresso_addons()
282
-    {
283
-        do_action('AHEE__EE_System__load_espresso_addons');
284
-        //if the WP API basic auth plugin isn't already loaded, load it now.
285
-        //We want it for mobile apps. Just include the entire plugin
286
-        //also, don't load the basic auth when a plugin is getting activated, because
287
-        //it could be the basic auth plugin, and it doesn't check if its methods are already defined
288
-        //and causes a fatal error
289
-        if (
290
-            ! (isset($_GET['activate']) && $_GET['activate'] === 'true')
291
-            && ! function_exists('json_basic_auth_handler')
292
-            && ! function_exists('json_basic_auth_error')
293
-            && ! (
294
-                isset($_GET['action'])
295
-                && in_array($_GET['action'], array('activate', 'activate-selected'), true)
296
-            )
297
-        ) {
298
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
299
-        }
300
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
301
-    }
302
-
303
-
304
-
305
-    /**
306
-     * detect_activations_or_upgrades
307
-     * Checks for activation or upgrade of core first;
308
-     * then also checks if any registered addons have been activated or upgraded
309
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
310
-     * which runs during the WP 'plugins_loaded' action at priority 3
311
-     *
312
-     * @access public
313
-     * @return void
314
-     */
315
-    public function detect_activations_or_upgrades()
316
-    {
317
-        //first off: let's make sure to handle core
318
-        $this->detect_if_activation_or_upgrade();
319
-        foreach ($this->registry->addons as $addon) {
320
-            //detect teh request type for that addon
321
-            $addon->detect_activation_or_upgrade();
322
-        }
323
-    }
324
-
325
-
326
-
327
-    /**
328
-     * detect_if_activation_or_upgrade
329
-     * Takes care of detecting whether this is a brand new install or code upgrade,
330
-     * and either setting up the DB or setting up maintenance mode etc.
331
-     *
332
-     * @access public
333
-     * @return void
334
-     */
335
-    public function detect_if_activation_or_upgrade()
336
-    {
337
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
338
-        // load M-Mode class
339
-        $this->registry->load_core('Maintenance_Mode');
340
-        // check if db has been updated, or if its a brand-new installation
341
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
342
-        $request_type = $this->detect_req_type($espresso_db_update);
343
-        //EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
344
-        switch ($request_type) {
345
-            case EE_System::req_type_new_activation:
346
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
347
-                $this->_handle_core_version_change($espresso_db_update);
348
-                break;
349
-            case EE_System::req_type_reactivation:
350
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
351
-                $this->_handle_core_version_change($espresso_db_update);
352
-                break;
353
-            case EE_System::req_type_upgrade:
354
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
355
-                //migrations may be required now that we've upgraded
356
-                EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
357
-                $this->_handle_core_version_change($espresso_db_update);
358
-                //				echo "done upgrade";die;
359
-                break;
360
-            case EE_System::req_type_downgrade:
361
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
362
-                //its possible migrations are no longer required
363
-                EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
364
-                $this->_handle_core_version_change($espresso_db_update);
365
-                break;
366
-            case EE_System::req_type_normal:
367
-            default:
368
-                //				$this->_maybe_redirect_to_ee_about();
369
-                break;
370
-        }
371
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
372
-    }
373
-
374
-
375
-
376
-    /**
377
-     * Updates the list of installed versions and sets hooks for
378
-     * initializing the database later during the request
379
-     *
380
-     * @param array $espresso_db_update
381
-     */
382
-    protected function _handle_core_version_change($espresso_db_update)
383
-    {
384
-        $this->update_list_of_installed_versions($espresso_db_update);
385
-        //get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
386
-        add_action('AHEE__EE_System__perform_activations_upgrades_and_migrations',
387
-            array($this, 'initialize_db_if_no_migrations_required'));
388
-    }
389
-
390
-
391
-
392
-    /**
393
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
394
-     * information about what versions of EE have been installed and activated,
395
-     * NOT necessarily the state of the database
396
-     *
397
-     * @param mixed $espresso_db_update the value of the WordPress option.
398
-     *                                            If not supplied, fetches it from the options table
399
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
400
-     */
401
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
402
-    {
403
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
404
-        if ( ! $espresso_db_update) {
405
-            $espresso_db_update = get_option('espresso_db_update');
406
-        }
407
-        // check that option is an array
408
-        if ( ! is_array($espresso_db_update)) {
409
-            // if option is FALSE, then it never existed
410
-            if ($espresso_db_update === false) {
411
-                // make $espresso_db_update an array and save option with autoload OFF
412
-                $espresso_db_update = array();
413
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
414
-            } else {
415
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
416
-                $espresso_db_update = array($espresso_db_update => array());
417
-                update_option('espresso_db_update', $espresso_db_update);
418
-            }
419
-        } else {
420
-            $corrected_db_update = array();
421
-            //if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
422
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
423
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
424
-                    //the key is an int, and the value IS NOT an array
425
-                    //so it must be numerically-indexed, where values are versions installed...
426
-                    //fix it!
427
-                    $version_string = $should_be_array;
428
-                    $corrected_db_update[$version_string] = array('unknown-date');
429
-                } else {
430
-                    //ok it checks out
431
-                    $corrected_db_update[$should_be_version_string] = $should_be_array;
432
-                }
433
-            }
434
-            $espresso_db_update = $corrected_db_update;
435
-            update_option('espresso_db_update', $espresso_db_update);
436
-        }
437
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
438
-        return $espresso_db_update;
439
-    }
440
-
441
-
442
-
443
-    /**
444
-     * Does the traditional work of setting up the plugin's database and adding default data.
445
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
446
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
447
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
448
-     * so that it will be done when migrations are finished
449
-     *
450
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
451
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
452
-     *                                       This is a resource-intensive job
453
-     *                                       so we prefer to only do it when necessary
454
-     * @return void
455
-     * @throws EE_Error
456
-     */
457
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
458
-    {
459
-        $request_type = $this->detect_req_type();
460
-        //only initialize system if we're not in maintenance mode.
461
-        if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
462
-            update_option('ee_flush_rewrite_rules', true);
463
-            if ($verify_schema) {
464
-                EEH_Activation::initialize_db_and_folders();
465
-            }
466
-            EEH_Activation::initialize_db_content();
467
-            EEH_Activation::system_initialization();
468
-            if ($initialize_addons_too) {
469
-                $this->initialize_addons();
470
-            }
471
-        } else {
472
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
473
-        }
474
-        if ($request_type === EE_System::req_type_new_activation
475
-            || $request_type === EE_System::req_type_reactivation
476
-            || (
477
-                $request_type === EE_System::req_type_upgrade
478
-                && $this->is_major_version_change()
479
-            )
480
-        ) {
481
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
482
-        }
483
-    }
484
-
485
-
486
-
487
-    /**
488
-     * Initializes the db for all registered addons
489
-     *
490
-     * @throws EE_Error
491
-     */
492
-    public function initialize_addons()
493
-    {
494
-        //foreach registered addon, make sure its db is up-to-date too
495
-        foreach ($this->registry->addons as $addon) {
496
-            $addon->initialize_db_if_no_migrations_required();
497
-        }
498
-    }
499
-
500
-
501
-
502
-    /**
503
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
504
-     *
505
-     * @param    array  $version_history
506
-     * @param    string $current_version_to_add version to be added to the version history
507
-     * @return    boolean success as to whether or not this option was changed
508
-     */
509
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
510
-    {
511
-        if ( ! $version_history) {
512
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
513
-        }
514
-        if ($current_version_to_add === null) {
515
-            $current_version_to_add = espresso_version();
516
-        }
517
-        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
518
-        // re-save
519
-        return update_option('espresso_db_update', $version_history);
520
-    }
521
-
522
-
523
-
524
-    /**
525
-     * Detects if the current version indicated in the has existed in the list of
526
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
527
-     *
528
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
529
-     *                                  If not supplied, fetches it from the options table.
530
-     *                                  Also, caches its result so later parts of the code can also know whether
531
-     *                                  there's been an update or not. This way we can add the current version to
532
-     *                                  espresso_db_update, but still know if this is a new install or not
533
-     * @return int one of the constants on EE_System::req_type_
534
-     */
535
-    public function detect_req_type($espresso_db_update = null)
536
-    {
537
-        if ($this->_req_type === null) {
538
-            $espresso_db_update = ! empty($espresso_db_update) ? $espresso_db_update
539
-                : $this->fix_espresso_db_upgrade_option();
540
-            $this->_req_type = EE_System::detect_req_type_given_activation_history($espresso_db_update,
541
-                'ee_espresso_activation', espresso_version());
542
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
543
-        }
544
-        return $this->_req_type;
545
-    }
546
-
547
-
548
-
549
-    /**
550
-     * Returns whether or not there was a non-micro version change (ie, change in either
551
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
552
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
553
-     *
554
-     * @param $activation_history
555
-     * @return bool
556
-     */
557
-    protected function _detect_major_version_change($activation_history)
558
-    {
559
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
560
-        $previous_version_parts = explode('.', $previous_version);
561
-        $current_version_parts = explode('.', espresso_version());
562
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
563
-               && ($previous_version_parts[0] !== $current_version_parts[0]
564
-                   || $previous_version_parts[1] !== $current_version_parts[1]
565
-               );
566
-    }
567
-
568
-
569
-
570
-    /**
571
-     * Returns true if either the major or minor version of EE changed during this request.
572
-     * 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
573
-     *
574
-     * @return bool
575
-     */
576
-    public function is_major_version_change()
577
-    {
578
-        return $this->_major_version_change;
579
-    }
580
-
581
-
582
-
583
-    /**
584
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
585
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
586
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
587
-     * just activated to (for core that will always be espresso_version())
588
-     *
589
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
590
-     *                                                 ee plugin. for core that's 'espresso_db_update'
591
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
592
-     *                                                 indicate that this plugin was just activated
593
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
594
-     *                                                 espresso_version())
595
-     * @return int one of the constants on EE_System::req_type_*
596
-     */
597
-    public static function detect_req_type_given_activation_history(
598
-        $activation_history_for_addon,
599
-        $activation_indicator_option_name,
600
-        $version_to_upgrade_to
601
-    ) {
602
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
603
-        if ($activation_history_for_addon) {
604
-            //it exists, so this isn't a completely new install
605
-            //check if this version already in that list of previously installed versions
606
-            if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
607
-                //it a version we haven't seen before
608
-                if ($version_is_higher === 1) {
609
-                    $req_type = EE_System::req_type_upgrade;
610
-                } else {
611
-                    $req_type = EE_System::req_type_downgrade;
612
-                }
613
-                delete_option($activation_indicator_option_name);
614
-            } else {
615
-                // its not an update. maybe a reactivation?
616
-                if (get_option($activation_indicator_option_name, false)) {
617
-                    if ($version_is_higher === -1) {
618
-                        $req_type = EE_System::req_type_downgrade;
619
-                    } elseif ($version_is_higher === 0) {
620
-                        //we've seen this version before, but it's an activation. must be a reactivation
621
-                        $req_type = EE_System::req_type_reactivation;
622
-                    } else {//$version_is_higher === 1
623
-                        $req_type = EE_System::req_type_upgrade;
624
-                    }
625
-                    delete_option($activation_indicator_option_name);
626
-                } else {
627
-                    //we've seen this version before and the activation indicate doesn't show it was just activated
628
-                    if ($version_is_higher === -1) {
629
-                        $req_type = EE_System::req_type_downgrade;
630
-                    } elseif ($version_is_higher === 0) {
631
-                        //we've seen this version before and it's not an activation. its normal request
632
-                        $req_type = EE_System::req_type_normal;
633
-                    } else {//$version_is_higher === 1
634
-                        $req_type = EE_System::req_type_upgrade;
635
-                    }
636
-                }
637
-            }
638
-        } else {
639
-            //brand new install
640
-            $req_type = EE_System::req_type_new_activation;
641
-            delete_option($activation_indicator_option_name);
642
-        }
643
-        return $req_type;
644
-    }
645
-
646
-
647
-
648
-    /**
649
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
650
-     * the $activation_history_for_addon
651
-     *
652
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
653
-     *                                             sometimes containing 'unknown-date'
654
-     * @param string $version_to_upgrade_to        (current version)
655
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
656
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
657
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
658
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
659
-     */
660
-    protected static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
661
-    {
662
-        //find the most recently-activated version
663
-        $most_recently_active_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
664
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
665
-    }
666
-
667
-
668
-
669
-    /**
670
-     * Gets the most recently active version listed in the activation history,
671
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
672
-     *
673
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
674
-     *                                   sometimes containing 'unknown-date'
675
-     * @return string
676
-     */
677
-    protected static function _get_most_recently_active_version_from_activation_history($activation_history)
678
-    {
679
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
680
-        $most_recently_active_version = '0.0.0.dev.000';
681
-        if (is_array($activation_history)) {
682
-            foreach ($activation_history as $version => $times_activated) {
683
-                //check there is a record of when this version was activated. Otherwise,
684
-                //mark it as unknown
685
-                if ( ! $times_activated) {
686
-                    $times_activated = array('unknown-date');
687
-                }
688
-                if (is_string($times_activated)) {
689
-                    $times_activated = array($times_activated);
690
-                }
691
-                foreach ($times_activated as $an_activation) {
692
-                    if ($an_activation !== 'unknown-date' && $an_activation > $most_recently_active_version_activation) {
693
-                        $most_recently_active_version = $version;
694
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
695
-                            ? '1970-01-01 00:00:00' : $an_activation;
696
-                    }
697
-                }
698
-            }
699
-        }
700
-        return $most_recently_active_version;
701
-    }
702
-
703
-
704
-
705
-    /**
706
-     * This redirects to the about EE page after activation
707
-     *
708
-     * @return void
709
-     */
710
-    public function redirect_to_about_ee()
711
-    {
712
-        $notices = EE_Error::get_notices(false);
713
-        //if current user is an admin and it's not an ajax or rest request
714
-        if (
715
-            ! (defined('DOING_AJAX') && DOING_AJAX)
716
-            && ! (defined('REST_REQUEST') && REST_REQUEST)
717
-            && ! isset($notices['errors'])
718
-            && apply_filters(
719
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
720
-                $this->registry->CAP->current_user_can('manage_options', 'espresso_about_default')
721
-            )
722
-        ) {
723
-            $query_params = array('page' => 'espresso_about');
724
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
725
-                $query_params['new_activation'] = true;
726
-            }
727
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
728
-                $query_params['reactivation'] = true;
729
-            }
730
-            $url = add_query_arg($query_params, admin_url('admin.php'));
731
-            wp_safe_redirect($url);
732
-            exit();
733
-        }
734
-    }
735
-
736
-
737
-
738
-    /**
739
-     * load_core_configuration
740
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
741
-     * which runs during the WP 'plugins_loaded' action at priority 5
742
-     *
743
-     * @return void
744
-     * @throws \ReflectionException
745
-     */
746
-    public function load_core_configuration()
747
-    {
748
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
749
-        $this->registry->load_core('EE_Load_Textdomain');
750
-        //load textdomain
751
-        EE_Load_Textdomain::load_textdomain();
752
-        // load and setup EE_Config and EE_Network_Config
753
-        $this->registry->load_core('Config');
754
-        $this->registry->load_core('Network_Config');
755
-        // setup autoloaders
756
-        // enable logging?
757
-        if ($this->registry->CFG->admin->use_full_logging) {
758
-            $this->registry->load_core('Log');
759
-        }
760
-        // check for activation errors
761
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
762
-        if ($activation_errors) {
763
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
764
-            update_option('ee_plugin_activation_errors', false);
765
-        }
766
-        // get model names
767
-        $this->_parse_model_names();
768
-        //load caf stuff a chance to play during the activation process too.
769
-        $this->_maybe_brew_regular();
770
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
771
-    }
772
-
773
-
774
-
775
-    /**
776
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
777
-     *
778
-     * @return void
779
-     * @throws ReflectionException
780
-     */
781
-    private function _parse_model_names()
782
-    {
783
-        //get all the files in the EE_MODELS folder that end in .model.php
784
-        $models = glob(EE_MODELS . '*.model.php');
785
-        $model_names = array();
786
-        $non_abstract_db_models = array();
787
-        foreach ($models as $model) {
788
-            // get model classname
789
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
790
-            $short_name = str_replace('EEM_', '', $classname);
791
-            $reflectionClass = new ReflectionClass($classname);
792
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
793
-                $non_abstract_db_models[$short_name] = $classname;
794
-            }
795
-            $model_names[$short_name] = $classname;
796
-        }
797
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
798
-        $this->registry->non_abstract_db_models = apply_filters('FHEE__EE_System__parse_implemented_model_names',
799
-            $non_abstract_db_models);
800
-    }
801
-
802
-
803
-
804
-    /**
805
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
806
-     * that need to be setup before our EE_System launches.
807
-     *
808
-     * @return void
809
-     */
810
-    private function _maybe_brew_regular()
811
-    {
812
-        if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
813
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
814
-        }
815
-    }
816
-
817
-
818
-
819
-    /**
820
-     * register_shortcodes_modules_and_widgets
821
-     * generate lists of shortcodes and modules, then verify paths and classes
822
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
823
-     * which runs during the WP 'plugins_loaded' action at priority 7
824
-     *
825
-     * @access public
826
-     * @return void
827
-     */
828
-    public function register_shortcodes_modules_and_widgets()
829
-    {
830
-        try {
831
-            // load, register, and add shortcodes the new way
832
-            new ShortcodesManager(
833
-            // and the old way, but we'll put it under control of the new system
834
-                EE_Config::getLegacyShortcodesManager()
835
-            );
836
-        } catch (Exception $exception) {
837
-            new ExceptionStackTraceDisplay($exception);
838
-        }
839
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
840
-        // check for addons using old hook point
841
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
842
-            $this->_incompatible_addon_error();
843
-        }
844
-    }
845
-
846
-
847
-
848
-    /**
849
-     * _incompatible_addon_error
850
-     *
851
-     * @access public
852
-     * @return void
853
-     */
854
-    private function _incompatible_addon_error()
855
-    {
856
-        // get array of classes hooking into here
857
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook('AHEE__EE_System__register_shortcodes_modules_and_addons');
858
-        if ( ! empty($class_names)) {
859
-            $msg = __('The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
860
-                'event_espresso');
861
-            $msg .= '<ul>';
862
-            foreach ($class_names as $class_name) {
863
-                $msg .= '<li><b>Event Espresso - ' . str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
864
-                        $class_name) . '</b></li>';
865
-            }
866
-            $msg .= '</ul>';
867
-            $msg .= __('Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
868
-                'event_espresso');
869
-            // save list of incompatible addons to wp-options for later use
870
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
871
-            if (is_admin()) {
872
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
873
-            }
874
-        }
875
-    }
876
-
877
-
878
-
879
-    /**
880
-     * brew_espresso
881
-     * begins the process of setting hooks for initializing EE in the correct order
882
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
883
-     * which runs during the WP 'plugins_loaded' action at priority 9
884
-     *
885
-     * @return void
886
-     */
887
-    public function brew_espresso()
888
-    {
889
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
890
-        // load some final core systems
891
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
892
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
893
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
894
-        add_action('init', array($this, 'load_controllers'), 7);
895
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
896
-        add_action('init', array($this, 'initialize'), 10);
897
-        add_action('init', array($this, 'initialize_last'), 100);
898
-        add_action('admin_bar_menu', array($this, 'espresso_toolbar_items'), 100);
899
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
900
-            // pew pew pew
901
-            $this->registry->load_core('PUE');
902
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
903
-        }
904
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
905
-    }
906
-
907
-
908
-
909
-    /**
910
-     *    set_hooks_for_core
911
-     *
912
-     * @access public
913
-     * @return    void
914
-     * @throws EE_Error
915
-     */
916
-    public function set_hooks_for_core()
917
-    {
918
-        $this->_deactivate_incompatible_addons();
919
-        do_action('AHEE__EE_System__set_hooks_for_core');
920
-        //caps need to be initialized on every request so that capability maps are set.
921
-        //@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
922
-        $this->registry->CAP->init_caps();
923
-    }
924
-
925
-
926
-
927
-    /**
928
-     * Using the information gathered in EE_System::_incompatible_addon_error,
929
-     * deactivates any addons considered incompatible with the current version of EE
930
-     */
931
-    private function _deactivate_incompatible_addons()
932
-    {
933
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
934
-        if ( ! empty($incompatible_addons)) {
935
-            $active_plugins = get_option('active_plugins', array());
936
-            foreach ($active_plugins as $active_plugin) {
937
-                foreach ($incompatible_addons as $incompatible_addon) {
938
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
939
-                        unset($_GET['activate']);
940
-                        espresso_deactivate_plugin($active_plugin);
941
-                    }
942
-                }
943
-            }
944
-        }
945
-    }
946
-
947
-
948
-
949
-    /**
950
-     *    perform_activations_upgrades_and_migrations
951
-     *
952
-     * @access public
953
-     * @return    void
954
-     */
955
-    public function perform_activations_upgrades_and_migrations()
956
-    {
957
-        //first check if we had previously attempted to setup EE's directories but failed
958
-        if (EEH_Activation::upload_directories_incomplete()) {
959
-            EEH_Activation::create_upload_directories();
960
-        }
961
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
962
-    }
963
-
964
-
965
-
966
-    /**
967
-     *    load_CPTs_and_session
968
-     *
969
-     * @access public
970
-     * @return    void
971
-     */
972
-    public function load_CPTs_and_session()
973
-    {
974
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
975
-        // register Custom Post Types
976
-        $this->registry->load_core('Register_CPTs');
977
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
978
-    }
979
-
980
-
981
-
982
-    /**
983
-     * load_controllers
984
-     * this is the best place to load any additional controllers that needs access to EE core.
985
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
986
-     * time
987
-     *
988
-     * @access public
989
-     * @return void
990
-     */
991
-    public function load_controllers()
992
-    {
993
-        do_action('AHEE__EE_System__load_controllers__start');
994
-        // let's get it started
995
-        if ( ! is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
996
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
997
-            $this->registry->load_core('Front_Controller');
998
-        } else if ( ! EE_FRONT_AJAX) {
999
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1000
-            EE_Registry::instance()->load_core('Admin');
1001
-        }
1002
-        do_action('AHEE__EE_System__load_controllers__complete');
1003
-    }
1004
-
1005
-
1006
-
1007
-    /**
1008
-     * core_loaded_and_ready
1009
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1010
-     *
1011
-     * @access public
1012
-     * @return void
1013
-     */
1014
-    public function core_loaded_and_ready()
1015
-    {
1016
-        $this->registry->load_core('Session');
1017
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1018
-        // load_espresso_template_tags
1019
-        if (is_readable(EE_PUBLIC . 'template_tags.php')) {
1020
-            require_once(EE_PUBLIC . 'template_tags.php');
1021
-        }
1022
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1023
-        $this->registry->create('EventEspresso\core\services\assets\Registry', array(), true);
1024
-    }
1025
-
1026
-
1027
-
1028
-    /**
1029
-     * initialize
1030
-     * this is the best place to begin initializing client code
1031
-     *
1032
-     * @access public
1033
-     * @return void
1034
-     */
1035
-    public function initialize()
1036
-    {
1037
-        do_action('AHEE__EE_System__initialize');
1038
-    }
1039
-
1040
-
1041
-
1042
-    /**
1043
-     * initialize_last
1044
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1045
-     * initialize has done so
1046
-     *
1047
-     * @access public
1048
-     * @return void
1049
-     */
1050
-    public function initialize_last()
1051
-    {
1052
-        do_action('AHEE__EE_System__initialize_last');
1053
-    }
1054
-
1055
-
1056
-
1057
-    /**
1058
-     * set_hooks_for_shortcodes_modules_and_addons
1059
-     * this is the best place for other systems to set callbacks for hooking into other parts of EE
1060
-     * this happens at the very beginning of the wp_loaded hook point
1061
-     *
1062
-     * @access public
1063
-     * @return void
1064
-     */
1065
-    public function set_hooks_for_shortcodes_modules_and_addons()
1066
-    {
1067
-        //		do_action( 'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons' );
1068
-    }
1069
-
1070
-
1071
-
1072
-    /**
1073
-     * do_not_cache
1074
-     * sets no cache headers and defines no cache constants for WP plugins
1075
-     *
1076
-     * @access public
1077
-     * @return void
1078
-     */
1079
-    public static function do_not_cache()
1080
-    {
1081
-        // set no cache constants
1082
-        if ( ! defined('DONOTCACHEPAGE')) {
1083
-            define('DONOTCACHEPAGE', true);
1084
-        }
1085
-        if ( ! defined('DONOTCACHCEOBJECT')) {
1086
-            define('DONOTCACHCEOBJECT', true);
1087
-        }
1088
-        if ( ! defined('DONOTCACHEDB')) {
1089
-            define('DONOTCACHEDB', true);
1090
-        }
1091
-        // add no cache headers
1092
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1093
-        // plus a little extra for nginx and Google Chrome
1094
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1095
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1096
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1097
-    }
1098
-
1099
-
1100
-
1101
-    /**
1102
-     *    extra_nocache_headers
1103
-     *
1104
-     * @access    public
1105
-     * @param $headers
1106
-     * @return    array
1107
-     */
1108
-    public static function extra_nocache_headers($headers)
1109
-    {
1110
-        // for NGINX
1111
-        $headers['X-Accel-Expires'] = 0;
1112
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1113
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1114
-        return $headers;
1115
-    }
1116
-
1117
-
1118
-
1119
-    /**
1120
-     *    nocache_headers
1121
-     *
1122
-     * @access    public
1123
-     * @return    void
1124
-     */
1125
-    public static function nocache_headers()
1126
-    {
1127
-        nocache_headers();
1128
-    }
1129
-
1130
-
1131
-
1132
-    /**
1133
-     *    espresso_toolbar_items
1134
-     *
1135
-     * @access public
1136
-     * @param  WP_Admin_Bar $admin_bar
1137
-     * @return void
1138
-     */
1139
-    public function espresso_toolbar_items(WP_Admin_Bar $admin_bar)
1140
-    {
1141
-        // if in full M-Mode, or its an AJAX request, or user is NOT an admin
1142
-        if (
1143
-            defined('DOING_AJAX')
1144
-            || ! $this->registry->CAP->current_user_can('ee_read_ee', 'ee_admin_bar_menu_top_level')
1145
-            || EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
1146
-        ) {
1147
-            return;
1148
-        }
1149
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1150
-        $menu_class = 'espresso_menu_item_class';
1151
-        //we don't use the constants EVENTS_ADMIN_URL or REG_ADMIN_URL
1152
-        //because they're only defined in each of their respective constructors
1153
-        //and this might be a frontend request, in which case they aren't available
1154
-        $events_admin_url = admin_url('admin.php?page=espresso_events');
1155
-        $reg_admin_url = admin_url('admin.php?page=espresso_registrations');
1156
-        $extensions_admin_url = admin_url('admin.php?page=espresso_packages');
1157
-        //Top Level
1158
-        $admin_bar->add_menu(array(
1159
-            'id'    => 'espresso-toolbar',
1160
-            'title' => '<span class="ee-icon ee-icon-ee-cup-thick ee-icon-size-20"></span><span class="ab-label">'
1161
-                       . _x('Event Espresso', 'admin bar menu group label', 'event_espresso')
1162
-                       . '</span>',
1163
-            'href'  => $events_admin_url,
1164
-            'meta'  => array(
1165
-                'title' => __('Event Espresso', 'event_espresso'),
1166
-                'class' => $menu_class . 'first',
1167
-            ),
1168
-        ));
1169
-        //Events
1170
-        if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events')) {
1171
-            $admin_bar->add_menu(array(
1172
-                'id'     => 'espresso-toolbar-events',
1173
-                'parent' => 'espresso-toolbar',
1174
-                'title'  => __('Events', 'event_espresso'),
1175
-                'href'   => $events_admin_url,
1176
-                'meta'   => array(
1177
-                    'title'  => __('Events', 'event_espresso'),
1178
-                    'target' => '',
1179
-                    'class'  => $menu_class,
1180
-                ),
1181
-            ));
1182
-        }
1183
-        if ($this->registry->CAP->current_user_can('ee_edit_events', 'ee_admin_bar_menu_espresso-toolbar-events-new')) {
1184
-            //Events Add New
1185
-            $admin_bar->add_menu(array(
1186
-                'id'     => 'espresso-toolbar-events-new',
1187
-                'parent' => 'espresso-toolbar-events',
1188
-                'title'  => __('Add New', 'event_espresso'),
1189
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'create_new'), $events_admin_url),
1190
-                'meta'   => array(
1191
-                    'title'  => __('Add New', 'event_espresso'),
1192
-                    'target' => '',
1193
-                    'class'  => $menu_class,
1194
-                ),
1195
-            ));
1196
-        }
1197
-        if (is_single() && (get_post_type() === 'espresso_events')) {
1198
-            //Current post
1199
-            global $post;
1200
-            if ($this->registry->CAP->current_user_can('ee_edit_event',
1201
-                'ee_admin_bar_menu_espresso-toolbar-events-edit', $post->ID)
1202
-            ) {
1203
-                //Events Edit Current Event
1204
-                $admin_bar->add_menu(array(
1205
-                    'id'     => 'espresso-toolbar-events-edit',
1206
-                    'parent' => 'espresso-toolbar-events',
1207
-                    'title'  => __('Edit Event', 'event_espresso'),
1208
-                    'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'edit', 'post' => $post->ID),
1209
-                        $events_admin_url),
1210
-                    'meta'   => array(
1211
-                        'title'  => __('Edit Event', 'event_espresso'),
1212
-                        'target' => '',
1213
-                        'class'  => $menu_class,
1214
-                    ),
1215
-                ));
1216
-            }
1217
-        }
1218
-        //Events View
1219
-        if ($this->registry->CAP->current_user_can('ee_read_events',
1220
-            'ee_admin_bar_menu_espresso-toolbar-events-view')
1221
-        ) {
1222
-            $admin_bar->add_menu(array(
1223
-                'id'     => 'espresso-toolbar-events-view',
1224
-                'parent' => 'espresso-toolbar-events',
1225
-                'title'  => __('View', 'event_espresso'),
1226
-                'href'   => $events_admin_url,
1227
-                'meta'   => array(
1228
-                    'title'  => __('View', 'event_espresso'),
1229
-                    'target' => '',
1230
-                    'class'  => $menu_class,
1231
-                ),
1232
-            ));
1233
-        }
1234
-        if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-all')) {
1235
-            //Events View All
1236
-            $admin_bar->add_menu(array(
1237
-                'id'     => 'espresso-toolbar-events-all',
1238
-                'parent' => 'espresso-toolbar-events-view',
1239
-                'title'  => __('All', 'event_espresso'),
1240
-                'href'   => $events_admin_url,
1241
-                'meta'   => array(
1242
-                    'title'  => __('All', 'event_espresso'),
1243
-                    'target' => '',
1244
-                    'class'  => $menu_class,
1245
-                ),
1246
-            ));
1247
-        }
1248
-        if ($this->registry->CAP->current_user_can('ee_read_events',
1249
-            'ee_admin_bar_menu_espresso-toolbar-events-today')
1250
-        ) {
1251
-            //Events View Today
1252
-            $admin_bar->add_menu(array(
1253
-                'id'     => 'espresso-toolbar-events-today',
1254
-                'parent' => 'espresso-toolbar-events-view',
1255
-                'title'  => __('Today', 'event_espresso'),
1256
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1257
-                    $events_admin_url),
1258
-                'meta'   => array(
1259
-                    'title'  => __('Today', 'event_espresso'),
1260
-                    'target' => '',
1261
-                    'class'  => $menu_class,
1262
-                ),
1263
-            ));
1264
-        }
1265
-        if ($this->registry->CAP->current_user_can('ee_read_events',
1266
-            'ee_admin_bar_menu_espresso-toolbar-events-month')
1267
-        ) {
1268
-            //Events View This Month
1269
-            $admin_bar->add_menu(array(
1270
-                'id'     => 'espresso-toolbar-events-month',
1271
-                'parent' => 'espresso-toolbar-events-view',
1272
-                'title'  => __('This Month', 'event_espresso'),
1273
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1274
-                    $events_admin_url),
1275
-                'meta'   => array(
1276
-                    'title'  => __('This Month', 'event_espresso'),
1277
-                    'target' => '',
1278
-                    'class'  => $menu_class,
1279
-                ),
1280
-            ));
1281
-        }
1282
-        //Registration Overview
1283
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1284
-            'ee_admin_bar_menu_espresso-toolbar-registrations')
1285
-        ) {
1286
-            $admin_bar->add_menu(array(
1287
-                'id'     => 'espresso-toolbar-registrations',
1288
-                'parent' => 'espresso-toolbar',
1289
-                'title'  => __('Registrations', 'event_espresso'),
1290
-                'href'   => $reg_admin_url,
1291
-                'meta'   => array(
1292
-                    'title'  => __('Registrations', 'event_espresso'),
1293
-                    'target' => '',
1294
-                    'class'  => $menu_class,
1295
-                ),
1296
-            ));
1297
-        }
1298
-        //Registration Overview Today
1299
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1300
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today')
1301
-        ) {
1302
-            $admin_bar->add_menu(array(
1303
-                'id'     => 'espresso-toolbar-registrations-today',
1304
-                'parent' => 'espresso-toolbar-registrations',
1305
-                'title'  => __('Today', 'event_espresso'),
1306
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1307
-                    $reg_admin_url),
1308
-                'meta'   => array(
1309
-                    'title'  => __('Today', 'event_espresso'),
1310
-                    'target' => '',
1311
-                    'class'  => $menu_class,
1312
-                ),
1313
-            ));
1314
-        }
1315
-        //Registration Overview Today Completed
1316
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1317
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-approved')
1318
-        ) {
1319
-            $admin_bar->add_menu(array(
1320
-                'id'     => 'espresso-toolbar-registrations-today-approved',
1321
-                'parent' => 'espresso-toolbar-registrations-today',
1322
-                'title'  => __('Approved', 'event_espresso'),
1323
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1324
-                    'action'      => 'default',
1325
-                    'status'      => 'today',
1326
-                    '_reg_status' => EEM_Registration::status_id_approved,
1327
-                ), $reg_admin_url),
1328
-                'meta'   => array(
1329
-                    'title'  => __('Approved', 'event_espresso'),
1330
-                    'target' => '',
1331
-                    'class'  => $menu_class,
1332
-                ),
1333
-            ));
1334
-        }
1335
-        //Registration Overview Today Pending\
1336
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1337
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-pending')
1338
-        ) {
1339
-            $admin_bar->add_menu(array(
1340
-                'id'     => 'espresso-toolbar-registrations-today-pending',
1341
-                'parent' => 'espresso-toolbar-registrations-today',
1342
-                'title'  => __('Pending', 'event_espresso'),
1343
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1344
-                    'action'     => 'default',
1345
-                    'status'     => 'today',
1346
-                    'reg_status' => EEM_Registration::status_id_pending_payment,
1347
-                ), $reg_admin_url),
1348
-                'meta'   => array(
1349
-                    'title'  => __('Pending Payment', 'event_espresso'),
1350
-                    'target' => '',
1351
-                    'class'  => $menu_class,
1352
-                ),
1353
-            ));
1354
-        }
1355
-        //Registration Overview Today Incomplete
1356
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1357
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-not-approved')
1358
-        ) {
1359
-            $admin_bar->add_menu(array(
1360
-                'id'     => 'espresso-toolbar-registrations-today-not-approved',
1361
-                'parent' => 'espresso-toolbar-registrations-today',
1362
-                'title'  => __('Not Approved', 'event_espresso'),
1363
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1364
-                    'action'      => 'default',
1365
-                    'status'      => 'today',
1366
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1367
-                ), $reg_admin_url),
1368
-                'meta'   => array(
1369
-                    'title'  => __('Not Approved', 'event_espresso'),
1370
-                    'target' => '',
1371
-                    'class'  => $menu_class,
1372
-                ),
1373
-            ));
1374
-        }
1375
-        //Registration Overview Today Incomplete
1376
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1377
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-cancelled')
1378
-        ) {
1379
-            $admin_bar->add_menu(array(
1380
-                'id'     => 'espresso-toolbar-registrations-today-cancelled',
1381
-                'parent' => 'espresso-toolbar-registrations-today',
1382
-                'title'  => __('Cancelled', 'event_espresso'),
1383
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1384
-                    'action'      => 'default',
1385
-                    'status'      => 'today',
1386
-                    '_reg_status' => EEM_Registration::status_id_cancelled,
1387
-                ), $reg_admin_url),
1388
-                'meta'   => array(
1389
-                    'title'  => __('Cancelled', 'event_espresso'),
1390
-                    'target' => '',
1391
-                    'class'  => $menu_class,
1392
-                ),
1393
-            ));
1394
-        }
1395
-        //Registration Overview This Month
1396
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1397
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month')
1398
-        ) {
1399
-            $admin_bar->add_menu(array(
1400
-                'id'     => 'espresso-toolbar-registrations-month',
1401
-                'parent' => 'espresso-toolbar-registrations',
1402
-                'title'  => __('This Month', 'event_espresso'),
1403
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1404
-                    $reg_admin_url),
1405
-                'meta'   => array(
1406
-                    'title'  => __('This Month', 'event_espresso'),
1407
-                    'target' => '',
1408
-                    'class'  => $menu_class,
1409
-                ),
1410
-            ));
1411
-        }
1412
-        //Registration Overview This Month Approved
1413
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1414
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-approved')
1415
-        ) {
1416
-            $admin_bar->add_menu(array(
1417
-                'id'     => 'espresso-toolbar-registrations-month-approved',
1418
-                'parent' => 'espresso-toolbar-registrations-month',
1419
-                'title'  => __('Approved', 'event_espresso'),
1420
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1421
-                    'action'      => 'default',
1422
-                    'status'      => 'month',
1423
-                    '_reg_status' => EEM_Registration::status_id_approved,
1424
-                ), $reg_admin_url),
1425
-                'meta'   => array(
1426
-                    'title'  => __('Approved', 'event_espresso'),
1427
-                    'target' => '',
1428
-                    'class'  => $menu_class,
1429
-                ),
1430
-            ));
1431
-        }
1432
-        //Registration Overview This Month Pending
1433
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1434
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-pending')
1435
-        ) {
1436
-            $admin_bar->add_menu(array(
1437
-                'id'     => 'espresso-toolbar-registrations-month-pending',
1438
-                'parent' => 'espresso-toolbar-registrations-month',
1439
-                'title'  => __('Pending', 'event_espresso'),
1440
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1441
-                    'action'      => 'default',
1442
-                    'status'      => 'month',
1443
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1444
-                ), $reg_admin_url),
1445
-                'meta'   => array(
1446
-                    'title'  => __('Pending', 'event_espresso'),
1447
-                    'target' => '',
1448
-                    'class'  => $menu_class,
1449
-                ),
1450
-            ));
1451
-        }
1452
-        //Registration Overview This Month Not Approved
1453
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1454
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-not-approved')
1455
-        ) {
1456
-            $admin_bar->add_menu(array(
1457
-                'id'     => 'espresso-toolbar-registrations-month-not-approved',
1458
-                'parent' => 'espresso-toolbar-registrations-month',
1459
-                'title'  => __('Not Approved', 'event_espresso'),
1460
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1461
-                    'action'      => 'default',
1462
-                    'status'      => 'month',
1463
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1464
-                ), $reg_admin_url),
1465
-                'meta'   => array(
1466
-                    'title'  => __('Not Approved', 'event_espresso'),
1467
-                    'target' => '',
1468
-                    'class'  => $menu_class,
1469
-                ),
1470
-            ));
1471
-        }
1472
-        //Registration Overview This Month Cancelled
1473
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1474
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-cancelled')
1475
-        ) {
1476
-            $admin_bar->add_menu(array(
1477
-                'id'     => 'espresso-toolbar-registrations-month-cancelled',
1478
-                'parent' => 'espresso-toolbar-registrations-month',
1479
-                'title'  => __('Cancelled', 'event_espresso'),
1480
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1481
-                    'action'      => 'default',
1482
-                    'status'      => 'month',
1483
-                    '_reg_status' => EEM_Registration::status_id_cancelled,
1484
-                ), $reg_admin_url),
1485
-                'meta'   => array(
1486
-                    'title'  => __('Cancelled', 'event_espresso'),
1487
-                    'target' => '',
1488
-                    'class'  => $menu_class,
1489
-                ),
1490
-            ));
1491
-        }
1492
-        //Extensions & Services
1493
-        if ($this->registry->CAP->current_user_can('ee_read_ee',
1494
-            'ee_admin_bar_menu_espresso-toolbar-extensions-and-services')
1495
-        ) {
1496
-            $admin_bar->add_menu(array(
1497
-                'id'     => 'espresso-toolbar-extensions-and-services',
1498
-                'parent' => 'espresso-toolbar',
1499
-                'title'  => __('Extensions & Services', 'event_espresso'),
1500
-                'href'   => $extensions_admin_url,
1501
-                'meta'   => array(
1502
-                    'title'  => __('Extensions & Services', 'event_espresso'),
1503
-                    'target' => '',
1504
-                    'class'  => $menu_class,
1505
-                ),
1506
-            ));
1507
-        }
1508
-    }
1509
-
1510
-
1511
-
1512
-    /**
1513
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1514
-     * never returned with the function.
1515
-     *
1516
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1517
-     * @return array
1518
-     */
1519
-    public function remove_pages_from_wp_list_pages($exclude_array)
1520
-    {
1521
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1522
-    }
26
+	/**
27
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
28
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
29
+	 */
30
+	const req_type_normal = 0;
31
+
32
+	/**
33
+	 * Indicates this is a brand new installation of EE so we should install
34
+	 * tables and default data etc
35
+	 */
36
+	const req_type_new_activation = 1;
37
+
38
+	/**
39
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
40
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
41
+	 * and that default data is setup too
42
+	 */
43
+	const req_type_reactivation = 2;
44
+
45
+	/**
46
+	 * indicates that EE has been upgraded since its previous request.
47
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
48
+	 */
49
+	const req_type_upgrade = 3;
50
+
51
+	/**
52
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
53
+	 */
54
+	const req_type_downgrade = 4;
55
+
56
+	/**
57
+	 * @deprecated since version 4.6.0.dev.006
58
+	 * Now whenever a new_activation is detected the request type is still just
59
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
60
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
61
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
62
+	 * (Specifically, when the migration manager indicates migrations are finished
63
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
64
+	 */
65
+	const req_type_activation_but_not_installed = 5;
66
+
67
+	/**
68
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
69
+	 */
70
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
71
+
72
+
73
+	/**
74
+	 * @var EE_System $_instance
75
+	 */
76
+	private static $_instance;
77
+
78
+	/**
79
+	 * @var EE_Registry $registry
80
+	 */
81
+	protected $registry;
82
+
83
+	/**
84
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
85
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
86
+	 *
87
+	 * @var int $_req_type
88
+	 */
89
+	private $_req_type;
90
+
91
+	/**
92
+	 * Whether or not there was a non-micro version change in EE core version during this request
93
+	 *
94
+	 * @var boolean $_major_version_change
95
+	 */
96
+	private $_major_version_change = false;
97
+
98
+
99
+
100
+	/**
101
+	 * @singleton method used to instantiate class object
102
+	 * @access    public
103
+	 * @param  EE_Registry $Registry
104
+	 * @return EE_System
105
+	 */
106
+	public static function instance(EE_Registry $Registry = null)
107
+	{
108
+		// check if class object is instantiated
109
+		if ( ! self::$_instance instanceof EE_System) {
110
+			self::$_instance = new self($Registry);
111
+		}
112
+		return self::$_instance;
113
+	}
114
+
115
+
116
+
117
+	/**
118
+	 * resets the instance and returns it
119
+	 *
120
+	 * @return EE_System
121
+	 */
122
+	public static function reset()
123
+	{
124
+		self::$_instance->_req_type = null;
125
+		//make sure none of the old hooks are left hanging around
126
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
127
+		//we need to reset the migration manager in order for it to detect DMSs properly
128
+		EE_Data_Migration_Manager::reset();
129
+		self::instance()->detect_activations_or_upgrades();
130
+		self::instance()->perform_activations_upgrades_and_migrations();
131
+		return self::instance();
132
+	}
133
+
134
+
135
+
136
+	/**
137
+	 *    sets hooks for running rest of system
138
+	 *    provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
139
+	 *    starting EE Addons from any other point may lead to problems
140
+	 *
141
+	 * @access private
142
+	 * @param  EE_Registry $Registry
143
+	 */
144
+	private function __construct(EE_Registry $Registry)
145
+	{
146
+		$this->registry = $Registry;
147
+		do_action('AHEE__EE_System__construct__begin', $this);
148
+		add_action(
149
+			'AHEE__EE_Bootstrap__load_espresso_addons',
150
+			array($this, 'loadCapabilities'),
151
+			5
152
+		);
153
+		add_action(
154
+			'AHEE__EE_Bootstrap__load_espresso_addons',
155
+			array($this, 'loadCommandBus'),
156
+			7
157
+		);
158
+		add_action(
159
+			'AHEE__EE_Bootstrap__load_espresso_addons',
160
+			array($this, 'loadPluginApi'),
161
+			9
162
+		);
163
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
164
+		add_action(
165
+			'AHEE__EE_Bootstrap__load_espresso_addons',
166
+			array($this, 'load_espresso_addons')
167
+		);
168
+		// when an ee addon is activated, we want to call the core hook(s) again
169
+		// because the newly-activated addon didn't get a chance to run at all
170
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
171
+		// detect whether install or upgrade
172
+		add_action(
173
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
174
+			array($this, 'detect_activations_or_upgrades'),
175
+			3
176
+		);
177
+		// load EE_Config, EE_Textdomain, etc
178
+		add_action(
179
+			'AHEE__EE_Bootstrap__load_core_configuration',
180
+			array($this, 'load_core_configuration'),
181
+			5
182
+		);
183
+		// load EE_Config, EE_Textdomain, etc
184
+		add_action(
185
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
186
+			array($this, 'register_shortcodes_modules_and_widgets'),
187
+			7
188
+		);
189
+		// you wanna get going? I wanna get going... let's get going!
190
+		add_action(
191
+			'AHEE__EE_Bootstrap__brew_espresso',
192
+			array($this, 'brew_espresso'),
193
+			9
194
+		);
195
+		//other housekeeping
196
+		//exclude EE critical pages from wp_list_pages
197
+		add_filter(
198
+			'wp_list_pages_excludes',
199
+			array($this, 'remove_pages_from_wp_list_pages'),
200
+			10
201
+		);
202
+		// ALL EE Addons should use the following hook point to attach their initial setup too
203
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
204
+		do_action('AHEE__EE_System__construct__complete', $this);
205
+	}
206
+
207
+
208
+
209
+	/**
210
+	 * load and setup EE_Capabilities
211
+	 *
212
+	 * @return void
213
+	 * @throws EE_Error
214
+	 */
215
+	public function loadCapabilities()
216
+	{
217
+		$this->registry->load_core('EE_Capabilities');
218
+		add_action(
219
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
220
+			function() {
221
+				EE_Registry::instance()->load_lib('Payment_Method_Manager');
222
+			}
223
+		);
224
+	}
225
+
226
+
227
+
228
+	/**
229
+	 * create and cache the CommandBus, and also add middleware
230
+	 * The CapChecker middleware requires the use of EE_Capabilities
231
+	 * which is why we need to load the CommandBus after Caps are set up
232
+	 *
233
+	 * @return void
234
+	 * @throws EE_Error
235
+	 */
236
+	public function loadCommandBus()
237
+	{
238
+		$this->registry->create(
239
+			'CommandBusInterface',
240
+			array(
241
+				null,
242
+				apply_filters(
243
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
244
+					array(
245
+						$this->registry->create('CapChecker'),
246
+						$this->registry->create('AddActionHook'),
247
+					)
248
+				),
249
+			),
250
+			true
251
+		);
252
+	}
253
+
254
+
255
+
256
+	/**
257
+	 * @return void
258
+	 * @throws EE_Error
259
+	 */
260
+	public function loadPluginApi()
261
+	{
262
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
263
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
264
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
265
+	}
266
+
267
+
268
+
269
+	/**
270
+	 * load_espresso_addons
271
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
272
+	 * this is hooked into both:
273
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
274
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
275
+	 *    and the WP 'activate_plugin' hook point
276
+	 *
277
+	 * @access public
278
+	 * @return void
279
+	 * @throws EE_Error
280
+	 */
281
+	public function load_espresso_addons()
282
+	{
283
+		do_action('AHEE__EE_System__load_espresso_addons');
284
+		//if the WP API basic auth plugin isn't already loaded, load it now.
285
+		//We want it for mobile apps. Just include the entire plugin
286
+		//also, don't load the basic auth when a plugin is getting activated, because
287
+		//it could be the basic auth plugin, and it doesn't check if its methods are already defined
288
+		//and causes a fatal error
289
+		if (
290
+			! (isset($_GET['activate']) && $_GET['activate'] === 'true')
291
+			&& ! function_exists('json_basic_auth_handler')
292
+			&& ! function_exists('json_basic_auth_error')
293
+			&& ! (
294
+				isset($_GET['action'])
295
+				&& in_array($_GET['action'], array('activate', 'activate-selected'), true)
296
+			)
297
+		) {
298
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
299
+		}
300
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
301
+	}
302
+
303
+
304
+
305
+	/**
306
+	 * detect_activations_or_upgrades
307
+	 * Checks for activation or upgrade of core first;
308
+	 * then also checks if any registered addons have been activated or upgraded
309
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
310
+	 * which runs during the WP 'plugins_loaded' action at priority 3
311
+	 *
312
+	 * @access public
313
+	 * @return void
314
+	 */
315
+	public function detect_activations_or_upgrades()
316
+	{
317
+		//first off: let's make sure to handle core
318
+		$this->detect_if_activation_or_upgrade();
319
+		foreach ($this->registry->addons as $addon) {
320
+			//detect teh request type for that addon
321
+			$addon->detect_activation_or_upgrade();
322
+		}
323
+	}
324
+
325
+
326
+
327
+	/**
328
+	 * detect_if_activation_or_upgrade
329
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
330
+	 * and either setting up the DB or setting up maintenance mode etc.
331
+	 *
332
+	 * @access public
333
+	 * @return void
334
+	 */
335
+	public function detect_if_activation_or_upgrade()
336
+	{
337
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
338
+		// load M-Mode class
339
+		$this->registry->load_core('Maintenance_Mode');
340
+		// check if db has been updated, or if its a brand-new installation
341
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
342
+		$request_type = $this->detect_req_type($espresso_db_update);
343
+		//EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
344
+		switch ($request_type) {
345
+			case EE_System::req_type_new_activation:
346
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
347
+				$this->_handle_core_version_change($espresso_db_update);
348
+				break;
349
+			case EE_System::req_type_reactivation:
350
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
351
+				$this->_handle_core_version_change($espresso_db_update);
352
+				break;
353
+			case EE_System::req_type_upgrade:
354
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
355
+				//migrations may be required now that we've upgraded
356
+				EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
357
+				$this->_handle_core_version_change($espresso_db_update);
358
+				//				echo "done upgrade";die;
359
+				break;
360
+			case EE_System::req_type_downgrade:
361
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
362
+				//its possible migrations are no longer required
363
+				EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
364
+				$this->_handle_core_version_change($espresso_db_update);
365
+				break;
366
+			case EE_System::req_type_normal:
367
+			default:
368
+				//				$this->_maybe_redirect_to_ee_about();
369
+				break;
370
+		}
371
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
372
+	}
373
+
374
+
375
+
376
+	/**
377
+	 * Updates the list of installed versions and sets hooks for
378
+	 * initializing the database later during the request
379
+	 *
380
+	 * @param array $espresso_db_update
381
+	 */
382
+	protected function _handle_core_version_change($espresso_db_update)
383
+	{
384
+		$this->update_list_of_installed_versions($espresso_db_update);
385
+		//get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
386
+		add_action('AHEE__EE_System__perform_activations_upgrades_and_migrations',
387
+			array($this, 'initialize_db_if_no_migrations_required'));
388
+	}
389
+
390
+
391
+
392
+	/**
393
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
394
+	 * information about what versions of EE have been installed and activated,
395
+	 * NOT necessarily the state of the database
396
+	 *
397
+	 * @param mixed $espresso_db_update the value of the WordPress option.
398
+	 *                                            If not supplied, fetches it from the options table
399
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
400
+	 */
401
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
402
+	{
403
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
404
+		if ( ! $espresso_db_update) {
405
+			$espresso_db_update = get_option('espresso_db_update');
406
+		}
407
+		// check that option is an array
408
+		if ( ! is_array($espresso_db_update)) {
409
+			// if option is FALSE, then it never existed
410
+			if ($espresso_db_update === false) {
411
+				// make $espresso_db_update an array and save option with autoload OFF
412
+				$espresso_db_update = array();
413
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
414
+			} else {
415
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
416
+				$espresso_db_update = array($espresso_db_update => array());
417
+				update_option('espresso_db_update', $espresso_db_update);
418
+			}
419
+		} else {
420
+			$corrected_db_update = array();
421
+			//if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
422
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
423
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
424
+					//the key is an int, and the value IS NOT an array
425
+					//so it must be numerically-indexed, where values are versions installed...
426
+					//fix it!
427
+					$version_string = $should_be_array;
428
+					$corrected_db_update[$version_string] = array('unknown-date');
429
+				} else {
430
+					//ok it checks out
431
+					$corrected_db_update[$should_be_version_string] = $should_be_array;
432
+				}
433
+			}
434
+			$espresso_db_update = $corrected_db_update;
435
+			update_option('espresso_db_update', $espresso_db_update);
436
+		}
437
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
438
+		return $espresso_db_update;
439
+	}
440
+
441
+
442
+
443
+	/**
444
+	 * Does the traditional work of setting up the plugin's database and adding default data.
445
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
446
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
447
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
448
+	 * so that it will be done when migrations are finished
449
+	 *
450
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
451
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
452
+	 *                                       This is a resource-intensive job
453
+	 *                                       so we prefer to only do it when necessary
454
+	 * @return void
455
+	 * @throws EE_Error
456
+	 */
457
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
458
+	{
459
+		$request_type = $this->detect_req_type();
460
+		//only initialize system if we're not in maintenance mode.
461
+		if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
462
+			update_option('ee_flush_rewrite_rules', true);
463
+			if ($verify_schema) {
464
+				EEH_Activation::initialize_db_and_folders();
465
+			}
466
+			EEH_Activation::initialize_db_content();
467
+			EEH_Activation::system_initialization();
468
+			if ($initialize_addons_too) {
469
+				$this->initialize_addons();
470
+			}
471
+		} else {
472
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
473
+		}
474
+		if ($request_type === EE_System::req_type_new_activation
475
+			|| $request_type === EE_System::req_type_reactivation
476
+			|| (
477
+				$request_type === EE_System::req_type_upgrade
478
+				&& $this->is_major_version_change()
479
+			)
480
+		) {
481
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
482
+		}
483
+	}
484
+
485
+
486
+
487
+	/**
488
+	 * Initializes the db for all registered addons
489
+	 *
490
+	 * @throws EE_Error
491
+	 */
492
+	public function initialize_addons()
493
+	{
494
+		//foreach registered addon, make sure its db is up-to-date too
495
+		foreach ($this->registry->addons as $addon) {
496
+			$addon->initialize_db_if_no_migrations_required();
497
+		}
498
+	}
499
+
500
+
501
+
502
+	/**
503
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
504
+	 *
505
+	 * @param    array  $version_history
506
+	 * @param    string $current_version_to_add version to be added to the version history
507
+	 * @return    boolean success as to whether or not this option was changed
508
+	 */
509
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
510
+	{
511
+		if ( ! $version_history) {
512
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
513
+		}
514
+		if ($current_version_to_add === null) {
515
+			$current_version_to_add = espresso_version();
516
+		}
517
+		$version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
518
+		// re-save
519
+		return update_option('espresso_db_update', $version_history);
520
+	}
521
+
522
+
523
+
524
+	/**
525
+	 * Detects if the current version indicated in the has existed in the list of
526
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
527
+	 *
528
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
529
+	 *                                  If not supplied, fetches it from the options table.
530
+	 *                                  Also, caches its result so later parts of the code can also know whether
531
+	 *                                  there's been an update or not. This way we can add the current version to
532
+	 *                                  espresso_db_update, but still know if this is a new install or not
533
+	 * @return int one of the constants on EE_System::req_type_
534
+	 */
535
+	public function detect_req_type($espresso_db_update = null)
536
+	{
537
+		if ($this->_req_type === null) {
538
+			$espresso_db_update = ! empty($espresso_db_update) ? $espresso_db_update
539
+				: $this->fix_espresso_db_upgrade_option();
540
+			$this->_req_type = EE_System::detect_req_type_given_activation_history($espresso_db_update,
541
+				'ee_espresso_activation', espresso_version());
542
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
543
+		}
544
+		return $this->_req_type;
545
+	}
546
+
547
+
548
+
549
+	/**
550
+	 * Returns whether or not there was a non-micro version change (ie, change in either
551
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
552
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
553
+	 *
554
+	 * @param $activation_history
555
+	 * @return bool
556
+	 */
557
+	protected function _detect_major_version_change($activation_history)
558
+	{
559
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
560
+		$previous_version_parts = explode('.', $previous_version);
561
+		$current_version_parts = explode('.', espresso_version());
562
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
563
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
564
+				   || $previous_version_parts[1] !== $current_version_parts[1]
565
+			   );
566
+	}
567
+
568
+
569
+
570
+	/**
571
+	 * Returns true if either the major or minor version of EE changed during this request.
572
+	 * 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
573
+	 *
574
+	 * @return bool
575
+	 */
576
+	public function is_major_version_change()
577
+	{
578
+		return $this->_major_version_change;
579
+	}
580
+
581
+
582
+
583
+	/**
584
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
585
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
586
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
587
+	 * just activated to (for core that will always be espresso_version())
588
+	 *
589
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
590
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
591
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
592
+	 *                                                 indicate that this plugin was just activated
593
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
594
+	 *                                                 espresso_version())
595
+	 * @return int one of the constants on EE_System::req_type_*
596
+	 */
597
+	public static function detect_req_type_given_activation_history(
598
+		$activation_history_for_addon,
599
+		$activation_indicator_option_name,
600
+		$version_to_upgrade_to
601
+	) {
602
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
603
+		if ($activation_history_for_addon) {
604
+			//it exists, so this isn't a completely new install
605
+			//check if this version already in that list of previously installed versions
606
+			if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
607
+				//it a version we haven't seen before
608
+				if ($version_is_higher === 1) {
609
+					$req_type = EE_System::req_type_upgrade;
610
+				} else {
611
+					$req_type = EE_System::req_type_downgrade;
612
+				}
613
+				delete_option($activation_indicator_option_name);
614
+			} else {
615
+				// its not an update. maybe a reactivation?
616
+				if (get_option($activation_indicator_option_name, false)) {
617
+					if ($version_is_higher === -1) {
618
+						$req_type = EE_System::req_type_downgrade;
619
+					} elseif ($version_is_higher === 0) {
620
+						//we've seen this version before, but it's an activation. must be a reactivation
621
+						$req_type = EE_System::req_type_reactivation;
622
+					} else {//$version_is_higher === 1
623
+						$req_type = EE_System::req_type_upgrade;
624
+					}
625
+					delete_option($activation_indicator_option_name);
626
+				} else {
627
+					//we've seen this version before and the activation indicate doesn't show it was just activated
628
+					if ($version_is_higher === -1) {
629
+						$req_type = EE_System::req_type_downgrade;
630
+					} elseif ($version_is_higher === 0) {
631
+						//we've seen this version before and it's not an activation. its normal request
632
+						$req_type = EE_System::req_type_normal;
633
+					} else {//$version_is_higher === 1
634
+						$req_type = EE_System::req_type_upgrade;
635
+					}
636
+				}
637
+			}
638
+		} else {
639
+			//brand new install
640
+			$req_type = EE_System::req_type_new_activation;
641
+			delete_option($activation_indicator_option_name);
642
+		}
643
+		return $req_type;
644
+	}
645
+
646
+
647
+
648
+	/**
649
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
650
+	 * the $activation_history_for_addon
651
+	 *
652
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
653
+	 *                                             sometimes containing 'unknown-date'
654
+	 * @param string $version_to_upgrade_to        (current version)
655
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
656
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
657
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
658
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
659
+	 */
660
+	protected static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
661
+	{
662
+		//find the most recently-activated version
663
+		$most_recently_active_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
664
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
665
+	}
666
+
667
+
668
+
669
+	/**
670
+	 * Gets the most recently active version listed in the activation history,
671
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
672
+	 *
673
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
674
+	 *                                   sometimes containing 'unknown-date'
675
+	 * @return string
676
+	 */
677
+	protected static function _get_most_recently_active_version_from_activation_history($activation_history)
678
+	{
679
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
680
+		$most_recently_active_version = '0.0.0.dev.000';
681
+		if (is_array($activation_history)) {
682
+			foreach ($activation_history as $version => $times_activated) {
683
+				//check there is a record of when this version was activated. Otherwise,
684
+				//mark it as unknown
685
+				if ( ! $times_activated) {
686
+					$times_activated = array('unknown-date');
687
+				}
688
+				if (is_string($times_activated)) {
689
+					$times_activated = array($times_activated);
690
+				}
691
+				foreach ($times_activated as $an_activation) {
692
+					if ($an_activation !== 'unknown-date' && $an_activation > $most_recently_active_version_activation) {
693
+						$most_recently_active_version = $version;
694
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
695
+							? '1970-01-01 00:00:00' : $an_activation;
696
+					}
697
+				}
698
+			}
699
+		}
700
+		return $most_recently_active_version;
701
+	}
702
+
703
+
704
+
705
+	/**
706
+	 * This redirects to the about EE page after activation
707
+	 *
708
+	 * @return void
709
+	 */
710
+	public function redirect_to_about_ee()
711
+	{
712
+		$notices = EE_Error::get_notices(false);
713
+		//if current user is an admin and it's not an ajax or rest request
714
+		if (
715
+			! (defined('DOING_AJAX') && DOING_AJAX)
716
+			&& ! (defined('REST_REQUEST') && REST_REQUEST)
717
+			&& ! isset($notices['errors'])
718
+			&& apply_filters(
719
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
720
+				$this->registry->CAP->current_user_can('manage_options', 'espresso_about_default')
721
+			)
722
+		) {
723
+			$query_params = array('page' => 'espresso_about');
724
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
725
+				$query_params['new_activation'] = true;
726
+			}
727
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
728
+				$query_params['reactivation'] = true;
729
+			}
730
+			$url = add_query_arg($query_params, admin_url('admin.php'));
731
+			wp_safe_redirect($url);
732
+			exit();
733
+		}
734
+	}
735
+
736
+
737
+
738
+	/**
739
+	 * load_core_configuration
740
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
741
+	 * which runs during the WP 'plugins_loaded' action at priority 5
742
+	 *
743
+	 * @return void
744
+	 * @throws \ReflectionException
745
+	 */
746
+	public function load_core_configuration()
747
+	{
748
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
749
+		$this->registry->load_core('EE_Load_Textdomain');
750
+		//load textdomain
751
+		EE_Load_Textdomain::load_textdomain();
752
+		// load and setup EE_Config and EE_Network_Config
753
+		$this->registry->load_core('Config');
754
+		$this->registry->load_core('Network_Config');
755
+		// setup autoloaders
756
+		// enable logging?
757
+		if ($this->registry->CFG->admin->use_full_logging) {
758
+			$this->registry->load_core('Log');
759
+		}
760
+		// check for activation errors
761
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
762
+		if ($activation_errors) {
763
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
764
+			update_option('ee_plugin_activation_errors', false);
765
+		}
766
+		// get model names
767
+		$this->_parse_model_names();
768
+		//load caf stuff a chance to play during the activation process too.
769
+		$this->_maybe_brew_regular();
770
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
771
+	}
772
+
773
+
774
+
775
+	/**
776
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
777
+	 *
778
+	 * @return void
779
+	 * @throws ReflectionException
780
+	 */
781
+	private function _parse_model_names()
782
+	{
783
+		//get all the files in the EE_MODELS folder that end in .model.php
784
+		$models = glob(EE_MODELS . '*.model.php');
785
+		$model_names = array();
786
+		$non_abstract_db_models = array();
787
+		foreach ($models as $model) {
788
+			// get model classname
789
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
790
+			$short_name = str_replace('EEM_', '', $classname);
791
+			$reflectionClass = new ReflectionClass($classname);
792
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
793
+				$non_abstract_db_models[$short_name] = $classname;
794
+			}
795
+			$model_names[$short_name] = $classname;
796
+		}
797
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
798
+		$this->registry->non_abstract_db_models = apply_filters('FHEE__EE_System__parse_implemented_model_names',
799
+			$non_abstract_db_models);
800
+	}
801
+
802
+
803
+
804
+	/**
805
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
806
+	 * that need to be setup before our EE_System launches.
807
+	 *
808
+	 * @return void
809
+	 */
810
+	private function _maybe_brew_regular()
811
+	{
812
+		if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
813
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
814
+		}
815
+	}
816
+
817
+
818
+
819
+	/**
820
+	 * register_shortcodes_modules_and_widgets
821
+	 * generate lists of shortcodes and modules, then verify paths and classes
822
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
823
+	 * which runs during the WP 'plugins_loaded' action at priority 7
824
+	 *
825
+	 * @access public
826
+	 * @return void
827
+	 */
828
+	public function register_shortcodes_modules_and_widgets()
829
+	{
830
+		try {
831
+			// load, register, and add shortcodes the new way
832
+			new ShortcodesManager(
833
+			// and the old way, but we'll put it under control of the new system
834
+				EE_Config::getLegacyShortcodesManager()
835
+			);
836
+		} catch (Exception $exception) {
837
+			new ExceptionStackTraceDisplay($exception);
838
+		}
839
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
840
+		// check for addons using old hook point
841
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
842
+			$this->_incompatible_addon_error();
843
+		}
844
+	}
845
+
846
+
847
+
848
+	/**
849
+	 * _incompatible_addon_error
850
+	 *
851
+	 * @access public
852
+	 * @return void
853
+	 */
854
+	private function _incompatible_addon_error()
855
+	{
856
+		// get array of classes hooking into here
857
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook('AHEE__EE_System__register_shortcodes_modules_and_addons');
858
+		if ( ! empty($class_names)) {
859
+			$msg = __('The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
860
+				'event_espresso');
861
+			$msg .= '<ul>';
862
+			foreach ($class_names as $class_name) {
863
+				$msg .= '<li><b>Event Espresso - ' . str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
864
+						$class_name) . '</b></li>';
865
+			}
866
+			$msg .= '</ul>';
867
+			$msg .= __('Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
868
+				'event_espresso');
869
+			// save list of incompatible addons to wp-options for later use
870
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
871
+			if (is_admin()) {
872
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
873
+			}
874
+		}
875
+	}
876
+
877
+
878
+
879
+	/**
880
+	 * brew_espresso
881
+	 * begins the process of setting hooks for initializing EE in the correct order
882
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
883
+	 * which runs during the WP 'plugins_loaded' action at priority 9
884
+	 *
885
+	 * @return void
886
+	 */
887
+	public function brew_espresso()
888
+	{
889
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
890
+		// load some final core systems
891
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
892
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
893
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
894
+		add_action('init', array($this, 'load_controllers'), 7);
895
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
896
+		add_action('init', array($this, 'initialize'), 10);
897
+		add_action('init', array($this, 'initialize_last'), 100);
898
+		add_action('admin_bar_menu', array($this, 'espresso_toolbar_items'), 100);
899
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
900
+			// pew pew pew
901
+			$this->registry->load_core('PUE');
902
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
903
+		}
904
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
905
+	}
906
+
907
+
908
+
909
+	/**
910
+	 *    set_hooks_for_core
911
+	 *
912
+	 * @access public
913
+	 * @return    void
914
+	 * @throws EE_Error
915
+	 */
916
+	public function set_hooks_for_core()
917
+	{
918
+		$this->_deactivate_incompatible_addons();
919
+		do_action('AHEE__EE_System__set_hooks_for_core');
920
+		//caps need to be initialized on every request so that capability maps are set.
921
+		//@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
922
+		$this->registry->CAP->init_caps();
923
+	}
924
+
925
+
926
+
927
+	/**
928
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
929
+	 * deactivates any addons considered incompatible with the current version of EE
930
+	 */
931
+	private function _deactivate_incompatible_addons()
932
+	{
933
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
934
+		if ( ! empty($incompatible_addons)) {
935
+			$active_plugins = get_option('active_plugins', array());
936
+			foreach ($active_plugins as $active_plugin) {
937
+				foreach ($incompatible_addons as $incompatible_addon) {
938
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
939
+						unset($_GET['activate']);
940
+						espresso_deactivate_plugin($active_plugin);
941
+					}
942
+				}
943
+			}
944
+		}
945
+	}
946
+
947
+
948
+
949
+	/**
950
+	 *    perform_activations_upgrades_and_migrations
951
+	 *
952
+	 * @access public
953
+	 * @return    void
954
+	 */
955
+	public function perform_activations_upgrades_and_migrations()
956
+	{
957
+		//first check if we had previously attempted to setup EE's directories but failed
958
+		if (EEH_Activation::upload_directories_incomplete()) {
959
+			EEH_Activation::create_upload_directories();
960
+		}
961
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
962
+	}
963
+
964
+
965
+
966
+	/**
967
+	 *    load_CPTs_and_session
968
+	 *
969
+	 * @access public
970
+	 * @return    void
971
+	 */
972
+	public function load_CPTs_and_session()
973
+	{
974
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
975
+		// register Custom Post Types
976
+		$this->registry->load_core('Register_CPTs');
977
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
978
+	}
979
+
980
+
981
+
982
+	/**
983
+	 * load_controllers
984
+	 * this is the best place to load any additional controllers that needs access to EE core.
985
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
986
+	 * time
987
+	 *
988
+	 * @access public
989
+	 * @return void
990
+	 */
991
+	public function load_controllers()
992
+	{
993
+		do_action('AHEE__EE_System__load_controllers__start');
994
+		// let's get it started
995
+		if ( ! is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
996
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
997
+			$this->registry->load_core('Front_Controller');
998
+		} else if ( ! EE_FRONT_AJAX) {
999
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1000
+			EE_Registry::instance()->load_core('Admin');
1001
+		}
1002
+		do_action('AHEE__EE_System__load_controllers__complete');
1003
+	}
1004
+
1005
+
1006
+
1007
+	/**
1008
+	 * core_loaded_and_ready
1009
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1010
+	 *
1011
+	 * @access public
1012
+	 * @return void
1013
+	 */
1014
+	public function core_loaded_and_ready()
1015
+	{
1016
+		$this->registry->load_core('Session');
1017
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1018
+		// load_espresso_template_tags
1019
+		if (is_readable(EE_PUBLIC . 'template_tags.php')) {
1020
+			require_once(EE_PUBLIC . 'template_tags.php');
1021
+		}
1022
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1023
+		$this->registry->create('EventEspresso\core\services\assets\Registry', array(), true);
1024
+	}
1025
+
1026
+
1027
+
1028
+	/**
1029
+	 * initialize
1030
+	 * this is the best place to begin initializing client code
1031
+	 *
1032
+	 * @access public
1033
+	 * @return void
1034
+	 */
1035
+	public function initialize()
1036
+	{
1037
+		do_action('AHEE__EE_System__initialize');
1038
+	}
1039
+
1040
+
1041
+
1042
+	/**
1043
+	 * initialize_last
1044
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1045
+	 * initialize has done so
1046
+	 *
1047
+	 * @access public
1048
+	 * @return void
1049
+	 */
1050
+	public function initialize_last()
1051
+	{
1052
+		do_action('AHEE__EE_System__initialize_last');
1053
+	}
1054
+
1055
+
1056
+
1057
+	/**
1058
+	 * set_hooks_for_shortcodes_modules_and_addons
1059
+	 * this is the best place for other systems to set callbacks for hooking into other parts of EE
1060
+	 * this happens at the very beginning of the wp_loaded hook point
1061
+	 *
1062
+	 * @access public
1063
+	 * @return void
1064
+	 */
1065
+	public function set_hooks_for_shortcodes_modules_and_addons()
1066
+	{
1067
+		//		do_action( 'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons' );
1068
+	}
1069
+
1070
+
1071
+
1072
+	/**
1073
+	 * do_not_cache
1074
+	 * sets no cache headers and defines no cache constants for WP plugins
1075
+	 *
1076
+	 * @access public
1077
+	 * @return void
1078
+	 */
1079
+	public static function do_not_cache()
1080
+	{
1081
+		// set no cache constants
1082
+		if ( ! defined('DONOTCACHEPAGE')) {
1083
+			define('DONOTCACHEPAGE', true);
1084
+		}
1085
+		if ( ! defined('DONOTCACHCEOBJECT')) {
1086
+			define('DONOTCACHCEOBJECT', true);
1087
+		}
1088
+		if ( ! defined('DONOTCACHEDB')) {
1089
+			define('DONOTCACHEDB', true);
1090
+		}
1091
+		// add no cache headers
1092
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1093
+		// plus a little extra for nginx and Google Chrome
1094
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1095
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1096
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1097
+	}
1098
+
1099
+
1100
+
1101
+	/**
1102
+	 *    extra_nocache_headers
1103
+	 *
1104
+	 * @access    public
1105
+	 * @param $headers
1106
+	 * @return    array
1107
+	 */
1108
+	public static function extra_nocache_headers($headers)
1109
+	{
1110
+		// for NGINX
1111
+		$headers['X-Accel-Expires'] = 0;
1112
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1113
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1114
+		return $headers;
1115
+	}
1116
+
1117
+
1118
+
1119
+	/**
1120
+	 *    nocache_headers
1121
+	 *
1122
+	 * @access    public
1123
+	 * @return    void
1124
+	 */
1125
+	public static function nocache_headers()
1126
+	{
1127
+		nocache_headers();
1128
+	}
1129
+
1130
+
1131
+
1132
+	/**
1133
+	 *    espresso_toolbar_items
1134
+	 *
1135
+	 * @access public
1136
+	 * @param  WP_Admin_Bar $admin_bar
1137
+	 * @return void
1138
+	 */
1139
+	public function espresso_toolbar_items(WP_Admin_Bar $admin_bar)
1140
+	{
1141
+		// if in full M-Mode, or its an AJAX request, or user is NOT an admin
1142
+		if (
1143
+			defined('DOING_AJAX')
1144
+			|| ! $this->registry->CAP->current_user_can('ee_read_ee', 'ee_admin_bar_menu_top_level')
1145
+			|| EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
1146
+		) {
1147
+			return;
1148
+		}
1149
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1150
+		$menu_class = 'espresso_menu_item_class';
1151
+		//we don't use the constants EVENTS_ADMIN_URL or REG_ADMIN_URL
1152
+		//because they're only defined in each of their respective constructors
1153
+		//and this might be a frontend request, in which case they aren't available
1154
+		$events_admin_url = admin_url('admin.php?page=espresso_events');
1155
+		$reg_admin_url = admin_url('admin.php?page=espresso_registrations');
1156
+		$extensions_admin_url = admin_url('admin.php?page=espresso_packages');
1157
+		//Top Level
1158
+		$admin_bar->add_menu(array(
1159
+			'id'    => 'espresso-toolbar',
1160
+			'title' => '<span class="ee-icon ee-icon-ee-cup-thick ee-icon-size-20"></span><span class="ab-label">'
1161
+					   . _x('Event Espresso', 'admin bar menu group label', 'event_espresso')
1162
+					   . '</span>',
1163
+			'href'  => $events_admin_url,
1164
+			'meta'  => array(
1165
+				'title' => __('Event Espresso', 'event_espresso'),
1166
+				'class' => $menu_class . 'first',
1167
+			),
1168
+		));
1169
+		//Events
1170
+		if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events')) {
1171
+			$admin_bar->add_menu(array(
1172
+				'id'     => 'espresso-toolbar-events',
1173
+				'parent' => 'espresso-toolbar',
1174
+				'title'  => __('Events', 'event_espresso'),
1175
+				'href'   => $events_admin_url,
1176
+				'meta'   => array(
1177
+					'title'  => __('Events', 'event_espresso'),
1178
+					'target' => '',
1179
+					'class'  => $menu_class,
1180
+				),
1181
+			));
1182
+		}
1183
+		if ($this->registry->CAP->current_user_can('ee_edit_events', 'ee_admin_bar_menu_espresso-toolbar-events-new')) {
1184
+			//Events Add New
1185
+			$admin_bar->add_menu(array(
1186
+				'id'     => 'espresso-toolbar-events-new',
1187
+				'parent' => 'espresso-toolbar-events',
1188
+				'title'  => __('Add New', 'event_espresso'),
1189
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'create_new'), $events_admin_url),
1190
+				'meta'   => array(
1191
+					'title'  => __('Add New', 'event_espresso'),
1192
+					'target' => '',
1193
+					'class'  => $menu_class,
1194
+				),
1195
+			));
1196
+		}
1197
+		if (is_single() && (get_post_type() === 'espresso_events')) {
1198
+			//Current post
1199
+			global $post;
1200
+			if ($this->registry->CAP->current_user_can('ee_edit_event',
1201
+				'ee_admin_bar_menu_espresso-toolbar-events-edit', $post->ID)
1202
+			) {
1203
+				//Events Edit Current Event
1204
+				$admin_bar->add_menu(array(
1205
+					'id'     => 'espresso-toolbar-events-edit',
1206
+					'parent' => 'espresso-toolbar-events',
1207
+					'title'  => __('Edit Event', 'event_espresso'),
1208
+					'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'edit', 'post' => $post->ID),
1209
+						$events_admin_url),
1210
+					'meta'   => array(
1211
+						'title'  => __('Edit Event', 'event_espresso'),
1212
+						'target' => '',
1213
+						'class'  => $menu_class,
1214
+					),
1215
+				));
1216
+			}
1217
+		}
1218
+		//Events View
1219
+		if ($this->registry->CAP->current_user_can('ee_read_events',
1220
+			'ee_admin_bar_menu_espresso-toolbar-events-view')
1221
+		) {
1222
+			$admin_bar->add_menu(array(
1223
+				'id'     => 'espresso-toolbar-events-view',
1224
+				'parent' => 'espresso-toolbar-events',
1225
+				'title'  => __('View', 'event_espresso'),
1226
+				'href'   => $events_admin_url,
1227
+				'meta'   => array(
1228
+					'title'  => __('View', 'event_espresso'),
1229
+					'target' => '',
1230
+					'class'  => $menu_class,
1231
+				),
1232
+			));
1233
+		}
1234
+		if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-all')) {
1235
+			//Events View All
1236
+			$admin_bar->add_menu(array(
1237
+				'id'     => 'espresso-toolbar-events-all',
1238
+				'parent' => 'espresso-toolbar-events-view',
1239
+				'title'  => __('All', 'event_espresso'),
1240
+				'href'   => $events_admin_url,
1241
+				'meta'   => array(
1242
+					'title'  => __('All', 'event_espresso'),
1243
+					'target' => '',
1244
+					'class'  => $menu_class,
1245
+				),
1246
+			));
1247
+		}
1248
+		if ($this->registry->CAP->current_user_can('ee_read_events',
1249
+			'ee_admin_bar_menu_espresso-toolbar-events-today')
1250
+		) {
1251
+			//Events View Today
1252
+			$admin_bar->add_menu(array(
1253
+				'id'     => 'espresso-toolbar-events-today',
1254
+				'parent' => 'espresso-toolbar-events-view',
1255
+				'title'  => __('Today', 'event_espresso'),
1256
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1257
+					$events_admin_url),
1258
+				'meta'   => array(
1259
+					'title'  => __('Today', 'event_espresso'),
1260
+					'target' => '',
1261
+					'class'  => $menu_class,
1262
+				),
1263
+			));
1264
+		}
1265
+		if ($this->registry->CAP->current_user_can('ee_read_events',
1266
+			'ee_admin_bar_menu_espresso-toolbar-events-month')
1267
+		) {
1268
+			//Events View This Month
1269
+			$admin_bar->add_menu(array(
1270
+				'id'     => 'espresso-toolbar-events-month',
1271
+				'parent' => 'espresso-toolbar-events-view',
1272
+				'title'  => __('This Month', 'event_espresso'),
1273
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1274
+					$events_admin_url),
1275
+				'meta'   => array(
1276
+					'title'  => __('This Month', 'event_espresso'),
1277
+					'target' => '',
1278
+					'class'  => $menu_class,
1279
+				),
1280
+			));
1281
+		}
1282
+		//Registration Overview
1283
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1284
+			'ee_admin_bar_menu_espresso-toolbar-registrations')
1285
+		) {
1286
+			$admin_bar->add_menu(array(
1287
+				'id'     => 'espresso-toolbar-registrations',
1288
+				'parent' => 'espresso-toolbar',
1289
+				'title'  => __('Registrations', 'event_espresso'),
1290
+				'href'   => $reg_admin_url,
1291
+				'meta'   => array(
1292
+					'title'  => __('Registrations', 'event_espresso'),
1293
+					'target' => '',
1294
+					'class'  => $menu_class,
1295
+				),
1296
+			));
1297
+		}
1298
+		//Registration Overview Today
1299
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1300
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today')
1301
+		) {
1302
+			$admin_bar->add_menu(array(
1303
+				'id'     => 'espresso-toolbar-registrations-today',
1304
+				'parent' => 'espresso-toolbar-registrations',
1305
+				'title'  => __('Today', 'event_espresso'),
1306
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1307
+					$reg_admin_url),
1308
+				'meta'   => array(
1309
+					'title'  => __('Today', 'event_espresso'),
1310
+					'target' => '',
1311
+					'class'  => $menu_class,
1312
+				),
1313
+			));
1314
+		}
1315
+		//Registration Overview Today Completed
1316
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1317
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-approved')
1318
+		) {
1319
+			$admin_bar->add_menu(array(
1320
+				'id'     => 'espresso-toolbar-registrations-today-approved',
1321
+				'parent' => 'espresso-toolbar-registrations-today',
1322
+				'title'  => __('Approved', 'event_espresso'),
1323
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1324
+					'action'      => 'default',
1325
+					'status'      => 'today',
1326
+					'_reg_status' => EEM_Registration::status_id_approved,
1327
+				), $reg_admin_url),
1328
+				'meta'   => array(
1329
+					'title'  => __('Approved', 'event_espresso'),
1330
+					'target' => '',
1331
+					'class'  => $menu_class,
1332
+				),
1333
+			));
1334
+		}
1335
+		//Registration Overview Today Pending\
1336
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1337
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-pending')
1338
+		) {
1339
+			$admin_bar->add_menu(array(
1340
+				'id'     => 'espresso-toolbar-registrations-today-pending',
1341
+				'parent' => 'espresso-toolbar-registrations-today',
1342
+				'title'  => __('Pending', 'event_espresso'),
1343
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1344
+					'action'     => 'default',
1345
+					'status'     => 'today',
1346
+					'reg_status' => EEM_Registration::status_id_pending_payment,
1347
+				), $reg_admin_url),
1348
+				'meta'   => array(
1349
+					'title'  => __('Pending Payment', 'event_espresso'),
1350
+					'target' => '',
1351
+					'class'  => $menu_class,
1352
+				),
1353
+			));
1354
+		}
1355
+		//Registration Overview Today Incomplete
1356
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1357
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-not-approved')
1358
+		) {
1359
+			$admin_bar->add_menu(array(
1360
+				'id'     => 'espresso-toolbar-registrations-today-not-approved',
1361
+				'parent' => 'espresso-toolbar-registrations-today',
1362
+				'title'  => __('Not Approved', 'event_espresso'),
1363
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1364
+					'action'      => 'default',
1365
+					'status'      => 'today',
1366
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1367
+				), $reg_admin_url),
1368
+				'meta'   => array(
1369
+					'title'  => __('Not Approved', 'event_espresso'),
1370
+					'target' => '',
1371
+					'class'  => $menu_class,
1372
+				),
1373
+			));
1374
+		}
1375
+		//Registration Overview Today Incomplete
1376
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1377
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-cancelled')
1378
+		) {
1379
+			$admin_bar->add_menu(array(
1380
+				'id'     => 'espresso-toolbar-registrations-today-cancelled',
1381
+				'parent' => 'espresso-toolbar-registrations-today',
1382
+				'title'  => __('Cancelled', 'event_espresso'),
1383
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1384
+					'action'      => 'default',
1385
+					'status'      => 'today',
1386
+					'_reg_status' => EEM_Registration::status_id_cancelled,
1387
+				), $reg_admin_url),
1388
+				'meta'   => array(
1389
+					'title'  => __('Cancelled', 'event_espresso'),
1390
+					'target' => '',
1391
+					'class'  => $menu_class,
1392
+				),
1393
+			));
1394
+		}
1395
+		//Registration Overview This Month
1396
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1397
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month')
1398
+		) {
1399
+			$admin_bar->add_menu(array(
1400
+				'id'     => 'espresso-toolbar-registrations-month',
1401
+				'parent' => 'espresso-toolbar-registrations',
1402
+				'title'  => __('This Month', 'event_espresso'),
1403
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1404
+					$reg_admin_url),
1405
+				'meta'   => array(
1406
+					'title'  => __('This Month', 'event_espresso'),
1407
+					'target' => '',
1408
+					'class'  => $menu_class,
1409
+				),
1410
+			));
1411
+		}
1412
+		//Registration Overview This Month Approved
1413
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1414
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-approved')
1415
+		) {
1416
+			$admin_bar->add_menu(array(
1417
+				'id'     => 'espresso-toolbar-registrations-month-approved',
1418
+				'parent' => 'espresso-toolbar-registrations-month',
1419
+				'title'  => __('Approved', 'event_espresso'),
1420
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1421
+					'action'      => 'default',
1422
+					'status'      => 'month',
1423
+					'_reg_status' => EEM_Registration::status_id_approved,
1424
+				), $reg_admin_url),
1425
+				'meta'   => array(
1426
+					'title'  => __('Approved', 'event_espresso'),
1427
+					'target' => '',
1428
+					'class'  => $menu_class,
1429
+				),
1430
+			));
1431
+		}
1432
+		//Registration Overview This Month Pending
1433
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1434
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-pending')
1435
+		) {
1436
+			$admin_bar->add_menu(array(
1437
+				'id'     => 'espresso-toolbar-registrations-month-pending',
1438
+				'parent' => 'espresso-toolbar-registrations-month',
1439
+				'title'  => __('Pending', 'event_espresso'),
1440
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1441
+					'action'      => 'default',
1442
+					'status'      => 'month',
1443
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1444
+				), $reg_admin_url),
1445
+				'meta'   => array(
1446
+					'title'  => __('Pending', 'event_espresso'),
1447
+					'target' => '',
1448
+					'class'  => $menu_class,
1449
+				),
1450
+			));
1451
+		}
1452
+		//Registration Overview This Month Not Approved
1453
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1454
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-not-approved')
1455
+		) {
1456
+			$admin_bar->add_menu(array(
1457
+				'id'     => 'espresso-toolbar-registrations-month-not-approved',
1458
+				'parent' => 'espresso-toolbar-registrations-month',
1459
+				'title'  => __('Not Approved', 'event_espresso'),
1460
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1461
+					'action'      => 'default',
1462
+					'status'      => 'month',
1463
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1464
+				), $reg_admin_url),
1465
+				'meta'   => array(
1466
+					'title'  => __('Not Approved', 'event_espresso'),
1467
+					'target' => '',
1468
+					'class'  => $menu_class,
1469
+				),
1470
+			));
1471
+		}
1472
+		//Registration Overview This Month Cancelled
1473
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1474
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-cancelled')
1475
+		) {
1476
+			$admin_bar->add_menu(array(
1477
+				'id'     => 'espresso-toolbar-registrations-month-cancelled',
1478
+				'parent' => 'espresso-toolbar-registrations-month',
1479
+				'title'  => __('Cancelled', 'event_espresso'),
1480
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1481
+					'action'      => 'default',
1482
+					'status'      => 'month',
1483
+					'_reg_status' => EEM_Registration::status_id_cancelled,
1484
+				), $reg_admin_url),
1485
+				'meta'   => array(
1486
+					'title'  => __('Cancelled', 'event_espresso'),
1487
+					'target' => '',
1488
+					'class'  => $menu_class,
1489
+				),
1490
+			));
1491
+		}
1492
+		//Extensions & Services
1493
+		if ($this->registry->CAP->current_user_can('ee_read_ee',
1494
+			'ee_admin_bar_menu_espresso-toolbar-extensions-and-services')
1495
+		) {
1496
+			$admin_bar->add_menu(array(
1497
+				'id'     => 'espresso-toolbar-extensions-and-services',
1498
+				'parent' => 'espresso-toolbar',
1499
+				'title'  => __('Extensions & Services', 'event_espresso'),
1500
+				'href'   => $extensions_admin_url,
1501
+				'meta'   => array(
1502
+					'title'  => __('Extensions & Services', 'event_espresso'),
1503
+					'target' => '',
1504
+					'class'  => $menu_class,
1505
+				),
1506
+			));
1507
+		}
1508
+	}
1509
+
1510
+
1511
+
1512
+	/**
1513
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1514
+	 * never returned with the function.
1515
+	 *
1516
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1517
+	 * @return array
1518
+	 */
1519
+	public function remove_pages_from_wp_list_pages($exclude_array)
1520
+	{
1521
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1522
+	}
1523 1523
 
1524 1524
 
1525 1525
 
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
     {
262 262
         // set autoloaders for all of the classes implementing EEI_Plugin_API
263 263
         // which provide helpers for EE plugin authors to more easily register certain components with EE.
264
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
264
+        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'plugin_api');
265 265
     }
266 266
 
267 267
 
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
                 && in_array($_GET['action'], array('activate', 'activate-selected'), true)
296 296
             )
297 297
         ) {
298
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
298
+            include_once EE_THIRD_PARTY.'wp-api-basic-auth'.DS.'basic-auth.php';
299 299
         }
300 300
         do_action('AHEE__EE_System__load_espresso_addons__complete');
301 301
     }
@@ -781,7 +781,7 @@  discard block
 block discarded – undo
781 781
     private function _parse_model_names()
782 782
     {
783 783
         //get all the files in the EE_MODELS folder that end in .model.php
784
-        $models = glob(EE_MODELS . '*.model.php');
784
+        $models = glob(EE_MODELS.'*.model.php');
785 785
         $model_names = array();
786 786
         $non_abstract_db_models = array();
787 787
         foreach ($models as $model) {
@@ -809,8 +809,8 @@  discard block
 block discarded – undo
809 809
      */
810 810
     private function _maybe_brew_regular()
811 811
     {
812
-        if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
813
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
812
+        if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH.'brewing_regular.php')) {
813
+            require_once EE_CAFF_PATH.'brewing_regular.php';
814 814
         }
815 815
     }
816 816
 
@@ -860,8 +860,8 @@  discard block
 block discarded – undo
860 860
                 'event_espresso');
861 861
             $msg .= '<ul>';
862 862
             foreach ($class_names as $class_name) {
863
-                $msg .= '<li><b>Event Espresso - ' . str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
864
-                        $class_name) . '</b></li>';
863
+                $msg .= '<li><b>Event Espresso - '.str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
864
+                        $class_name).'</b></li>';
865 865
             }
866 866
             $msg .= '</ul>';
867 867
             $msg .= __('Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
@@ -1016,8 +1016,8 @@  discard block
 block discarded – undo
1016 1016
         $this->registry->load_core('Session');
1017 1017
         do_action('AHEE__EE_System__core_loaded_and_ready');
1018 1018
         // load_espresso_template_tags
1019
-        if (is_readable(EE_PUBLIC . 'template_tags.php')) {
1020
-            require_once(EE_PUBLIC . 'template_tags.php');
1019
+        if (is_readable(EE_PUBLIC.'template_tags.php')) {
1020
+            require_once(EE_PUBLIC.'template_tags.php');
1021 1021
         }
1022 1022
         do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1023 1023
         $this->registry->create('EventEspresso\core\services\assets\Registry', array(), true);
@@ -1163,7 +1163,7 @@  discard block
 block discarded – undo
1163 1163
             'href'  => $events_admin_url,
1164 1164
             'meta'  => array(
1165 1165
                 'title' => __('Event Espresso', 'event_espresso'),
1166
-                'class' => $menu_class . 'first',
1166
+                'class' => $menu_class.'first',
1167 1167
             ),
1168 1168
         ));
1169 1169
         //Events
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +219 added lines, -219 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('ABSPATH')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 /*
5 5
   Plugin Name:		Event Espresso
@@ -40,243 +40,243 @@  discard block
 block discarded – undo
40 40
  * @since            4.0
41 41
  */
42 42
 if (function_exists('espresso_version')) {
43
-    /**
44
-     *    espresso_duplicate_plugin_error
45
-     *    displays if more than one version of EE is activated at the same time
46
-     */
47
-    function espresso_duplicate_plugin_error()
48
-    {
49
-        ?>
43
+	/**
44
+	 *    espresso_duplicate_plugin_error
45
+	 *    displays if more than one version of EE is activated at the same time
46
+	 */
47
+	function espresso_duplicate_plugin_error()
48
+	{
49
+		?>
50 50
         <div class="error">
51 51
             <p>
52 52
                 <?php echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                ); ?>
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+				); ?>
56 56
             </p>
57 57
         </div>
58 58
         <?php
59
-        espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-    }
59
+		espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+	}
61 61
 
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
65
-    if ( ! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
65
+	if ( ! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                            esc_html__(
79
-                                    'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                                    'event_espresso'
81
-                            ),
82
-                            EE_MIN_PHP_VER_REQUIRED,
83
-                            PHP_VERSION,
84
-                            '<br/>',
85
-                            '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+							esc_html__(
79
+									'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+									'event_espresso'
81
+							),
82
+							EE_MIN_PHP_VER_REQUIRED,
83
+							PHP_VERSION,
84
+							'<br/>',
85
+							'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        /**
97
-         * espresso_version
98
-         * Returns the plugin version
99
-         *
100
-         * @return string
101
-         */
102
-        function espresso_version()
103
-        {
104
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.45.rc.014');
105
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		/**
97
+		 * espresso_version
98
+		 * Returns the plugin version
99
+		 *
100
+		 * @return string
101
+		 */
102
+		function espresso_version()
103
+		{
104
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.45.rc.014');
105
+		}
106 106
 
107
-        // define versions
108
-        define('EVENT_ESPRESSO_VERSION', espresso_version());
109
-        define('EE_MIN_WP_VER_REQUIRED', '4.1');
110
-        define('EE_MIN_WP_VER_RECOMMENDED', '4.4.2');
111
-        define('EE_MIN_PHP_VER_RECOMMENDED', '5.4.44');
112
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
113
-        //used to be DIRECTORY_SEPARATOR, but that caused issues on windows
114
-        if ( ! defined('DS')) {
115
-            define('DS', '/');
116
-        }
117
-        if ( ! defined('PS')) {
118
-            define('PS', PATH_SEPARATOR);
119
-        }
120
-        if ( ! defined('SP')) {
121
-            define('SP', ' ');
122
-        }
123
-        if ( ! defined('EENL')) {
124
-            define('EENL', "\n");
125
-        }
126
-        define('EE_SUPPORT_EMAIL', '[email protected]');
127
-        // define the plugin directory and URL
128
-        define('EE_PLUGIN_BASENAME', plugin_basename(EVENT_ESPRESSO_MAIN_FILE));
129
-        define('EE_PLUGIN_DIR_PATH', plugin_dir_path(EVENT_ESPRESSO_MAIN_FILE));
130
-        define('EE_PLUGIN_DIR_URL', plugin_dir_url(EVENT_ESPRESSO_MAIN_FILE));
131
-        // main root folder paths
132
-        define('EE_ADMIN_PAGES', EE_PLUGIN_DIR_PATH . 'admin_pages' . DS);
133
-        define('EE_CORE', EE_PLUGIN_DIR_PATH . 'core' . DS);
134
-        define('EE_MODULES', EE_PLUGIN_DIR_PATH . 'modules' . DS);
135
-        define('EE_PUBLIC', EE_PLUGIN_DIR_PATH . 'public' . DS);
136
-        define('EE_SHORTCODES', EE_PLUGIN_DIR_PATH . 'shortcodes' . DS);
137
-        define('EE_WIDGETS', EE_PLUGIN_DIR_PATH . 'widgets' . DS);
138
-        define('EE_PAYMENT_METHODS', EE_PLUGIN_DIR_PATH . 'payment_methods' . DS);
139
-        define('EE_CAFF_PATH', EE_PLUGIN_DIR_PATH . 'caffeinated' . DS);
140
-        // core system paths
141
-        define('EE_ADMIN', EE_CORE . 'admin' . DS);
142
-        define('EE_CPTS', EE_CORE . 'CPTs' . DS);
143
-        define('EE_CLASSES', EE_CORE . 'db_classes' . DS);
144
-        define('EE_INTERFACES', EE_CORE . 'interfaces' . DS);
145
-        define('EE_BUSINESS', EE_CORE . 'business' . DS);
146
-        define('EE_MODELS', EE_CORE . 'db_models' . DS);
147
-        define('EE_HELPERS', EE_CORE . 'helpers' . DS);
148
-        define('EE_LIBRARIES', EE_CORE . 'libraries' . DS);
149
-        define('EE_TEMPLATES', EE_CORE . 'templates' . DS);
150
-        define('EE_THIRD_PARTY', EE_CORE . 'third_party_libs' . DS);
151
-        define('EE_GLOBAL_ASSETS', EE_TEMPLATES . 'global_assets' . DS);
152
-        define('EE_FORM_SECTIONS', EE_LIBRARIES . 'form_sections' . DS);
153
-        // gateways
154
-        define('EE_GATEWAYS', EE_MODULES . 'gateways' . DS);
155
-        define('EE_GATEWAYS_URL', EE_PLUGIN_DIR_URL . 'modules' . DS . 'gateways' . DS);
156
-        // asset URL paths
157
-        define('EE_TEMPLATES_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'templates' . DS);
158
-        define('EE_GLOBAL_ASSETS_URL', EE_TEMPLATES_URL . 'global_assets' . DS);
159
-        define('EE_IMAGES_URL', EE_GLOBAL_ASSETS_URL . 'images' . DS);
160
-        define('EE_THIRD_PARTY_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'third_party_libs' . DS);
161
-        define('EE_HELPERS_ASSETS', EE_PLUGIN_DIR_URL . 'core/helpers/assets/');
162
-        define('EE_LIBRARIES_URL', EE_PLUGIN_DIR_URL . 'core/libraries/');
163
-        // define upload paths
164
-        $uploads = wp_upload_dir();
165
-        // define the uploads directory and URL
166
-        define('EVENT_ESPRESSO_UPLOAD_DIR', $uploads['basedir'] . DS . 'espresso' . DS);
167
-        define('EVENT_ESPRESSO_UPLOAD_URL', $uploads['baseurl'] . DS . 'espresso' . DS);
168
-        // define the templates directory and URL
169
-        define('EVENT_ESPRESSO_TEMPLATE_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'templates' . DS);
170
-        define('EVENT_ESPRESSO_TEMPLATE_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'templates' . DS);
171
-        // define the gateway directory and URL
172
-        define('EVENT_ESPRESSO_GATEWAY_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'gateways' . DS);
173
-        define('EVENT_ESPRESSO_GATEWAY_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'gateways' . DS);
174
-        // languages folder/path
175
-        define('EE_LANGUAGES_SAFE_LOC', '..' . DS . 'uploads' . DS . 'espresso' . DS . 'languages' . DS);
176
-        define('EE_LANGUAGES_SAFE_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'languages' . DS);
177
-        //check for dompdf fonts in uploads
178
-        if (file_exists(EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS)) {
179
-            define('DOMPDF_FONT_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS);
180
-        }
181
-        //ajax constants
182
-        define(
183
-                'EE_FRONT_AJAX',
184
-                isset($_REQUEST['ee_front_ajax']) || isset($_REQUEST['data']['ee_front_ajax']) ? true : false
185
-        );
186
-        define(
187
-                'EE_ADMIN_AJAX',
188
-                isset($_REQUEST['ee_admin_ajax']) || isset($_REQUEST['data']['ee_admin_ajax']) ? true : false
189
-        );
190
-        //just a handy constant occasionally needed for finding values representing infinity in the DB
191
-        //you're better to use this than its straight value (currently -1) in case you ever
192
-        //want to change its default value! or find when -1 means infinity
193
-        define('EE_INF_IN_DB', -1);
194
-        define('EE_INF', INF > (float)PHP_INT_MAX ? INF : PHP_INT_MAX);
195
-        define('EE_DEBUG', false);
196
-        // for older WP versions
197
-        if ( ! defined('MONTH_IN_SECONDS')) {
198
-            define('MONTH_IN_SECONDS', DAY_IN_SECONDS * 30);
199
-        }
200
-        /**
201
-         *    espresso_plugin_activation
202
-         *    adds a wp-option to indicate that EE has been activated via the WP admin plugins page
203
-         */
204
-        function espresso_plugin_activation()
205
-        {
206
-            update_option('ee_espresso_activation', true);
207
-        }
107
+		// define versions
108
+		define('EVENT_ESPRESSO_VERSION', espresso_version());
109
+		define('EE_MIN_WP_VER_REQUIRED', '4.1');
110
+		define('EE_MIN_WP_VER_RECOMMENDED', '4.4.2');
111
+		define('EE_MIN_PHP_VER_RECOMMENDED', '5.4.44');
112
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
113
+		//used to be DIRECTORY_SEPARATOR, but that caused issues on windows
114
+		if ( ! defined('DS')) {
115
+			define('DS', '/');
116
+		}
117
+		if ( ! defined('PS')) {
118
+			define('PS', PATH_SEPARATOR);
119
+		}
120
+		if ( ! defined('SP')) {
121
+			define('SP', ' ');
122
+		}
123
+		if ( ! defined('EENL')) {
124
+			define('EENL', "\n");
125
+		}
126
+		define('EE_SUPPORT_EMAIL', '[email protected]');
127
+		// define the plugin directory and URL
128
+		define('EE_PLUGIN_BASENAME', plugin_basename(EVENT_ESPRESSO_MAIN_FILE));
129
+		define('EE_PLUGIN_DIR_PATH', plugin_dir_path(EVENT_ESPRESSO_MAIN_FILE));
130
+		define('EE_PLUGIN_DIR_URL', plugin_dir_url(EVENT_ESPRESSO_MAIN_FILE));
131
+		// main root folder paths
132
+		define('EE_ADMIN_PAGES', EE_PLUGIN_DIR_PATH . 'admin_pages' . DS);
133
+		define('EE_CORE', EE_PLUGIN_DIR_PATH . 'core' . DS);
134
+		define('EE_MODULES', EE_PLUGIN_DIR_PATH . 'modules' . DS);
135
+		define('EE_PUBLIC', EE_PLUGIN_DIR_PATH . 'public' . DS);
136
+		define('EE_SHORTCODES', EE_PLUGIN_DIR_PATH . 'shortcodes' . DS);
137
+		define('EE_WIDGETS', EE_PLUGIN_DIR_PATH . 'widgets' . DS);
138
+		define('EE_PAYMENT_METHODS', EE_PLUGIN_DIR_PATH . 'payment_methods' . DS);
139
+		define('EE_CAFF_PATH', EE_PLUGIN_DIR_PATH . 'caffeinated' . DS);
140
+		// core system paths
141
+		define('EE_ADMIN', EE_CORE . 'admin' . DS);
142
+		define('EE_CPTS', EE_CORE . 'CPTs' . DS);
143
+		define('EE_CLASSES', EE_CORE . 'db_classes' . DS);
144
+		define('EE_INTERFACES', EE_CORE . 'interfaces' . DS);
145
+		define('EE_BUSINESS', EE_CORE . 'business' . DS);
146
+		define('EE_MODELS', EE_CORE . 'db_models' . DS);
147
+		define('EE_HELPERS', EE_CORE . 'helpers' . DS);
148
+		define('EE_LIBRARIES', EE_CORE . 'libraries' . DS);
149
+		define('EE_TEMPLATES', EE_CORE . 'templates' . DS);
150
+		define('EE_THIRD_PARTY', EE_CORE . 'third_party_libs' . DS);
151
+		define('EE_GLOBAL_ASSETS', EE_TEMPLATES . 'global_assets' . DS);
152
+		define('EE_FORM_SECTIONS', EE_LIBRARIES . 'form_sections' . DS);
153
+		// gateways
154
+		define('EE_GATEWAYS', EE_MODULES . 'gateways' . DS);
155
+		define('EE_GATEWAYS_URL', EE_PLUGIN_DIR_URL . 'modules' . DS . 'gateways' . DS);
156
+		// asset URL paths
157
+		define('EE_TEMPLATES_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'templates' . DS);
158
+		define('EE_GLOBAL_ASSETS_URL', EE_TEMPLATES_URL . 'global_assets' . DS);
159
+		define('EE_IMAGES_URL', EE_GLOBAL_ASSETS_URL . 'images' . DS);
160
+		define('EE_THIRD_PARTY_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'third_party_libs' . DS);
161
+		define('EE_HELPERS_ASSETS', EE_PLUGIN_DIR_URL . 'core/helpers/assets/');
162
+		define('EE_LIBRARIES_URL', EE_PLUGIN_DIR_URL . 'core/libraries/');
163
+		// define upload paths
164
+		$uploads = wp_upload_dir();
165
+		// define the uploads directory and URL
166
+		define('EVENT_ESPRESSO_UPLOAD_DIR', $uploads['basedir'] . DS . 'espresso' . DS);
167
+		define('EVENT_ESPRESSO_UPLOAD_URL', $uploads['baseurl'] . DS . 'espresso' . DS);
168
+		// define the templates directory and URL
169
+		define('EVENT_ESPRESSO_TEMPLATE_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'templates' . DS);
170
+		define('EVENT_ESPRESSO_TEMPLATE_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'templates' . DS);
171
+		// define the gateway directory and URL
172
+		define('EVENT_ESPRESSO_GATEWAY_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'gateways' . DS);
173
+		define('EVENT_ESPRESSO_GATEWAY_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'gateways' . DS);
174
+		// languages folder/path
175
+		define('EE_LANGUAGES_SAFE_LOC', '..' . DS . 'uploads' . DS . 'espresso' . DS . 'languages' . DS);
176
+		define('EE_LANGUAGES_SAFE_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'languages' . DS);
177
+		//check for dompdf fonts in uploads
178
+		if (file_exists(EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS)) {
179
+			define('DOMPDF_FONT_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS);
180
+		}
181
+		//ajax constants
182
+		define(
183
+				'EE_FRONT_AJAX',
184
+				isset($_REQUEST['ee_front_ajax']) || isset($_REQUEST['data']['ee_front_ajax']) ? true : false
185
+		);
186
+		define(
187
+				'EE_ADMIN_AJAX',
188
+				isset($_REQUEST['ee_admin_ajax']) || isset($_REQUEST['data']['ee_admin_ajax']) ? true : false
189
+		);
190
+		//just a handy constant occasionally needed for finding values representing infinity in the DB
191
+		//you're better to use this than its straight value (currently -1) in case you ever
192
+		//want to change its default value! or find when -1 means infinity
193
+		define('EE_INF_IN_DB', -1);
194
+		define('EE_INF', INF > (float)PHP_INT_MAX ? INF : PHP_INT_MAX);
195
+		define('EE_DEBUG', false);
196
+		// for older WP versions
197
+		if ( ! defined('MONTH_IN_SECONDS')) {
198
+			define('MONTH_IN_SECONDS', DAY_IN_SECONDS * 30);
199
+		}
200
+		/**
201
+		 *    espresso_plugin_activation
202
+		 *    adds a wp-option to indicate that EE has been activated via the WP admin plugins page
203
+		 */
204
+		function espresso_plugin_activation()
205
+		{
206
+			update_option('ee_espresso_activation', true);
207
+		}
208 208
 
209
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
210
-        /**
211
-         *    espresso_load_error_handling
212
-         *    this function loads EE's class for handling exceptions and errors
213
-         */
214
-        function espresso_load_error_handling()
215
-        {
216
-            // load debugging tools
217
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
218
-                require_once(EE_HELPERS . 'EEH_Debug_Tools.helper.php');
219
-                EEH_Debug_Tools::instance();
220
-            }
221
-            // load error handling
222
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
223
-                require_once(EE_CORE . 'EE_Error.core.php');
224
-            } else {
225
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
226
-            }
227
-        }
209
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
210
+		/**
211
+		 *    espresso_load_error_handling
212
+		 *    this function loads EE's class for handling exceptions and errors
213
+		 */
214
+		function espresso_load_error_handling()
215
+		{
216
+			// load debugging tools
217
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
218
+				require_once(EE_HELPERS . 'EEH_Debug_Tools.helper.php');
219
+				EEH_Debug_Tools::instance();
220
+			}
221
+			// load error handling
222
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
223
+				require_once(EE_CORE . 'EE_Error.core.php');
224
+			} else {
225
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
226
+			}
227
+		}
228 228
 
229
-        /**
230
-         *    espresso_load_required
231
-         *    given a class name and path, this function will load that file or throw an exception
232
-         *
233
-         * @param    string $classname
234
-         * @param    string $full_path_to_file
235
-         * @throws    EE_Error
236
-         */
237
-        function espresso_load_required($classname, $full_path_to_file)
238
-        {
239
-            static $error_handling_loaded = false;
240
-            if ( ! $error_handling_loaded) {
241
-                espresso_load_error_handling();
242
-                $error_handling_loaded = true;
243
-            }
244
-            if (is_readable($full_path_to_file)) {
245
-                require_once($full_path_to_file);
246
-            } else {
247
-                throw new EE_Error (
248
-                        sprintf(
249
-                                esc_html__(
250
-                                        'The %s class file could not be located or is not readable due to file permissions.',
251
-                                        'event_espresso'
252
-                                ),
253
-                                $classname
254
-                        )
255
-                );
256
-            }
257
-        }
229
+		/**
230
+		 *    espresso_load_required
231
+		 *    given a class name and path, this function will load that file or throw an exception
232
+		 *
233
+		 * @param    string $classname
234
+		 * @param    string $full_path_to_file
235
+		 * @throws    EE_Error
236
+		 */
237
+		function espresso_load_required($classname, $full_path_to_file)
238
+		{
239
+			static $error_handling_loaded = false;
240
+			if ( ! $error_handling_loaded) {
241
+				espresso_load_error_handling();
242
+				$error_handling_loaded = true;
243
+			}
244
+			if (is_readable($full_path_to_file)) {
245
+				require_once($full_path_to_file);
246
+			} else {
247
+				throw new EE_Error (
248
+						sprintf(
249
+								esc_html__(
250
+										'The %s class file could not be located or is not readable due to file permissions.',
251
+										'event_espresso'
252
+								),
253
+								$classname
254
+						)
255
+				);
256
+			}
257
+		}
258 258
 
259
-        espresso_load_required('EEH_Base', EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php');
260
-        espresso_load_required('EEH_File', EE_CORE . 'helpers' . DS . 'EEH_File.helper.php');
261
-        espresso_load_required('EE_Bootstrap', EE_CORE . 'EE_Bootstrap.core.php');
262
-        new EE_Bootstrap();
263
-    }
259
+		espresso_load_required('EEH_Base', EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php');
260
+		espresso_load_required('EEH_File', EE_CORE . 'helpers' . DS . 'EEH_File.helper.php');
261
+		espresso_load_required('EE_Bootstrap', EE_CORE . 'EE_Bootstrap.core.php');
262
+		new EE_Bootstrap();
263
+	}
264 264
 }
265 265
 if ( ! function_exists('espresso_deactivate_plugin')) {
266
-    /**
267
-     *    deactivate_plugin
268
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
269
-     *
270
-     * @access public
271
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
272
-     * @return    void
273
-     */
274
-    function espresso_deactivate_plugin($plugin_basename = '')
275
-    {
276
-        if ( ! function_exists('deactivate_plugins')) {
277
-            require_once(ABSPATH . 'wp-admin/includes/plugin.php');
278
-        }
279
-        unset($_GET['activate'], $_REQUEST['activate']);
280
-        deactivate_plugins($plugin_basename);
281
-    }
266
+	/**
267
+	 *    deactivate_plugin
268
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
269
+	 *
270
+	 * @access public
271
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
272
+	 * @return    void
273
+	 */
274
+	function espresso_deactivate_plugin($plugin_basename = '')
275
+	{
276
+		if ( ! function_exists('deactivate_plugins')) {
277
+			require_once(ABSPATH . 'wp-admin/includes/plugin.php');
278
+		}
279
+		unset($_GET['activate'], $_REQUEST['activate']);
280
+		deactivate_plugins($plugin_basename);
281
+	}
282 282
 }
283 283
\ No newline at end of file
Please login to merge, or discard this patch.