Completed
Pull Request — master (#947)
by Darren
08:48
created
admin/extend/registration_form/Extend_Registration_Form_Admin_Page.core.php 1 patch
Indentation   +1303 added lines, -1303 removed lines patch added patch discarded remove patch
@@ -14,1307 +14,1307 @@
 block discarded – undo
14 14
 class Extend_Registration_Form_Admin_Page extends Registration_Form_Admin_Page
15 15
 {
16 16
 
17
-    /**
18
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
19
-     */
20
-    public function __construct($routing = true)
21
-    {
22
-        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form' . DS);
23
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets' . DS);
24
-        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
25
-        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates' . DS);
26
-        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
27
-        parent::__construct($routing);
28
-    }
29
-
30
-
31
-    /**
32
-     * @return void
33
-     */
34
-    protected function _extend_page_config()
35
-    {
36
-        $this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
37
-        $qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
38
-            ? $this->_req_data['QST_ID'] : 0;
39
-        $qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
40
-            ? $this->_req_data['QSG_ID'] : 0;
41
-
42
-        $new_page_routes = array(
43
-            'question_groups'    => array(
44
-                'func'       => '_question_groups_overview_list_table',
45
-                'capability' => 'ee_read_question_groups',
46
-            ),
47
-            'add_question'       => array(
48
-                'func'       => '_edit_question',
49
-                'capability' => 'ee_edit_questions',
50
-            ),
51
-            'insert_question'    => array(
52
-                'func'       => '_insert_or_update_question',
53
-                'args'       => array('new_question' => true),
54
-                'capability' => 'ee_edit_questions',
55
-                'noheader'   => true,
56
-            ),
57
-            'duplicate_question' => array(
58
-                'func'       => '_duplicate_question',
59
-                'capability' => 'ee_edit_questions',
60
-                'noheader'   => true,
61
-            ),
62
-            'trash_question'     => array(
63
-                'func'       => '_trash_question',
64
-                'capability' => 'ee_delete_question',
65
-                'obj_id'     => $qst_id,
66
-                'noheader'   => true,
67
-            ),
68
-
69
-            'restore_question' => array(
70
-                'func'       => '_trash_or_restore_questions',
71
-                'capability' => 'ee_delete_question',
72
-                'obj_id'     => $qst_id,
73
-                'args'       => array('trash' => false),
74
-                'noheader'   => true,
75
-            ),
76
-
77
-            'delete_question' => array(
78
-                'func'       => '_delete_question',
79
-                'capability' => 'ee_delete_question',
80
-                'obj_id'     => $qst_id,
81
-                'noheader'   => true,
82
-            ),
83
-
84
-            'trash_questions' => array(
85
-                'func'       => '_trash_or_restore_questions',
86
-                'capability' => 'ee_delete_questions',
87
-                'args'       => array('trash' => true),
88
-                'noheader'   => true,
89
-            ),
90
-
91
-            'restore_questions' => array(
92
-                'func'       => '_trash_or_restore_questions',
93
-                'capability' => 'ee_delete_questions',
94
-                'args'       => array('trash' => false),
95
-                'noheader'   => true,
96
-            ),
97
-
98
-            'delete_questions' => array(
99
-                'func'       => '_delete_questions',
100
-                'args'       => array(),
101
-                'capability' => 'ee_delete_questions',
102
-                'noheader'   => true,
103
-            ),
104
-
105
-            'add_question_group' => array(
106
-                'func'       => '_edit_question_group',
107
-                'capability' => 'ee_edit_question_groups',
108
-            ),
109
-
110
-            'edit_question_group' => array(
111
-                'func'       => '_edit_question_group',
112
-                'capability' => 'ee_edit_question_group',
113
-                'obj_id'     => $qsg_id,
114
-                'args'       => array('edit'),
115
-            ),
116
-
117
-            'delete_question_groups' => array(
118
-                'func'       => '_delete_question_groups',
119
-                'capability' => 'ee_delete_question_groups',
120
-                'noheader'   => true,
121
-            ),
122
-
123
-            'delete_question_group' => array(
124
-                'func'       => '_delete_question_groups',
125
-                'capability' => 'ee_delete_question_group',
126
-                'obj_id'     => $qsg_id,
127
-                'noheader'   => true,
128
-            ),
129
-
130
-            'trash_question_group' => array(
131
-                'func'       => '_trash_or_restore_question_groups',
132
-                'args'       => array('trash' => true),
133
-                'capability' => 'ee_delete_question_group',
134
-                'obj_id'     => $qsg_id,
135
-                'noheader'   => true,
136
-            ),
137
-
138
-            'restore_question_group' => array(
139
-                'func'       => '_trash_or_restore_question_groups',
140
-                'args'       => array('trash' => false),
141
-                'capability' => 'ee_delete_question_group',
142
-                'obj_id'     => $qsg_id,
143
-                'noheader'   => true,
144
-            ),
145
-
146
-            'insert_question_group' => array(
147
-                'func'       => '_insert_or_update_question_group',
148
-                'args'       => array('new_question_group' => true),
149
-                'capability' => 'ee_edit_question_groups',
150
-                'noheader'   => true,
151
-            ),
152
-
153
-            'update_question_group' => array(
154
-                'func'       => '_insert_or_update_question_group',
155
-                'args'       => array('new_question_group' => false),
156
-                'capability' => 'ee_edit_question_group',
157
-                'obj_id'     => $qsg_id,
158
-                'noheader'   => true,
159
-            ),
160
-
161
-            'trash_question_groups' => array(
162
-                'func'       => '_trash_or_restore_question_groups',
163
-                'args'       => array('trash' => true),
164
-                'capability' => 'ee_delete_question_groups',
165
-                'noheader'   => array('trash' => false),
166
-            ),
167
-
168
-            'restore_question_groups' => array(
169
-                'func'       => '_trash_or_restore_question_groups',
170
-                'args'       => array('trash' => false),
171
-                'capability' => 'ee_delete_question_groups',
172
-                'noheader'   => true,
173
-            ),
174
-
175
-
176
-            'espresso_update_question_group_order' => array(
177
-                'func'       => 'update_question_group_order',
178
-                'capability' => 'ee_edit_question_groups',
179
-                'noheader'   => true,
180
-            ),
181
-
182
-            'view_reg_form_settings' => array(
183
-                'func'       => '_reg_form_settings',
184
-                'capability' => 'manage_options',
185
-            ),
186
-
187
-            'update_reg_form_settings' => array(
188
-                'func'       => '_update_reg_form_settings',
189
-                'capability' => 'manage_options',
190
-                'noheader'   => true,
191
-            ),
192
-        );
193
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
194
-
195
-        $new_page_config = array(
196
-
197
-            'question_groups' => array(
198
-                'nav'           => array(
199
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
200
-                    'order' => 20,
201
-                ),
202
-                'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
203
-                'help_tabs'     => array(
204
-                    'registration_form_question_groups_help_tab'                           => array(
205
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
206
-                        'filename' => 'registration_form_question_groups',
207
-                    ),
208
-                    'registration_form_question_groups_table_column_headings_help_tab'     => array(
209
-                        'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
210
-                        'filename' => 'registration_form_question_groups_table_column_headings',
211
-                    ),
212
-                    'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
213
-                        'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
214
-                        'filename' => 'registration_form_question_groups_views_bulk_actions_search',
215
-                    ),
216
-                ),
217
-                'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
218
-                'metaboxes'     => $this->_default_espresso_metaboxes,
219
-                'require_nonce' => false,
220
-                'qtips'         => array(
221
-                    'EE_Registration_Form_Tips',
222
-                ),
223
-            ),
224
-
225
-            'add_question' => array(
226
-                'nav'           => array(
227
-                    'label'      => esc_html__('Add Question', 'event_espresso'),
228
-                    'order'      => 5,
229
-                    'persistent' => false,
230
-                ),
231
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
232
-                'help_tabs'     => array(
233
-                    'registration_form_add_question_help_tab' => array(
234
-                        'title'    => esc_html__('Add Question', 'event_espresso'),
235
-                        'filename' => 'registration_form_add_question',
236
-                    ),
237
-                ),
238
-                'help_tour'     => array('Registration_Form_Add_Question_Help_Tour'),
239
-                'require_nonce' => false,
240
-            ),
241
-
242
-            'add_question_group' => array(
243
-                'nav'           => array(
244
-                    'label'      => esc_html__('Add Question Group', 'event_espresso'),
245
-                    'order'      => 5,
246
-                    'persistent' => false,
247
-                ),
248
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
249
-                'help_tabs'     => array(
250
-                    'registration_form_add_question_group_help_tab' => array(
251
-                        'title'    => esc_html__('Add Question Group', 'event_espresso'),
252
-                        'filename' => 'registration_form_add_question_group',
253
-                    ),
254
-                ),
255
-                'help_tour'     => array('Registration_Form_Add_Question_Group_Help_Tour'),
256
-                'require_nonce' => false,
257
-            ),
258
-
259
-            'edit_question_group' => array(
260
-                'nav'           => array(
261
-                    'label'      => esc_html__('Edit Question Group', 'event_espresso'),
262
-                    'order'      => 5,
263
-                    'persistent' => false,
264
-                    'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
265
-                        array('question_group_id' => $this->_req_data['question_group_id']),
266
-                        $this->_current_page_view_url
267
-                    ) : $this->_admin_base_url,
268
-                ),
269
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
270
-                'help_tabs'     => array(
271
-                    'registration_form_edit_question_group_help_tab' => array(
272
-                        'title'    => esc_html__('Edit Question Group', 'event_espresso'),
273
-                        'filename' => 'registration_form_edit_question_group',
274
-                    ),
275
-                ),
276
-                'help_tour'     => array('Registration_Form_Edit_Question_Group_Help_Tour'),
277
-                'require_nonce' => false,
278
-            ),
279
-
280
-            'view_reg_form_settings' => array(
281
-                'nav'           => array(
282
-                    'label' => esc_html__('Reg Form Settings', 'event_espresso'),
283
-                    'order' => 40,
284
-                ),
285
-                'labels'        => array(
286
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
287
-                ),
288
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
289
-                'help_tabs'     => array(
290
-                    'registration_form_reg_form_settings_help_tab' => array(
291
-                        'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
292
-                        'filename' => 'registration_form_reg_form_settings',
293
-                    ),
294
-                ),
295
-                'help_tour'     => array('Registration_Form_Settings_Help_Tour'),
296
-                'require_nonce' => false,
297
-            ),
298
-
299
-        );
300
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
301
-
302
-        // change the list table we're going to use so it's the NEW list table!
303
-        $this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
304
-
305
-
306
-        // additional labels
307
-        $new_labels = array(
308
-            'add_question'          => esc_html__('Add New Question', 'event_espresso'),
309
-            'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
310
-            'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
311
-            'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
312
-            'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
313
-        );
314
-        $this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
315
-    }
316
-
317
-
318
-    /**
319
-     * @return void
320
-     */
321
-    protected function _ajax_hooks()
322
-    {
323
-        add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
324
-    }
325
-
326
-
327
-    /**
328
-     * @return void
329
-     */
330
-    public function load_scripts_styles_question_groups()
331
-    {
332
-        wp_enqueue_script('espresso_ajax_table_sorting');
333
-    }
334
-
335
-
336
-    /**
337
-     * @return void
338
-     */
339
-    public function load_scripts_styles_add_question_group()
340
-    {
341
-        $this->load_scripts_styles_forms();
342
-        $this->load_sortable_question_script();
343
-    }
344
-
345
-
346
-    /**
347
-     * @return void
348
-     */
349
-    public function load_scripts_styles_edit_question_group()
350
-    {
351
-        $this->load_scripts_styles_forms();
352
-        $this->load_sortable_question_script();
353
-    }
354
-
355
-
356
-    /**
357
-     * registers and enqueues script for questions
358
-     *
359
-     * @return void
360
-     */
361
-    public function load_sortable_question_script()
362
-    {
363
-        wp_register_script(
364
-            'ee-question-sortable',
365
-            REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
366
-            array('jquery-ui-sortable'),
367
-            EVENT_ESPRESSO_VERSION,
368
-            true
369
-        );
370
-        wp_enqueue_script('ee-question-sortable');
371
-    }
372
-
373
-
374
-    /**
375
-     * @return void
376
-     */
377
-    protected function _set_list_table_views_default()
378
-    {
379
-        $this->_views = array(
380
-            'all' => array(
381
-                'slug'        => 'all',
382
-                'label'       => esc_html__('View All Questions', 'event_espresso'),
383
-                'count'       => 0,
384
-                'bulk_action' => array(
385
-                    'trash_questions' => esc_html__('Trash', 'event_espresso'),
386
-                ),
387
-            ),
388
-        );
389
-
390
-        if (EE_Registry::instance()->CAP->current_user_can(
391
-            'ee_delete_questions',
392
-            'espresso_registration_form_trash_questions'
393
-        )
394
-        ) {
395
-            $this->_views['trash'] = array(
396
-                'slug'        => 'trash',
397
-                'label'       => esc_html__('Trash', 'event_espresso'),
398
-                'count'       => 0,
399
-                'bulk_action' => array(
400
-                    'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
401
-                    'restore_questions' => esc_html__('Restore', 'event_espresso'),
402
-                ),
403
-            );
404
-        }
405
-    }
406
-
407
-
408
-    /**
409
-     * @return void
410
-     */
411
-    protected function _set_list_table_views_question_groups()
412
-    {
413
-        $this->_views = array(
414
-            'all' => array(
415
-                'slug'        => 'all',
416
-                'label'       => esc_html__('All', 'event_espresso'),
417
-                'count'       => 0,
418
-                'bulk_action' => array(
419
-                    'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
420
-                ),
421
-            ),
422
-        );
423
-
424
-        if (EE_Registry::instance()->CAP->current_user_can(
425
-            'ee_delete_question_groups',
426
-            'espresso_registration_form_trash_question_groups'
427
-        )
428
-        ) {
429
-            $this->_views['trash'] = array(
430
-                'slug'        => 'trash',
431
-                'label'       => esc_html__('Trash', 'event_espresso'),
432
-                'count'       => 0,
433
-                'bulk_action' => array(
434
-                    'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
435
-                    'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
436
-                ),
437
-            );
438
-        }
439
-    }
440
-
441
-
442
-    /**
443
-     * @return void
444
-     * @throws EE_Error
445
-     * @throws InvalidArgumentException
446
-     * @throws InvalidDataTypeException
447
-     * @throws InvalidInterfaceException
448
-     */
449
-    protected function _questions_overview_list_table()
450
-    {
451
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
452
-            'add_question',
453
-            'add_question',
454
-            array(),
455
-            'add-new-h2'
456
-        );
457
-        parent::_questions_overview_list_table();
458
-    }
459
-
460
-
461
-    /**
462
-     * @return void
463
-     * @throws DomainException
464
-     * @throws EE_Error
465
-     * @throws InvalidArgumentException
466
-     * @throws InvalidDataTypeException
467
-     * @throws InvalidInterfaceException
468
-     */
469
-    protected function _question_groups_overview_list_table()
470
-    {
471
-        $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
472
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
473
-            'add_question_group',
474
-            'add_question_group',
475
-            array(),
476
-            'add-new-h2'
477
-        );
478
-        $this->display_admin_list_table_page_with_sidebar();
479
-    }
480
-
481
-
482
-    /**
483
-     * @return void
484
-     * @throws EE_Error
485
-     * @throws InvalidArgumentException
486
-     * @throws InvalidDataTypeException
487
-     * @throws InvalidInterfaceException
488
-     */
489
-    protected function _delete_question()
490
-    {
491
-        $success = $this->_delete_items($this->_question_model);
492
-        $this->_redirect_after_action(
493
-            $success,
494
-            $this->_question_model->item_name($success),
495
-            'deleted',
496
-            array('action' => 'default', 'status' => 'all')
497
-        );
498
-    }
499
-
500
-
501
-    /**
502
-     * @return void
503
-     * @throws EE_Error
504
-     * @throws InvalidArgumentException
505
-     * @throws InvalidDataTypeException
506
-     * @throws InvalidInterfaceException
507
-     */
508
-    protected function _delete_questions()
509
-    {
510
-        $success = $this->_delete_items($this->_question_model);
511
-        $this->_redirect_after_action(
512
-            $success,
513
-            $this->_question_model->item_name($success),
514
-            'deleted permanently',
515
-            array('action' => 'default', 'status' => 'trash')
516
-        );
517
-    }
518
-
519
-
520
-    /**
521
-     * Performs the deletion of a single or multiple questions or question groups.
522
-     *
523
-     * @param EEM_Soft_Delete_Base $model
524
-     * @return int number of items deleted permanently
525
-     * @throws EE_Error
526
-     * @throws InvalidArgumentException
527
-     * @throws InvalidDataTypeException
528
-     * @throws InvalidInterfaceException
529
-     */
530
-    private function _delete_items(EEM_Soft_Delete_Base $model)
531
-    {
532
-        $success = 0;
533
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
534
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
535
-            // if array has more than one element than success message should be plural
536
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
537
-            // cycle thru bulk action checkboxes
538
-            while (list($ID, $value) = each($this->_req_data['checkbox'])) {
539
-                if (! $this->_delete_item($ID, $model)) {
540
-                    $success = 0;
541
-                }
542
-            }
543
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
544
-            $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
545
-        } elseif (! empty($this->_req_data['QST_ID'])) {
546
-            $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
547
-        } else {
548
-            EE_Error::add_error(
549
-                sprintf(
550
-                    esc_html__(
551
-                        "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.",
552
-                        "event_espresso"
553
-                    )
554
-                ),
555
-                __FILE__,
556
-                __FUNCTION__,
557
-                __LINE__
558
-            );
559
-        }
560
-        return $success;
561
-    }
562
-
563
-
564
-    /**
565
-     * Deletes the specified question (and its associated question options) or question group
566
-     *
567
-     * @param int                  $id
568
-     * @param EEM_Soft_Delete_Base $model
569
-     * @return boolean
570
-     * @throws EE_Error
571
-     * @throws InvalidArgumentException
572
-     * @throws InvalidDataTypeException
573
-     * @throws InvalidInterfaceException
574
-     */
575
-    protected function _delete_item($id, $model)
576
-    {
577
-        if ($model instanceof EEM_Question) {
578
-            EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
579
-        }
580
-        return $model->delete_permanently_by_ID(absint($id));
581
-    }
582
-
583
-
584
-    /******************************    QUESTION GROUPS    ******************************/
585
-
586
-
587
-    /**
588
-     * @param string $type
589
-     * @return void
590
-     * @throws DomainException
591
-     * @throws EE_Error
592
-     * @throws InvalidArgumentException
593
-     * @throws InvalidDataTypeException
594
-     * @throws InvalidInterfaceException
595
-     */
596
-    protected function _edit_question_group($type = 'add')
597
-    {
598
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
599
-        $ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
600
-            ? absint($this->_req_data['QSG_ID'])
601
-            : false;
602
-
603
-        switch ($this->_req_action) {
604
-            case 'add_question_group':
605
-                $this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
606
-                break;
607
-            case 'edit_question_group':
608
-                $this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
609
-                break;
610
-            default:
611
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
612
-        }
613
-        // add ID to title if editing
614
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
615
-        if ($ID) {
616
-            /** @var EE_Question_Group $questionGroup */
617
-            $questionGroup = $this->_question_group_model->get_one_by_ID($ID);
618
-            $additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
619
-            $this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
620
-        } else {
621
-            /** @var EE_Question_Group $questionGroup */
622
-            $questionGroup = EEM_Question_Group::instance()->create_default_object();
623
-            $questionGroup->set_order_to_latest();
624
-            $this->_set_add_edit_form_tags('insert_question_group');
625
-        }
626
-        $this->_template_args['values'] = $this->_yes_no_values;
627
-        $this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
628
-        $this->_template_args['QSG_ID'] = $ID ? $ID : true;
629
-        $this->_template_args['question_group'] = $questionGroup;
630
-
631
-        $redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
632
-        $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
633
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
634
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
635
-            $this->_template_args,
636
-            true
637
-        );
638
-
639
-        // the details template wrapper
640
-        $this->display_admin_page_with_sidebar();
641
-    }
642
-
643
-
644
-    /**
645
-     * @return void
646
-     * @throws EE_Error
647
-     * @throws InvalidArgumentException
648
-     * @throws InvalidDataTypeException
649
-     * @throws InvalidInterfaceException
650
-     */
651
-    protected function _delete_question_groups()
652
-    {
653
-        $success = $this->_delete_items($this->_question_group_model);
654
-        $this->_redirect_after_action(
655
-            $success,
656
-            $this->_question_group_model->item_name($success),
657
-            'deleted permanently',
658
-            array('action' => 'question_groups', 'status' => 'trash')
659
-        );
660
-    }
661
-
662
-
663
-    /**
664
-     * @param bool $new_question_group
665
-     * @throws EE_Error
666
-     * @throws InvalidArgumentException
667
-     * @throws InvalidDataTypeException
668
-     * @throws InvalidInterfaceException
669
-     */
670
-    protected function _insert_or_update_question_group($new_question_group = true)
671
-    {
672
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
673
-        $set_column_values = $this->_set_column_values_for($this->_question_group_model);
674
-        if ($new_question_group) {
675
-            // make sure identifier is unique
676
-            $identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
677
-            $identifier_exists = ! empty($identifier_value)
678
-                ? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
679
-                : false;
680
-            if ($identifier_exists) {
681
-                $set_column_values['QSG_identifier'] .= uniqid('id', true);
682
-            }
683
-            $QSG_ID = $this->_question_group_model->insert($set_column_values);
684
-            $success = $QSG_ID ? 1 : 0;
685
-        } else {
686
-            $QSG_ID = absint($this->_req_data['QSG_ID']);
687
-            unset($set_column_values['QSG_ID']);
688
-            $success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
689
-        }
690
-        $phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
691
-            EEM_Attendee::system_question_phone
692
-        );
693
-        // update the existing related questions
694
-        // BUT FIRST...  delete the phone question from the Question_Group_Question
695
-        // if it is being added to this question group (therefore removed from the existing group)
696
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
697
-            // delete where QST ID = system phone question ID and Question Group ID is NOT this group
698
-            EEM_Question_Group_Question::instance()->delete(
699
-                array(
700
-                    array(
701
-                        'QST_ID' => $phone_question_id,
702
-                        'QSG_ID' => array('!=', $QSG_ID),
703
-                    ),
704
-                )
705
-            );
706
-        }
707
-        /** @type EE_Question_Group $question_group */
708
-        $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
709
-        $questions = $question_group->questions();
710
-        // make sure system phone question is added to list of questions for this group
711
-        if (! isset($questions[ $phone_question_id ])) {
712
-            $questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
713
-        }
714
-
715
-        foreach ($questions as $question_ID => $question) {
716
-            // first we always check for order.
717
-            if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
718
-                // update question order
719
-                $question_group->update_question_order(
720
-                    $question_ID,
721
-                    $this->_req_data['question_orders'][ $question_ID ]
722
-                );
723
-            }
724
-
725
-            // then we always check if adding or removing.
726
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
727
-                $question_group->add_question($question_ID);
728
-            } else {
729
-                // not found, remove it (but only if not a system question for the personal group
730
-                // with the exception of lname system question - we allow removal of it)
731
-                if (in_array(
732
-                    $question->system_ID(),
733
-                    EEM_Question::instance()->required_system_questions_in_system_question_group(
734
-                        $question_group->system_group()
735
-                    )
736
-                )) {
737
-                    continue;
738
-                } else {
739
-                    $question_group->remove_question($question_ID);
740
-                }
741
-            }
742
-        }
743
-        // save new related questions
744
-        if (isset($this->_req_data['questions'])) {
745
-            foreach ($this->_req_data['questions'] as $QST_ID) {
746
-                $question_group->add_question($QST_ID);
747
-                if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
748
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
749
-                }
750
-            }
751
-        }
752
-
753
-        if ($success !== false) {
754
-            $msg = $new_question_group
755
-                ? sprintf(
756
-                    esc_html__('The %s has been created', 'event_espresso'),
757
-                    $this->_question_group_model->item_name()
758
-                )
759
-                : sprintf(
760
-                    esc_html__(
761
-                        'The %s has been updated',
762
-                        'event_espresso'
763
-                    ),
764
-                    $this->_question_group_model->item_name()
765
-                );
766
-            EE_Error::add_success($msg);
767
-        }
768
-        $this->_redirect_after_action(
769
-            false,
770
-            '',
771
-            '',
772
-            array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
773
-            true
774
-        );
775
-    }
776
-
777
-
778
-    /**
779
-     * duplicates a question and all its question options and redirects to the new question.
780
-     *
781
-     * @return void
782
-     * @throws EE_Error
783
-     * @throws InvalidArgumentException
784
-     * @throws ReflectionException
785
-     * @throws InvalidDataTypeException
786
-     * @throws InvalidInterfaceException
787
-     */
788
-    public function _duplicate_question()
789
-    {
790
-        $question_ID = (int) $this->_req_data['QST_ID'];
791
-        $question = EEM_Question::instance()->get_one_by_ID($question_ID);
792
-        if ($question instanceof EE_Question) {
793
-            $new_question = $question->duplicate();
794
-            if ($new_question instanceof EE_Question) {
795
-                $this->_redirect_after_action(
796
-                    true,
797
-                    esc_html__('Question', 'event_espresso'),
798
-                    esc_html__('Duplicated', 'event_espresso'),
799
-                    array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
800
-                    true
801
-                );
802
-            } else {
803
-                global $wpdb;
804
-                EE_Error::add_error(
805
-                    sprintf(
806
-                        esc_html__(
807
-                            'Could not duplicate question with ID %1$d because: %2$s',
808
-                            'event_espresso'
809
-                        ),
810
-                        $question_ID,
811
-                        $wpdb->last_error
812
-                    ),
813
-                    __FILE__,
814
-                    __FUNCTION__,
815
-                    __LINE__
816
-                );
817
-                $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
818
-            }
819
-        } else {
820
-            EE_Error::add_error(
821
-                sprintf(
822
-                    esc_html__(
823
-                        'Could not duplicate question with ID %d because it didn\'t exist!',
824
-                        'event_espresso'
825
-                    ),
826
-                    $question_ID
827
-                ),
828
-                __FILE__,
829
-                __FUNCTION__,
830
-                __LINE__
831
-            );
832
-            $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
833
-        }
834
-    }
835
-
836
-
837
-    /**
838
-     * @param bool $trash
839
-     * @throws EE_Error
840
-     */
841
-    protected function _trash_or_restore_question_groups($trash = true)
842
-    {
843
-        $this->_trash_or_restore_items($this->_question_group_model, $trash);
844
-    }
845
-
846
-
847
-    /**
848
-     *_trash_question
849
-     *
850
-     * @return void
851
-     * @throws EE_Error
852
-     */
853
-    protected function _trash_question()
854
-    {
855
-        $success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
856
-        $query_args = array('action' => 'default', 'status' => 'all');
857
-        $this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
858
-    }
859
-
860
-
861
-    /**
862
-     * @param bool $trash
863
-     * @throws EE_Error
864
-     */
865
-    protected function _trash_or_restore_questions($trash = true)
866
-    {
867
-        $this->_trash_or_restore_items($this->_question_model, $trash);
868
-    }
869
-
870
-
871
-    /**
872
-     * Internally used to delete or restore items, using the request data. Meant to be
873
-     * flexible between question or question groups
874
-     *
875
-     * @param EEM_Soft_Delete_Base $model
876
-     * @param boolean              $trash whether to trash or restore
877
-     * @throws EE_Error
878
-     */
879
-    private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
880
-    {
881
-
882
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
883
-
884
-        $success = 1;
885
-        // Checkboxes
886
-        // echo "trash $trash";
887
-        // var_dump($this->_req_data['checkbox']);die;
888
-        if (isset($this->_req_data['checkbox'])) {
889
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
890
-                // if array has more than one element than success message should be plural
891
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
892
-                // cycle thru bulk action checkboxes
893
-                while (list($ID, $value) = each($this->_req_data['checkbox'])) {
894
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
895
-                        $success = 0;
896
-                    }
897
-                }
898
-            } else {
899
-                // grab single id and delete
900
-                $ID = absint($this->_req_data['checkbox']);
901
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
902
-                    $success = 0;
903
-                }
904
-            }
905
-        } else {
906
-            // delete via trash link
907
-            // grab single id and delete
908
-            $ID = absint($this->_req_data[ $model->primary_key_name() ]);
909
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
910
-                $success = 0;
911
-            }
912
-        }
913
-
914
-
915
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
916
-        // echo "action :$action";
917
-        // $action = 'questions' ? 'default' : $action;
918
-        if ($trash) {
919
-            $action_desc = 'trashed';
920
-            $status = 'trash';
921
-        } else {
922
-            $action_desc = 'restored';
923
-            $status = 'all';
924
-        }
925
-        $this->_redirect_after_action(
926
-            $success,
927
-            $model->item_name($success),
928
-            $action_desc,
929
-            array('action' => $action, 'status' => $status)
930
-        );
931
-    }
932
-
933
-
934
-    /**
935
-     * @param            $per_page
936
-     * @param int        $current_page
937
-     * @param bool|false $count
938
-     * @return EE_Soft_Delete_Base_Class[]|int
939
-     * @throws EE_Error
940
-     * @throws InvalidArgumentException
941
-     * @throws InvalidDataTypeException
942
-     * @throws InvalidInterfaceException
943
-     */
944
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
945
-    {
946
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
947
-
948
-        if ($count) {
949
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
950
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
951
-            $results = $this->_question_model->count_deleted($where);
952
-        } else {
953
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
954
-            $results = $this->_question_model->get_all_deleted($query_params);
955
-        }
956
-        return $results;
957
-    }
958
-
959
-
960
-    /**
961
-     * @param            $per_page
962
-     * @param int        $current_page
963
-     * @param bool|false $count
964
-     * @return EE_Soft_Delete_Base_Class[]|int
965
-     * @throws EE_Error
966
-     * @throws InvalidArgumentException
967
-     * @throws InvalidDataTypeException
968
-     * @throws InvalidInterfaceException
969
-     */
970
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
971
-    {
972
-        $questionGroupModel = EEM_Question_Group::instance();
973
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
974
-        if ($count) {
975
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
976
-            $results = $questionGroupModel->count($where);
977
-        } else {
978
-            $results = $questionGroupModel->get_all($query_params);
979
-        }
980
-        return $results;
981
-    }
982
-
983
-
984
-    /**
985
-     * @param      $per_page
986
-     * @param int  $current_page
987
-     * @param bool $count
988
-     * @return EE_Soft_Delete_Base_Class[]|int
989
-     * @throws EE_Error
990
-     * @throws InvalidArgumentException
991
-     * @throws InvalidDataTypeException
992
-     * @throws InvalidInterfaceException
993
-     */
994
-    public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
995
-    {
996
-        $questionGroupModel = EEM_Question_Group::instance();
997
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
998
-        if ($count) {
999
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
1000
-            $query_params['limit'] = null;
1001
-            $results = $questionGroupModel->count_deleted($where);
1002
-        } else {
1003
-            $results = $questionGroupModel->get_all_deleted($query_params);
1004
-        }
1005
-        return $results;
1006
-    }
1007
-
1008
-
1009
-    /**
1010
-     * method for performing updates to question order
1011
-     *
1012
-     * @return void results array
1013
-     * @throws EE_Error
1014
-     * @throws InvalidArgumentException
1015
-     * @throws InvalidDataTypeException
1016
-     * @throws InvalidInterfaceException
1017
-     */
1018
-    public function update_question_group_order()
1019
-    {
1020
-
1021
-        $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1022
-
1023
-        // grab our row IDs
1024
-        $row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1025
-            ? explode(',', rtrim($this->_req_data['row_ids'], ','))
1026
-            : array();
1027
-
1028
-        $perpage = ! empty($this->_req_data['perpage'])
1029
-            ? (int) $this->_req_data['perpage']
1030
-            : null;
1031
-        $curpage = ! empty($this->_req_data['curpage'])
1032
-            ? (int) $this->_req_data['curpage']
1033
-            : null;
1034
-
1035
-        if (! empty($row_ids)) {
1036
-            // figure out where we start the row_id count at for the current page.
1037
-            $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1038
-
1039
-            $row_count = count($row_ids);
1040
-            for ($i = 0; $i < $row_count; $i++) {
1041
-                // Update the questions when re-ordering
1042
-                $updated = EEM_Question_Group::instance()->update(
1043
-                    array('QSG_order' => $qsgcount),
1044
-                    array(array('QSG_ID' => $row_ids[ $i ]))
1045
-                );
1046
-                if ($updated === false) {
1047
-                    $success = false;
1048
-                }
1049
-                $qsgcount++;
1050
-            }
1051
-        } else {
1052
-            $success = false;
1053
-        }
1054
-
1055
-        $errors = ! $success
1056
-            ? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1057
-            : false;
1058
-
1059
-        echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1060
-        die();
1061
-    }
1062
-
1063
-
1064
-
1065
-    /***************************************       REGISTRATION SETTINGS       ***************************************/
1066
-
1067
-
1068
-    /**
1069
-     * @throws DomainException
1070
-     * @throws EE_Error
1071
-     * @throws InvalidArgumentException
1072
-     * @throws InvalidDataTypeException
1073
-     * @throws InvalidInterfaceException
1074
-     */
1075
-    protected function _reg_form_settings()
1076
-    {
1077
-        $this->_template_args['values'] = $this->_yes_no_values;
1078
-        add_action(
1079
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1080
-            array($this, 'email_validation_settings_form'),
1081
-            2
1082
-        );
1083
-        $this->_template_args = (array) apply_filters(
1084
-            'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1085
-            $this->_template_args
1086
-        );
1087
-        $this->_set_add_edit_form_tags('update_reg_form_settings');
1088
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
1089
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1090
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1091
-            $this->_template_args,
1092
-            true
1093
-        );
1094
-        $this->display_admin_page_with_sidebar();
1095
-    }
1096
-
1097
-
1098
-    /**
1099
-     * @return void
1100
-     * @throws EE_Error
1101
-     * @throws InvalidArgumentException
1102
-     * @throws ReflectionException
1103
-     * @throws InvalidDataTypeException
1104
-     * @throws InvalidInterfaceException
1105
-     */
1106
-    protected function _update_reg_form_settings()
1107
-    {
1108
-        EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1109
-            EE_Registry::instance()->CFG->registration
1110
-        );
1111
-        EE_Registry::instance()->CFG->registration = apply_filters(
1112
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1113
-            EE_Registry::instance()->CFG->registration
1114
-        );
1115
-        $success = $this->_update_espresso_configuration(
1116
-            esc_html__('Registration Form Options', 'event_espresso'),
1117
-            EE_Registry::instance()->CFG,
1118
-            __FILE__,
1119
-            __FUNCTION__,
1120
-            __LINE__
1121
-        );
1122
-        $this->_redirect_after_action(
1123
-            $success,
1124
-            esc_html__('Registration Form Options', 'event_espresso'),
1125
-            'updated',
1126
-            array('action' => 'view_reg_form_settings')
1127
-        );
1128
-    }
1129
-
1130
-
1131
-    /**
1132
-     * @return void
1133
-     * @throws EE_Error
1134
-     * @throws InvalidArgumentException
1135
-     * @throws InvalidDataTypeException
1136
-     * @throws InvalidInterfaceException
1137
-     */
1138
-    public function email_validation_settings_form()
1139
-    {
1140
-        echo $this->_email_validation_settings_form()->get_html();
1141
-    }
1142
-
1143
-
1144
-    /**
1145
-     * _email_validation_settings_form
1146
-     *
1147
-     * @access protected
1148
-     * @return EE_Form_Section_Proper
1149
-     * @throws \EE_Error
1150
-     */
1151
-    protected function _email_validation_settings_form()
1152
-    {
1153
-        return new EE_Form_Section_Proper(
1154
-            array(
1155
-                'name'            => 'email_validation_settings',
1156
-                'html_id'         => 'email_validation_settings',
1157
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1158
-                'subsections'     => apply_filters(
1159
-                    'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1160
-                    array(
1161
-                        'email_validation_hdr'   => new EE_Form_Section_HTML(
1162
-                            EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1163
-                        ),
1164
-                        'email_validation_level' => new EE_Select_Input(
1165
-                            array(
1166
-                                'basic'      => esc_html__('Basic', 'event_espresso'),
1167
-                                'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1168
-                                'i18n'       => esc_html__('International', 'event_espresso'),
1169
-                                'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1170
-                            ),
1171
-                            array(
1172
-                                'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1173
-                                                     . EEH_Template::get_help_tab_link('email_validation_info'),
1174
-                                'html_help_text'  => esc_html__(
1175
-                                    '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.',
1176
-                                    'event_espresso'
1177
-                                ),
1178
-                                'default'         => isset(
1179
-                                    EE_Registry::instance()->CFG->registration->email_validation_level
1180
-                                )
1181
-                                    ? EE_Registry::instance()->CFG->registration->email_validation_level
1182
-                                    : 'wp_default',
1183
-                                'required'        => false,
1184
-                            )
1185
-                        ),
1186
-                    )
1187
-                ),
1188
-            )
1189
-        );
1190
-    }
1191
-
1192
-
1193
-    /**
1194
-     * @param EE_Registration_Config $EE_Registration_Config
1195
-     * @return EE_Registration_Config
1196
-     * @throws EE_Error
1197
-     * @throws InvalidArgumentException
1198
-     * @throws ReflectionException
1199
-     * @throws InvalidDataTypeException
1200
-     * @throws InvalidInterfaceException
1201
-     */
1202
-    public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1203
-    {
1204
-        $prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1205
-        try {
1206
-            $email_validation_settings_form = $this->_email_validation_settings_form();
1207
-            // if not displaying a form, then check for form submission
1208
-            if ($email_validation_settings_form->was_submitted()) {
1209
-                // capture form data
1210
-                $email_validation_settings_form->receive_form_submission();
1211
-                // validate form data
1212
-                if ($email_validation_settings_form->is_valid()) {
1213
-                    // grab validated data from form
1214
-                    $valid_data = $email_validation_settings_form->valid_data();
1215
-                    if (isset($valid_data['email_validation_level'])) {
1216
-                        $email_validation_level = $valid_data['email_validation_level'];
1217
-                        // now if they want to use international email addresses
1218
-                        if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1219
-                            // in case we need to reset their email validation level,
1220
-                            // make sure that the previous value wasn't already set to one of the i18n options.
1221
-                            if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1222
-                                // if so, then reset it back to "basic" since that is the only other option that,
1223
-                                // despite offering poor validation, supports i18n email addresses
1224
-                                $prev_email_validation_level = 'basic';
1225
-                            }
1226
-                            // confirm our i18n email validation will work on the server
1227
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1228
-                                // or reset email validation level to previous value
1229
-                                $email_validation_level = $prev_email_validation_level;
1230
-                            }
1231
-                        }
1232
-                        $EE_Registration_Config->email_validation_level = $email_validation_level;
1233
-                    } else {
1234
-                        EE_Error::add_error(
1235
-                            esc_html__(
1236
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1237
-                                'event_espresso'
1238
-                            ),
1239
-                            __FILE__,
1240
-                            __FUNCTION__,
1241
-                            __LINE__
1242
-                        );
1243
-                    }
1244
-                } else {
1245
-                    if ($email_validation_settings_form->submission_error_message() !== '') {
1246
-                        EE_Error::add_error(
1247
-                            $email_validation_settings_form->submission_error_message(),
1248
-                            __FILE__,
1249
-                            __FUNCTION__,
1250
-                            __LINE__
1251
-                        );
1252
-                    }
1253
-                }
1254
-            }
1255
-        } catch (EE_Error $e) {
1256
-            $e->get_error();
1257
-        }
1258
-        return $EE_Registration_Config;
1259
-    }
1260
-
1261
-
1262
-    /**
1263
-     * confirms that the server's PHP version has the PCRE module enabled,
1264
-     * and that the PCRE version works with our i18n email validation
1265
-     *
1266
-     * @param EE_Registration_Config $EE_Registration_Config
1267
-     * @param string                 $email_validation_level
1268
-     * @return bool
1269
-     */
1270
-    private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1271
-    {
1272
-        // first check that PCRE is enabled
1273
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1274
-            EE_Error::add_error(
1275
-                sprintf(
1276
-                    esc_html__(
1277
-                        '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.',
1278
-                        'event_espresso'
1279
-                    ),
1280
-                    '<br />'
1281
-                ),
1282
-                __FILE__,
1283
-                __FUNCTION__,
1284
-                __LINE__
1285
-            );
1286
-            return false;
1287
-        } else {
1288
-            // PCRE support is enabled, but let's still
1289
-            // perform a test to see if the server will support it.
1290
-            // but first, save the updated validation level to the config,
1291
-            // so that the validation strategy picks it up.
1292
-            // this will get bumped back down if it doesn't work
1293
-            $EE_Registration_Config->email_validation_level = $email_validation_level;
1294
-            try {
1295
-                $email_validator = new EE_Email_Validation_Strategy();
1296
-                $i18n_email_address = apply_filters(
1297
-                    'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1298
-                    'jägerjü[email protected]'
1299
-                );
1300
-                $email_validator->validate($i18n_email_address);
1301
-            } catch (Exception $e) {
1302
-                EE_Error::add_error(
1303
-                    sprintf(
1304
-                        esc_html__(
1305
-                            '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',
1306
-                            'event_espresso'
1307
-                        ),
1308
-                        '<br />',
1309
-                        '<a href="http://php.net/manual/en/pcre.installation.php" target="_blank">http://php.net/manual/en/pcre.installation.php</a>'
1310
-                    ),
1311
-                    __FILE__,
1312
-                    __FUNCTION__,
1313
-                    __LINE__
1314
-                );
1315
-                return false;
1316
-            }
1317
-        }
1318
-        return true;
1319
-    }
17
+	/**
18
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
19
+	 */
20
+	public function __construct($routing = true)
21
+	{
22
+		define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form' . DS);
23
+		define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets' . DS);
24
+		define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
25
+		define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates' . DS);
26
+		define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
27
+		parent::__construct($routing);
28
+	}
29
+
30
+
31
+	/**
32
+	 * @return void
33
+	 */
34
+	protected function _extend_page_config()
35
+	{
36
+		$this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
37
+		$qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
38
+			? $this->_req_data['QST_ID'] : 0;
39
+		$qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
40
+			? $this->_req_data['QSG_ID'] : 0;
41
+
42
+		$new_page_routes = array(
43
+			'question_groups'    => array(
44
+				'func'       => '_question_groups_overview_list_table',
45
+				'capability' => 'ee_read_question_groups',
46
+			),
47
+			'add_question'       => array(
48
+				'func'       => '_edit_question',
49
+				'capability' => 'ee_edit_questions',
50
+			),
51
+			'insert_question'    => array(
52
+				'func'       => '_insert_or_update_question',
53
+				'args'       => array('new_question' => true),
54
+				'capability' => 'ee_edit_questions',
55
+				'noheader'   => true,
56
+			),
57
+			'duplicate_question' => array(
58
+				'func'       => '_duplicate_question',
59
+				'capability' => 'ee_edit_questions',
60
+				'noheader'   => true,
61
+			),
62
+			'trash_question'     => array(
63
+				'func'       => '_trash_question',
64
+				'capability' => 'ee_delete_question',
65
+				'obj_id'     => $qst_id,
66
+				'noheader'   => true,
67
+			),
68
+
69
+			'restore_question' => array(
70
+				'func'       => '_trash_or_restore_questions',
71
+				'capability' => 'ee_delete_question',
72
+				'obj_id'     => $qst_id,
73
+				'args'       => array('trash' => false),
74
+				'noheader'   => true,
75
+			),
76
+
77
+			'delete_question' => array(
78
+				'func'       => '_delete_question',
79
+				'capability' => 'ee_delete_question',
80
+				'obj_id'     => $qst_id,
81
+				'noheader'   => true,
82
+			),
83
+
84
+			'trash_questions' => array(
85
+				'func'       => '_trash_or_restore_questions',
86
+				'capability' => 'ee_delete_questions',
87
+				'args'       => array('trash' => true),
88
+				'noheader'   => true,
89
+			),
90
+
91
+			'restore_questions' => array(
92
+				'func'       => '_trash_or_restore_questions',
93
+				'capability' => 'ee_delete_questions',
94
+				'args'       => array('trash' => false),
95
+				'noheader'   => true,
96
+			),
97
+
98
+			'delete_questions' => array(
99
+				'func'       => '_delete_questions',
100
+				'args'       => array(),
101
+				'capability' => 'ee_delete_questions',
102
+				'noheader'   => true,
103
+			),
104
+
105
+			'add_question_group' => array(
106
+				'func'       => '_edit_question_group',
107
+				'capability' => 'ee_edit_question_groups',
108
+			),
109
+
110
+			'edit_question_group' => array(
111
+				'func'       => '_edit_question_group',
112
+				'capability' => 'ee_edit_question_group',
113
+				'obj_id'     => $qsg_id,
114
+				'args'       => array('edit'),
115
+			),
116
+
117
+			'delete_question_groups' => array(
118
+				'func'       => '_delete_question_groups',
119
+				'capability' => 'ee_delete_question_groups',
120
+				'noheader'   => true,
121
+			),
122
+
123
+			'delete_question_group' => array(
124
+				'func'       => '_delete_question_groups',
125
+				'capability' => 'ee_delete_question_group',
126
+				'obj_id'     => $qsg_id,
127
+				'noheader'   => true,
128
+			),
129
+
130
+			'trash_question_group' => array(
131
+				'func'       => '_trash_or_restore_question_groups',
132
+				'args'       => array('trash' => true),
133
+				'capability' => 'ee_delete_question_group',
134
+				'obj_id'     => $qsg_id,
135
+				'noheader'   => true,
136
+			),
137
+
138
+			'restore_question_group' => array(
139
+				'func'       => '_trash_or_restore_question_groups',
140
+				'args'       => array('trash' => false),
141
+				'capability' => 'ee_delete_question_group',
142
+				'obj_id'     => $qsg_id,
143
+				'noheader'   => true,
144
+			),
145
+
146
+			'insert_question_group' => array(
147
+				'func'       => '_insert_or_update_question_group',
148
+				'args'       => array('new_question_group' => true),
149
+				'capability' => 'ee_edit_question_groups',
150
+				'noheader'   => true,
151
+			),
152
+
153
+			'update_question_group' => array(
154
+				'func'       => '_insert_or_update_question_group',
155
+				'args'       => array('new_question_group' => false),
156
+				'capability' => 'ee_edit_question_group',
157
+				'obj_id'     => $qsg_id,
158
+				'noheader'   => true,
159
+			),
160
+
161
+			'trash_question_groups' => array(
162
+				'func'       => '_trash_or_restore_question_groups',
163
+				'args'       => array('trash' => true),
164
+				'capability' => 'ee_delete_question_groups',
165
+				'noheader'   => array('trash' => false),
166
+			),
167
+
168
+			'restore_question_groups' => array(
169
+				'func'       => '_trash_or_restore_question_groups',
170
+				'args'       => array('trash' => false),
171
+				'capability' => 'ee_delete_question_groups',
172
+				'noheader'   => true,
173
+			),
174
+
175
+
176
+			'espresso_update_question_group_order' => array(
177
+				'func'       => 'update_question_group_order',
178
+				'capability' => 'ee_edit_question_groups',
179
+				'noheader'   => true,
180
+			),
181
+
182
+			'view_reg_form_settings' => array(
183
+				'func'       => '_reg_form_settings',
184
+				'capability' => 'manage_options',
185
+			),
186
+
187
+			'update_reg_form_settings' => array(
188
+				'func'       => '_update_reg_form_settings',
189
+				'capability' => 'manage_options',
190
+				'noheader'   => true,
191
+			),
192
+		);
193
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
194
+
195
+		$new_page_config = array(
196
+
197
+			'question_groups' => array(
198
+				'nav'           => array(
199
+					'label' => esc_html__('Question Groups', 'event_espresso'),
200
+					'order' => 20,
201
+				),
202
+				'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
203
+				'help_tabs'     => array(
204
+					'registration_form_question_groups_help_tab'                           => array(
205
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
206
+						'filename' => 'registration_form_question_groups',
207
+					),
208
+					'registration_form_question_groups_table_column_headings_help_tab'     => array(
209
+						'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
210
+						'filename' => 'registration_form_question_groups_table_column_headings',
211
+					),
212
+					'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
213
+						'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
214
+						'filename' => 'registration_form_question_groups_views_bulk_actions_search',
215
+					),
216
+				),
217
+				'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
218
+				'metaboxes'     => $this->_default_espresso_metaboxes,
219
+				'require_nonce' => false,
220
+				'qtips'         => array(
221
+					'EE_Registration_Form_Tips',
222
+				),
223
+			),
224
+
225
+			'add_question' => array(
226
+				'nav'           => array(
227
+					'label'      => esc_html__('Add Question', 'event_espresso'),
228
+					'order'      => 5,
229
+					'persistent' => false,
230
+				),
231
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
232
+				'help_tabs'     => array(
233
+					'registration_form_add_question_help_tab' => array(
234
+						'title'    => esc_html__('Add Question', 'event_espresso'),
235
+						'filename' => 'registration_form_add_question',
236
+					),
237
+				),
238
+				'help_tour'     => array('Registration_Form_Add_Question_Help_Tour'),
239
+				'require_nonce' => false,
240
+			),
241
+
242
+			'add_question_group' => array(
243
+				'nav'           => array(
244
+					'label'      => esc_html__('Add Question Group', 'event_espresso'),
245
+					'order'      => 5,
246
+					'persistent' => false,
247
+				),
248
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
249
+				'help_tabs'     => array(
250
+					'registration_form_add_question_group_help_tab' => array(
251
+						'title'    => esc_html__('Add Question Group', 'event_espresso'),
252
+						'filename' => 'registration_form_add_question_group',
253
+					),
254
+				),
255
+				'help_tour'     => array('Registration_Form_Add_Question_Group_Help_Tour'),
256
+				'require_nonce' => false,
257
+			),
258
+
259
+			'edit_question_group' => array(
260
+				'nav'           => array(
261
+					'label'      => esc_html__('Edit Question Group', 'event_espresso'),
262
+					'order'      => 5,
263
+					'persistent' => false,
264
+					'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
265
+						array('question_group_id' => $this->_req_data['question_group_id']),
266
+						$this->_current_page_view_url
267
+					) : $this->_admin_base_url,
268
+				),
269
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
270
+				'help_tabs'     => array(
271
+					'registration_form_edit_question_group_help_tab' => array(
272
+						'title'    => esc_html__('Edit Question Group', 'event_espresso'),
273
+						'filename' => 'registration_form_edit_question_group',
274
+					),
275
+				),
276
+				'help_tour'     => array('Registration_Form_Edit_Question_Group_Help_Tour'),
277
+				'require_nonce' => false,
278
+			),
279
+
280
+			'view_reg_form_settings' => array(
281
+				'nav'           => array(
282
+					'label' => esc_html__('Reg Form Settings', 'event_espresso'),
283
+					'order' => 40,
284
+				),
285
+				'labels'        => array(
286
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
287
+				),
288
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
289
+				'help_tabs'     => array(
290
+					'registration_form_reg_form_settings_help_tab' => array(
291
+						'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
292
+						'filename' => 'registration_form_reg_form_settings',
293
+					),
294
+				),
295
+				'help_tour'     => array('Registration_Form_Settings_Help_Tour'),
296
+				'require_nonce' => false,
297
+			),
298
+
299
+		);
300
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
301
+
302
+		// change the list table we're going to use so it's the NEW list table!
303
+		$this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
304
+
305
+
306
+		// additional labels
307
+		$new_labels = array(
308
+			'add_question'          => esc_html__('Add New Question', 'event_espresso'),
309
+			'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
310
+			'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
311
+			'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
312
+			'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
313
+		);
314
+		$this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
315
+	}
316
+
317
+
318
+	/**
319
+	 * @return void
320
+	 */
321
+	protected function _ajax_hooks()
322
+	{
323
+		add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
324
+	}
325
+
326
+
327
+	/**
328
+	 * @return void
329
+	 */
330
+	public function load_scripts_styles_question_groups()
331
+	{
332
+		wp_enqueue_script('espresso_ajax_table_sorting');
333
+	}
334
+
335
+
336
+	/**
337
+	 * @return void
338
+	 */
339
+	public function load_scripts_styles_add_question_group()
340
+	{
341
+		$this->load_scripts_styles_forms();
342
+		$this->load_sortable_question_script();
343
+	}
344
+
345
+
346
+	/**
347
+	 * @return void
348
+	 */
349
+	public function load_scripts_styles_edit_question_group()
350
+	{
351
+		$this->load_scripts_styles_forms();
352
+		$this->load_sortable_question_script();
353
+	}
354
+
355
+
356
+	/**
357
+	 * registers and enqueues script for questions
358
+	 *
359
+	 * @return void
360
+	 */
361
+	public function load_sortable_question_script()
362
+	{
363
+		wp_register_script(
364
+			'ee-question-sortable',
365
+			REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
366
+			array('jquery-ui-sortable'),
367
+			EVENT_ESPRESSO_VERSION,
368
+			true
369
+		);
370
+		wp_enqueue_script('ee-question-sortable');
371
+	}
372
+
373
+
374
+	/**
375
+	 * @return void
376
+	 */
377
+	protected function _set_list_table_views_default()
378
+	{
379
+		$this->_views = array(
380
+			'all' => array(
381
+				'slug'        => 'all',
382
+				'label'       => esc_html__('View All Questions', 'event_espresso'),
383
+				'count'       => 0,
384
+				'bulk_action' => array(
385
+					'trash_questions' => esc_html__('Trash', 'event_espresso'),
386
+				),
387
+			),
388
+		);
389
+
390
+		if (EE_Registry::instance()->CAP->current_user_can(
391
+			'ee_delete_questions',
392
+			'espresso_registration_form_trash_questions'
393
+		)
394
+		) {
395
+			$this->_views['trash'] = array(
396
+				'slug'        => 'trash',
397
+				'label'       => esc_html__('Trash', 'event_espresso'),
398
+				'count'       => 0,
399
+				'bulk_action' => array(
400
+					'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
401
+					'restore_questions' => esc_html__('Restore', 'event_espresso'),
402
+				),
403
+			);
404
+		}
405
+	}
406
+
407
+
408
+	/**
409
+	 * @return void
410
+	 */
411
+	protected function _set_list_table_views_question_groups()
412
+	{
413
+		$this->_views = array(
414
+			'all' => array(
415
+				'slug'        => 'all',
416
+				'label'       => esc_html__('All', 'event_espresso'),
417
+				'count'       => 0,
418
+				'bulk_action' => array(
419
+					'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
420
+				),
421
+			),
422
+		);
423
+
424
+		if (EE_Registry::instance()->CAP->current_user_can(
425
+			'ee_delete_question_groups',
426
+			'espresso_registration_form_trash_question_groups'
427
+		)
428
+		) {
429
+			$this->_views['trash'] = array(
430
+				'slug'        => 'trash',
431
+				'label'       => esc_html__('Trash', 'event_espresso'),
432
+				'count'       => 0,
433
+				'bulk_action' => array(
434
+					'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
435
+					'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
436
+				),
437
+			);
438
+		}
439
+	}
440
+
441
+
442
+	/**
443
+	 * @return void
444
+	 * @throws EE_Error
445
+	 * @throws InvalidArgumentException
446
+	 * @throws InvalidDataTypeException
447
+	 * @throws InvalidInterfaceException
448
+	 */
449
+	protected function _questions_overview_list_table()
450
+	{
451
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
452
+			'add_question',
453
+			'add_question',
454
+			array(),
455
+			'add-new-h2'
456
+		);
457
+		parent::_questions_overview_list_table();
458
+	}
459
+
460
+
461
+	/**
462
+	 * @return void
463
+	 * @throws DomainException
464
+	 * @throws EE_Error
465
+	 * @throws InvalidArgumentException
466
+	 * @throws InvalidDataTypeException
467
+	 * @throws InvalidInterfaceException
468
+	 */
469
+	protected function _question_groups_overview_list_table()
470
+	{
471
+		$this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
472
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
473
+			'add_question_group',
474
+			'add_question_group',
475
+			array(),
476
+			'add-new-h2'
477
+		);
478
+		$this->display_admin_list_table_page_with_sidebar();
479
+	}
480
+
481
+
482
+	/**
483
+	 * @return void
484
+	 * @throws EE_Error
485
+	 * @throws InvalidArgumentException
486
+	 * @throws InvalidDataTypeException
487
+	 * @throws InvalidInterfaceException
488
+	 */
489
+	protected function _delete_question()
490
+	{
491
+		$success = $this->_delete_items($this->_question_model);
492
+		$this->_redirect_after_action(
493
+			$success,
494
+			$this->_question_model->item_name($success),
495
+			'deleted',
496
+			array('action' => 'default', 'status' => 'all')
497
+		);
498
+	}
499
+
500
+
501
+	/**
502
+	 * @return void
503
+	 * @throws EE_Error
504
+	 * @throws InvalidArgumentException
505
+	 * @throws InvalidDataTypeException
506
+	 * @throws InvalidInterfaceException
507
+	 */
508
+	protected function _delete_questions()
509
+	{
510
+		$success = $this->_delete_items($this->_question_model);
511
+		$this->_redirect_after_action(
512
+			$success,
513
+			$this->_question_model->item_name($success),
514
+			'deleted permanently',
515
+			array('action' => 'default', 'status' => 'trash')
516
+		);
517
+	}
518
+
519
+
520
+	/**
521
+	 * Performs the deletion of a single or multiple questions or question groups.
522
+	 *
523
+	 * @param EEM_Soft_Delete_Base $model
524
+	 * @return int number of items deleted permanently
525
+	 * @throws EE_Error
526
+	 * @throws InvalidArgumentException
527
+	 * @throws InvalidDataTypeException
528
+	 * @throws InvalidInterfaceException
529
+	 */
530
+	private function _delete_items(EEM_Soft_Delete_Base $model)
531
+	{
532
+		$success = 0;
533
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
534
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
535
+			// if array has more than one element than success message should be plural
536
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
537
+			// cycle thru bulk action checkboxes
538
+			while (list($ID, $value) = each($this->_req_data['checkbox'])) {
539
+				if (! $this->_delete_item($ID, $model)) {
540
+					$success = 0;
541
+				}
542
+			}
543
+		} elseif (! empty($this->_req_data['QSG_ID'])) {
544
+			$success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
545
+		} elseif (! empty($this->_req_data['QST_ID'])) {
546
+			$success = $this->_delete_item($this->_req_data['QST_ID'], $model);
547
+		} else {
548
+			EE_Error::add_error(
549
+				sprintf(
550
+					esc_html__(
551
+						"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.",
552
+						"event_espresso"
553
+					)
554
+				),
555
+				__FILE__,
556
+				__FUNCTION__,
557
+				__LINE__
558
+			);
559
+		}
560
+		return $success;
561
+	}
562
+
563
+
564
+	/**
565
+	 * Deletes the specified question (and its associated question options) or question group
566
+	 *
567
+	 * @param int                  $id
568
+	 * @param EEM_Soft_Delete_Base $model
569
+	 * @return boolean
570
+	 * @throws EE_Error
571
+	 * @throws InvalidArgumentException
572
+	 * @throws InvalidDataTypeException
573
+	 * @throws InvalidInterfaceException
574
+	 */
575
+	protected function _delete_item($id, $model)
576
+	{
577
+		if ($model instanceof EEM_Question) {
578
+			EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
579
+		}
580
+		return $model->delete_permanently_by_ID(absint($id));
581
+	}
582
+
583
+
584
+	/******************************    QUESTION GROUPS    ******************************/
585
+
586
+
587
+	/**
588
+	 * @param string $type
589
+	 * @return void
590
+	 * @throws DomainException
591
+	 * @throws EE_Error
592
+	 * @throws InvalidArgumentException
593
+	 * @throws InvalidDataTypeException
594
+	 * @throws InvalidInterfaceException
595
+	 */
596
+	protected function _edit_question_group($type = 'add')
597
+	{
598
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
599
+		$ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
600
+			? absint($this->_req_data['QSG_ID'])
601
+			: false;
602
+
603
+		switch ($this->_req_action) {
604
+			case 'add_question_group':
605
+				$this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
606
+				break;
607
+			case 'edit_question_group':
608
+				$this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
609
+				break;
610
+			default:
611
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
612
+		}
613
+		// add ID to title if editing
614
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
615
+		if ($ID) {
616
+			/** @var EE_Question_Group $questionGroup */
617
+			$questionGroup = $this->_question_group_model->get_one_by_ID($ID);
618
+			$additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
619
+			$this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
620
+		} else {
621
+			/** @var EE_Question_Group $questionGroup */
622
+			$questionGroup = EEM_Question_Group::instance()->create_default_object();
623
+			$questionGroup->set_order_to_latest();
624
+			$this->_set_add_edit_form_tags('insert_question_group');
625
+		}
626
+		$this->_template_args['values'] = $this->_yes_no_values;
627
+		$this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
628
+		$this->_template_args['QSG_ID'] = $ID ? $ID : true;
629
+		$this->_template_args['question_group'] = $questionGroup;
630
+
631
+		$redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
632
+		$this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
633
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
634
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
635
+			$this->_template_args,
636
+			true
637
+		);
638
+
639
+		// the details template wrapper
640
+		$this->display_admin_page_with_sidebar();
641
+	}
642
+
643
+
644
+	/**
645
+	 * @return void
646
+	 * @throws EE_Error
647
+	 * @throws InvalidArgumentException
648
+	 * @throws InvalidDataTypeException
649
+	 * @throws InvalidInterfaceException
650
+	 */
651
+	protected function _delete_question_groups()
652
+	{
653
+		$success = $this->_delete_items($this->_question_group_model);
654
+		$this->_redirect_after_action(
655
+			$success,
656
+			$this->_question_group_model->item_name($success),
657
+			'deleted permanently',
658
+			array('action' => 'question_groups', 'status' => 'trash')
659
+		);
660
+	}
661
+
662
+
663
+	/**
664
+	 * @param bool $new_question_group
665
+	 * @throws EE_Error
666
+	 * @throws InvalidArgumentException
667
+	 * @throws InvalidDataTypeException
668
+	 * @throws InvalidInterfaceException
669
+	 */
670
+	protected function _insert_or_update_question_group($new_question_group = true)
671
+	{
672
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
673
+		$set_column_values = $this->_set_column_values_for($this->_question_group_model);
674
+		if ($new_question_group) {
675
+			// make sure identifier is unique
676
+			$identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
677
+			$identifier_exists = ! empty($identifier_value)
678
+				? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
679
+				: false;
680
+			if ($identifier_exists) {
681
+				$set_column_values['QSG_identifier'] .= uniqid('id', true);
682
+			}
683
+			$QSG_ID = $this->_question_group_model->insert($set_column_values);
684
+			$success = $QSG_ID ? 1 : 0;
685
+		} else {
686
+			$QSG_ID = absint($this->_req_data['QSG_ID']);
687
+			unset($set_column_values['QSG_ID']);
688
+			$success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
689
+		}
690
+		$phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
691
+			EEM_Attendee::system_question_phone
692
+		);
693
+		// update the existing related questions
694
+		// BUT FIRST...  delete the phone question from the Question_Group_Question
695
+		// if it is being added to this question group (therefore removed from the existing group)
696
+		if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
697
+			// delete where QST ID = system phone question ID and Question Group ID is NOT this group
698
+			EEM_Question_Group_Question::instance()->delete(
699
+				array(
700
+					array(
701
+						'QST_ID' => $phone_question_id,
702
+						'QSG_ID' => array('!=', $QSG_ID),
703
+					),
704
+				)
705
+			);
706
+		}
707
+		/** @type EE_Question_Group $question_group */
708
+		$question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
709
+		$questions = $question_group->questions();
710
+		// make sure system phone question is added to list of questions for this group
711
+		if (! isset($questions[ $phone_question_id ])) {
712
+			$questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
713
+		}
714
+
715
+		foreach ($questions as $question_ID => $question) {
716
+			// first we always check for order.
717
+			if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
718
+				// update question order
719
+				$question_group->update_question_order(
720
+					$question_ID,
721
+					$this->_req_data['question_orders'][ $question_ID ]
722
+				);
723
+			}
724
+
725
+			// then we always check if adding or removing.
726
+			if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
727
+				$question_group->add_question($question_ID);
728
+			} else {
729
+				// not found, remove it (but only if not a system question for the personal group
730
+				// with the exception of lname system question - we allow removal of it)
731
+				if (in_array(
732
+					$question->system_ID(),
733
+					EEM_Question::instance()->required_system_questions_in_system_question_group(
734
+						$question_group->system_group()
735
+					)
736
+				)) {
737
+					continue;
738
+				} else {
739
+					$question_group->remove_question($question_ID);
740
+				}
741
+			}
742
+		}
743
+		// save new related questions
744
+		if (isset($this->_req_data['questions'])) {
745
+			foreach ($this->_req_data['questions'] as $QST_ID) {
746
+				$question_group->add_question($QST_ID);
747
+				if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
748
+					$question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
749
+				}
750
+			}
751
+		}
752
+
753
+		if ($success !== false) {
754
+			$msg = $new_question_group
755
+				? sprintf(
756
+					esc_html__('The %s has been created', 'event_espresso'),
757
+					$this->_question_group_model->item_name()
758
+				)
759
+				: sprintf(
760
+					esc_html__(
761
+						'The %s has been updated',
762
+						'event_espresso'
763
+					),
764
+					$this->_question_group_model->item_name()
765
+				);
766
+			EE_Error::add_success($msg);
767
+		}
768
+		$this->_redirect_after_action(
769
+			false,
770
+			'',
771
+			'',
772
+			array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
773
+			true
774
+		);
775
+	}
776
+
777
+
778
+	/**
779
+	 * duplicates a question and all its question options and redirects to the new question.
780
+	 *
781
+	 * @return void
782
+	 * @throws EE_Error
783
+	 * @throws InvalidArgumentException
784
+	 * @throws ReflectionException
785
+	 * @throws InvalidDataTypeException
786
+	 * @throws InvalidInterfaceException
787
+	 */
788
+	public function _duplicate_question()
789
+	{
790
+		$question_ID = (int) $this->_req_data['QST_ID'];
791
+		$question = EEM_Question::instance()->get_one_by_ID($question_ID);
792
+		if ($question instanceof EE_Question) {
793
+			$new_question = $question->duplicate();
794
+			if ($new_question instanceof EE_Question) {
795
+				$this->_redirect_after_action(
796
+					true,
797
+					esc_html__('Question', 'event_espresso'),
798
+					esc_html__('Duplicated', 'event_espresso'),
799
+					array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
800
+					true
801
+				);
802
+			} else {
803
+				global $wpdb;
804
+				EE_Error::add_error(
805
+					sprintf(
806
+						esc_html__(
807
+							'Could not duplicate question with ID %1$d because: %2$s',
808
+							'event_espresso'
809
+						),
810
+						$question_ID,
811
+						$wpdb->last_error
812
+					),
813
+					__FILE__,
814
+					__FUNCTION__,
815
+					__LINE__
816
+				);
817
+				$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
818
+			}
819
+		} else {
820
+			EE_Error::add_error(
821
+				sprintf(
822
+					esc_html__(
823
+						'Could not duplicate question with ID %d because it didn\'t exist!',
824
+						'event_espresso'
825
+					),
826
+					$question_ID
827
+				),
828
+				__FILE__,
829
+				__FUNCTION__,
830
+				__LINE__
831
+			);
832
+			$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
833
+		}
834
+	}
835
+
836
+
837
+	/**
838
+	 * @param bool $trash
839
+	 * @throws EE_Error
840
+	 */
841
+	protected function _trash_or_restore_question_groups($trash = true)
842
+	{
843
+		$this->_trash_or_restore_items($this->_question_group_model, $trash);
844
+	}
845
+
846
+
847
+	/**
848
+	 *_trash_question
849
+	 *
850
+	 * @return void
851
+	 * @throws EE_Error
852
+	 */
853
+	protected function _trash_question()
854
+	{
855
+		$success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
856
+		$query_args = array('action' => 'default', 'status' => 'all');
857
+		$this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
858
+	}
859
+
860
+
861
+	/**
862
+	 * @param bool $trash
863
+	 * @throws EE_Error
864
+	 */
865
+	protected function _trash_or_restore_questions($trash = true)
866
+	{
867
+		$this->_trash_or_restore_items($this->_question_model, $trash);
868
+	}
869
+
870
+
871
+	/**
872
+	 * Internally used to delete or restore items, using the request data. Meant to be
873
+	 * flexible between question or question groups
874
+	 *
875
+	 * @param EEM_Soft_Delete_Base $model
876
+	 * @param boolean              $trash whether to trash or restore
877
+	 * @throws EE_Error
878
+	 */
879
+	private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
880
+	{
881
+
882
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
883
+
884
+		$success = 1;
885
+		// Checkboxes
886
+		// echo "trash $trash";
887
+		// var_dump($this->_req_data['checkbox']);die;
888
+		if (isset($this->_req_data['checkbox'])) {
889
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
890
+				// if array has more than one element than success message should be plural
891
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
892
+				// cycle thru bulk action checkboxes
893
+				while (list($ID, $value) = each($this->_req_data['checkbox'])) {
894
+					if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
895
+						$success = 0;
896
+					}
897
+				}
898
+			} else {
899
+				// grab single id and delete
900
+				$ID = absint($this->_req_data['checkbox']);
901
+				if (! $model->delete_or_restore_by_ID($trash, $ID)) {
902
+					$success = 0;
903
+				}
904
+			}
905
+		} else {
906
+			// delete via trash link
907
+			// grab single id and delete
908
+			$ID = absint($this->_req_data[ $model->primary_key_name() ]);
909
+			if (! $model->delete_or_restore_by_ID($trash, $ID)) {
910
+				$success = 0;
911
+			}
912
+		}
913
+
914
+
915
+		$action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
916
+		// echo "action :$action";
917
+		// $action = 'questions' ? 'default' : $action;
918
+		if ($trash) {
919
+			$action_desc = 'trashed';
920
+			$status = 'trash';
921
+		} else {
922
+			$action_desc = 'restored';
923
+			$status = 'all';
924
+		}
925
+		$this->_redirect_after_action(
926
+			$success,
927
+			$model->item_name($success),
928
+			$action_desc,
929
+			array('action' => $action, 'status' => $status)
930
+		);
931
+	}
932
+
933
+
934
+	/**
935
+	 * @param            $per_page
936
+	 * @param int        $current_page
937
+	 * @param bool|false $count
938
+	 * @return EE_Soft_Delete_Base_Class[]|int
939
+	 * @throws EE_Error
940
+	 * @throws InvalidArgumentException
941
+	 * @throws InvalidDataTypeException
942
+	 * @throws InvalidInterfaceException
943
+	 */
944
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
945
+	{
946
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
947
+
948
+		if ($count) {
949
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
950
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
951
+			$results = $this->_question_model->count_deleted($where);
952
+		} else {
953
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
954
+			$results = $this->_question_model->get_all_deleted($query_params);
955
+		}
956
+		return $results;
957
+	}
958
+
959
+
960
+	/**
961
+	 * @param            $per_page
962
+	 * @param int        $current_page
963
+	 * @param bool|false $count
964
+	 * @return EE_Soft_Delete_Base_Class[]|int
965
+	 * @throws EE_Error
966
+	 * @throws InvalidArgumentException
967
+	 * @throws InvalidDataTypeException
968
+	 * @throws InvalidInterfaceException
969
+	 */
970
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
971
+	{
972
+		$questionGroupModel = EEM_Question_Group::instance();
973
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
974
+		if ($count) {
975
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
976
+			$results = $questionGroupModel->count($where);
977
+		} else {
978
+			$results = $questionGroupModel->get_all($query_params);
979
+		}
980
+		return $results;
981
+	}
982
+
983
+
984
+	/**
985
+	 * @param      $per_page
986
+	 * @param int  $current_page
987
+	 * @param bool $count
988
+	 * @return EE_Soft_Delete_Base_Class[]|int
989
+	 * @throws EE_Error
990
+	 * @throws InvalidArgumentException
991
+	 * @throws InvalidDataTypeException
992
+	 * @throws InvalidInterfaceException
993
+	 */
994
+	public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
995
+	{
996
+		$questionGroupModel = EEM_Question_Group::instance();
997
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
998
+		if ($count) {
999
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
1000
+			$query_params['limit'] = null;
1001
+			$results = $questionGroupModel->count_deleted($where);
1002
+		} else {
1003
+			$results = $questionGroupModel->get_all_deleted($query_params);
1004
+		}
1005
+		return $results;
1006
+	}
1007
+
1008
+
1009
+	/**
1010
+	 * method for performing updates to question order
1011
+	 *
1012
+	 * @return void results array
1013
+	 * @throws EE_Error
1014
+	 * @throws InvalidArgumentException
1015
+	 * @throws InvalidDataTypeException
1016
+	 * @throws InvalidInterfaceException
1017
+	 */
1018
+	public function update_question_group_order()
1019
+	{
1020
+
1021
+		$success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1022
+
1023
+		// grab our row IDs
1024
+		$row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1025
+			? explode(',', rtrim($this->_req_data['row_ids'], ','))
1026
+			: array();
1027
+
1028
+		$perpage = ! empty($this->_req_data['perpage'])
1029
+			? (int) $this->_req_data['perpage']
1030
+			: null;
1031
+		$curpage = ! empty($this->_req_data['curpage'])
1032
+			? (int) $this->_req_data['curpage']
1033
+			: null;
1034
+
1035
+		if (! empty($row_ids)) {
1036
+			// figure out where we start the row_id count at for the current page.
1037
+			$qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1038
+
1039
+			$row_count = count($row_ids);
1040
+			for ($i = 0; $i < $row_count; $i++) {
1041
+				// Update the questions when re-ordering
1042
+				$updated = EEM_Question_Group::instance()->update(
1043
+					array('QSG_order' => $qsgcount),
1044
+					array(array('QSG_ID' => $row_ids[ $i ]))
1045
+				);
1046
+				if ($updated === false) {
1047
+					$success = false;
1048
+				}
1049
+				$qsgcount++;
1050
+			}
1051
+		} else {
1052
+			$success = false;
1053
+		}
1054
+
1055
+		$errors = ! $success
1056
+			? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1057
+			: false;
1058
+
1059
+		echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1060
+		die();
1061
+	}
1062
+
1063
+
1064
+
1065
+	/***************************************       REGISTRATION SETTINGS       ***************************************/
1066
+
1067
+
1068
+	/**
1069
+	 * @throws DomainException
1070
+	 * @throws EE_Error
1071
+	 * @throws InvalidArgumentException
1072
+	 * @throws InvalidDataTypeException
1073
+	 * @throws InvalidInterfaceException
1074
+	 */
1075
+	protected function _reg_form_settings()
1076
+	{
1077
+		$this->_template_args['values'] = $this->_yes_no_values;
1078
+		add_action(
1079
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1080
+			array($this, 'email_validation_settings_form'),
1081
+			2
1082
+		);
1083
+		$this->_template_args = (array) apply_filters(
1084
+			'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1085
+			$this->_template_args
1086
+		);
1087
+		$this->_set_add_edit_form_tags('update_reg_form_settings');
1088
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
1089
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1090
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1091
+			$this->_template_args,
1092
+			true
1093
+		);
1094
+		$this->display_admin_page_with_sidebar();
1095
+	}
1096
+
1097
+
1098
+	/**
1099
+	 * @return void
1100
+	 * @throws EE_Error
1101
+	 * @throws InvalidArgumentException
1102
+	 * @throws ReflectionException
1103
+	 * @throws InvalidDataTypeException
1104
+	 * @throws InvalidInterfaceException
1105
+	 */
1106
+	protected function _update_reg_form_settings()
1107
+	{
1108
+		EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1109
+			EE_Registry::instance()->CFG->registration
1110
+		);
1111
+		EE_Registry::instance()->CFG->registration = apply_filters(
1112
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1113
+			EE_Registry::instance()->CFG->registration
1114
+		);
1115
+		$success = $this->_update_espresso_configuration(
1116
+			esc_html__('Registration Form Options', 'event_espresso'),
1117
+			EE_Registry::instance()->CFG,
1118
+			__FILE__,
1119
+			__FUNCTION__,
1120
+			__LINE__
1121
+		);
1122
+		$this->_redirect_after_action(
1123
+			$success,
1124
+			esc_html__('Registration Form Options', 'event_espresso'),
1125
+			'updated',
1126
+			array('action' => 'view_reg_form_settings')
1127
+		);
1128
+	}
1129
+
1130
+
1131
+	/**
1132
+	 * @return void
1133
+	 * @throws EE_Error
1134
+	 * @throws InvalidArgumentException
1135
+	 * @throws InvalidDataTypeException
1136
+	 * @throws InvalidInterfaceException
1137
+	 */
1138
+	public function email_validation_settings_form()
1139
+	{
1140
+		echo $this->_email_validation_settings_form()->get_html();
1141
+	}
1142
+
1143
+
1144
+	/**
1145
+	 * _email_validation_settings_form
1146
+	 *
1147
+	 * @access protected
1148
+	 * @return EE_Form_Section_Proper
1149
+	 * @throws \EE_Error
1150
+	 */
1151
+	protected function _email_validation_settings_form()
1152
+	{
1153
+		return new EE_Form_Section_Proper(
1154
+			array(
1155
+				'name'            => 'email_validation_settings',
1156
+				'html_id'         => 'email_validation_settings',
1157
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1158
+				'subsections'     => apply_filters(
1159
+					'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1160
+					array(
1161
+						'email_validation_hdr'   => new EE_Form_Section_HTML(
1162
+							EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1163
+						),
1164
+						'email_validation_level' => new EE_Select_Input(
1165
+							array(
1166
+								'basic'      => esc_html__('Basic', 'event_espresso'),
1167
+								'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1168
+								'i18n'       => esc_html__('International', 'event_espresso'),
1169
+								'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1170
+							),
1171
+							array(
1172
+								'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1173
+													 . EEH_Template::get_help_tab_link('email_validation_info'),
1174
+								'html_help_text'  => esc_html__(
1175
+									'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.',
1176
+									'event_espresso'
1177
+								),
1178
+								'default'         => isset(
1179
+									EE_Registry::instance()->CFG->registration->email_validation_level
1180
+								)
1181
+									? EE_Registry::instance()->CFG->registration->email_validation_level
1182
+									: 'wp_default',
1183
+								'required'        => false,
1184
+							)
1185
+						),
1186
+					)
1187
+				),
1188
+			)
1189
+		);
1190
+	}
1191
+
1192
+
1193
+	/**
1194
+	 * @param EE_Registration_Config $EE_Registration_Config
1195
+	 * @return EE_Registration_Config
1196
+	 * @throws EE_Error
1197
+	 * @throws InvalidArgumentException
1198
+	 * @throws ReflectionException
1199
+	 * @throws InvalidDataTypeException
1200
+	 * @throws InvalidInterfaceException
1201
+	 */
1202
+	public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1203
+	{
1204
+		$prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1205
+		try {
1206
+			$email_validation_settings_form = $this->_email_validation_settings_form();
1207
+			// if not displaying a form, then check for form submission
1208
+			if ($email_validation_settings_form->was_submitted()) {
1209
+				// capture form data
1210
+				$email_validation_settings_form->receive_form_submission();
1211
+				// validate form data
1212
+				if ($email_validation_settings_form->is_valid()) {
1213
+					// grab validated data from form
1214
+					$valid_data = $email_validation_settings_form->valid_data();
1215
+					if (isset($valid_data['email_validation_level'])) {
1216
+						$email_validation_level = $valid_data['email_validation_level'];
1217
+						// now if they want to use international email addresses
1218
+						if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1219
+							// in case we need to reset their email validation level,
1220
+							// make sure that the previous value wasn't already set to one of the i18n options.
1221
+							if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1222
+								// if so, then reset it back to "basic" since that is the only other option that,
1223
+								// despite offering poor validation, supports i18n email addresses
1224
+								$prev_email_validation_level = 'basic';
1225
+							}
1226
+							// confirm our i18n email validation will work on the server
1227
+							if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1228
+								// or reset email validation level to previous value
1229
+								$email_validation_level = $prev_email_validation_level;
1230
+							}
1231
+						}
1232
+						$EE_Registration_Config->email_validation_level = $email_validation_level;
1233
+					} else {
1234
+						EE_Error::add_error(
1235
+							esc_html__(
1236
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1237
+								'event_espresso'
1238
+							),
1239
+							__FILE__,
1240
+							__FUNCTION__,
1241
+							__LINE__
1242
+						);
1243
+					}
1244
+				} else {
1245
+					if ($email_validation_settings_form->submission_error_message() !== '') {
1246
+						EE_Error::add_error(
1247
+							$email_validation_settings_form->submission_error_message(),
1248
+							__FILE__,
1249
+							__FUNCTION__,
1250
+							__LINE__
1251
+						);
1252
+					}
1253
+				}
1254
+			}
1255
+		} catch (EE_Error $e) {
1256
+			$e->get_error();
1257
+		}
1258
+		return $EE_Registration_Config;
1259
+	}
1260
+
1261
+
1262
+	/**
1263
+	 * confirms that the server's PHP version has the PCRE module enabled,
1264
+	 * and that the PCRE version works with our i18n email validation
1265
+	 *
1266
+	 * @param EE_Registration_Config $EE_Registration_Config
1267
+	 * @param string                 $email_validation_level
1268
+	 * @return bool
1269
+	 */
1270
+	private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1271
+	{
1272
+		// first check that PCRE is enabled
1273
+		if (! defined('PREG_BAD_UTF8_ERROR')) {
1274
+			EE_Error::add_error(
1275
+				sprintf(
1276
+					esc_html__(
1277
+						'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.',
1278
+						'event_espresso'
1279
+					),
1280
+					'<br />'
1281
+				),
1282
+				__FILE__,
1283
+				__FUNCTION__,
1284
+				__LINE__
1285
+			);
1286
+			return false;
1287
+		} else {
1288
+			// PCRE support is enabled, but let's still
1289
+			// perform a test to see if the server will support it.
1290
+			// but first, save the updated validation level to the config,
1291
+			// so that the validation strategy picks it up.
1292
+			// this will get bumped back down if it doesn't work
1293
+			$EE_Registration_Config->email_validation_level = $email_validation_level;
1294
+			try {
1295
+				$email_validator = new EE_Email_Validation_Strategy();
1296
+				$i18n_email_address = apply_filters(
1297
+					'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1298
+					'jägerjü[email protected]'
1299
+				);
1300
+				$email_validator->validate($i18n_email_address);
1301
+			} catch (Exception $e) {
1302
+				EE_Error::add_error(
1303
+					sprintf(
1304
+						esc_html__(
1305
+							'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',
1306
+							'event_espresso'
1307
+						),
1308
+						'<br />',
1309
+						'<a href="http://php.net/manual/en/pcre.installation.php" target="_blank">http://php.net/manual/en/pcre.installation.php</a>'
1310
+					),
1311
+					__FILE__,
1312
+					__FUNCTION__,
1313
+					__LINE__
1314
+				);
1315
+				return false;
1316
+			}
1317
+		}
1318
+		return true;
1319
+	}
1320 1320
 }
Please login to merge, or discard this patch.