Completed
Branch master (ec5ff5)
by
unknown
16:08 queued 14:18
created
admin_pages/registration_form/Registration_Form_Admin_Page.core.php 1 patch
Indentation   +764 added lines, -764 removed lines patch added patch discarded remove patch
@@ -16,707 +16,707 @@  discard block
 block discarded – undo
16 16
 class Registration_Form_Admin_Page extends EE_Admin_Page
17 17
 {
18 18
 
19
-    /**
20
-     * holds the specific question object for the question details screen
21
-     *
22
-     * @var EE_Question $_question
23
-     */
24
-    protected $_question;
25
-
26
-    /**
27
-     * holds the specific question group object for the question group details screen
28
-     *
29
-     * @var EE_Question_Group $_question_group
30
-     */
31
-    protected $_question_group;
32
-
33
-    /**
34
-     *_question_model EEM_Question model instance (for queries)
35
-     *
36
-     * @var EEM_Question $_question_model ;
37
-     */
38
-    protected $_question_model;
39
-
40
-    /**
41
-     * _question_group_model EEM_Question_group instance (for queries)
42
-     *
43
-     * @var EEM_Question_Group $_question_group_model
44
-     */
45
-    protected $_question_group_model;
46
-
47
-
48
-    /**
49
-     * @Constructor
50
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
51
-     * @throws EE_Error
52
-     * @throws ReflectionException
53
-     */
54
-    public function __construct($routing = true)
55
-    {
56
-        require_once(EE_MODELS . 'EEM_Question.model.php');
57
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
58
-        $this->_question_model       = EEM_Question::instance();
59
-        $this->_question_group_model = EEM_Question_Group::instance();
60
-        parent::__construct($routing);
61
-    }
62
-
63
-
64
-    protected function _init_page_props()
65
-    {
66
-        $this->page_slug        = REGISTRATION_FORM_PG_SLUG;
67
-        $this->page_label       = esc_html__('Registration Form', 'event_espresso');
68
-        $this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
69
-        $this->_admin_base_path = REGISTRATION_FORM_ADMIN;
70
-    }
71
-
72
-
73
-    protected function _ajax_hooks()
74
-    {
75
-    }
76
-
77
-
78
-    protected function _define_page_props()
79
-    {
80
-        $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
81
-        $this->_labels           = [
82
-            'buttons' => [
83
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
84
-            ],
85
-        ];
86
-    }
87
-
88
-
89
-    /**
90
-     *_set_page_routes
91
-     */
92
-    protected function _set_page_routes()
93
-    {
94
-        $qst_id             =
95
-            ! empty($this->_req_data['QST_ID'])
96
-                ? $this->_req_data['QST_ID']
97
-                : 0;
98
-        $this->_page_routes = [
99
-            'default' => [
100
-                'func'       => '_questions_overview_list_table',
101
-                'capability' => 'ee_read_questions',
102
-            ],
103
-
104
-            'edit_question' => [
105
-                'func'       => '_edit_question',
106
-                'capability' => 'ee_edit_question',
107
-                'obj_id'     => $qst_id,
108
-                'args'       => ['edit'],
109
-            ],
110
-
111
-            'question_groups' => [
112
-                'func'       => '_questions_groups_preview',
113
-                'capability' => 'ee_read_question_groups',
114
-            ],
115
-
116
-            'update_question' => [
117
-                'func'       => '_insert_or_update_question',
118
-                'args'       => ['new_question' => false],
119
-                'capability' => 'ee_edit_question',
120
-                'obj_id'     => $qst_id,
121
-                'noheader'   => true,
122
-            ],
123
-        ];
124
-    }
125
-
126
-
127
-    protected function _set_page_config()
128
-    {
129
-        $this->_page_config = [
130
-            'default' => [
131
-                'nav'           => [
132
-                    'label' => esc_html__('Questions', 'event_espresso'),
133
-                    'order' => 10,
134
-                ],
135
-                'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
136
-                'metaboxes'     => $this->_default_espresso_metaboxes,
137
-                'help_tabs'     => [
138
-                    'registration_form_questions_overview_help_tab'                           => [
139
-                        'title'    => esc_html__('Questions Overview', 'event_espresso'),
140
-                        'filename' => 'registration_form_questions_overview',
141
-                    ],
142
-                    'registration_form_questions_overview_table_column_headings_help_tab'     => [
143
-                        'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
144
-                        'filename' => 'registration_form_questions_overview_table_column_headings',
145
-                    ],
146
-                    'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
147
-                        'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
148
-                        'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
149
-                    ],
150
-                ],
151
-                'require_nonce' => false,
152
-                'qtips'         => [
153
-                    'EE_Registration_Form_Tips',
154
-                ]/**/
155
-            ],
156
-
157
-            'question_groups' => [
158
-                'nav'           => [
159
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
160
-                    'order' => 20,
161
-                ],
162
-                'metaboxes'     => $this->_default_espresso_metaboxes,
163
-                'help_tabs'     => [
164
-                    'registration_form_question_groups_help_tab' => [
165
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
166
-                        'filename' => 'registration_form_question_groups',
167
-                    ],
168
-                ],
169
-                'require_nonce' => false,
170
-            ],
171
-
172
-            'edit_question' => [
173
-                'nav'           => [
174
-                    'label'      => esc_html__('Edit Question', 'event_espresso'),
175
-                    'order'      => 15,
176
-                    'persistent' => false,
177
-                    'url'        => isset($this->_req_data['question_id'])
178
-                        ? add_query_arg(
179
-                            ['question_id' => $this->_req_data['question_id']],
180
-                            $this->_current_page_view_url
181
-                        )
182
-                        : $this->_admin_base_url,
183
-                ],
184
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
185
-                'help_tabs'     => [
186
-                    'registration_form_edit_question_group_help_tab' => [
187
-                        'title'    => esc_html__('Edit Question', 'event_espresso'),
188
-                        'filename' => 'registration_form_edit_question',
189
-                    ],
190
-                ],
191
-                'require_nonce' => false,
192
-            ],
193
-        ];
194
-    }
195
-
196
-
197
-    protected function _add_screen_options()
198
-    {
199
-        // todo
200
-    }
201
-
202
-
203
-    protected function _add_screen_options_default()
204
-    {
205
-        $page_title              = $this->_admin_page_title;
206
-        $this->_admin_page_title = esc_html__('Questions', 'event_espresso');
207
-        $this->_per_page_screen_option();
208
-        $this->_admin_page_title = $page_title;
209
-    }
210
-
211
-
212
-    protected function _add_screen_options_question_groups()
213
-    {
214
-        $page_title              = $this->_admin_page_title;
215
-        $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
216
-        $this->_per_page_screen_option();
217
-        $this->_admin_page_title = $page_title;
218
-    }
219
-
220
-
221
-    // none of the below group are currently used for Event Categories
222
-    protected function _add_feature_pointers()
223
-    {
224
-    }
225
-
226
-
227
-    public function load_scripts_styles()
228
-    {
229
-        wp_register_style(
230
-            'espresso_registration',
231
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
232
-            [],
233
-            EVENT_ESPRESSO_VERSION
234
-        );
235
-        wp_enqueue_style('espresso_registration');
236
-    }
237
-
238
-
239
-    public function admin_init()
240
-    {
241
-    }
242
-
243
-
244
-    public function admin_notices()
245
-    {
246
-    }
247
-
248
-
249
-    public function admin_footer_scripts()
250
-    {
251
-    }
252
-
253
-
254
-    public function load_scripts_styles_default()
255
-    {
256
-    }
257
-
258
-
259
-    /**
260
-     * @throws EE_Error
261
-     */
262
-    public function load_scripts_styles_add_question()
263
-    {
264
-        $this->load_scripts_styles_question_details();
265
-    }
266
-
267
-
268
-    /**
269
-     * @throws EE_Error
270
-     */
271
-    public function load_scripts_styles_edit_question()
272
-    {
273
-        $this->load_scripts_styles_question_details();
274
-    }
275
-
276
-
277
-    /**
278
-     * Loads the JS required for adding or editing a question
279
-     *
280
-     * @throws EE_Error
281
-     * @throws EE_Error
282
-     */
283
-    protected function load_scripts_styles_question_details()
284
-    {
285
-        $this->load_scripts_styles_forms();
286
-        wp_register_script(
287
-            'espresso_registration_form_single',
288
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
289
-            ['jquery-ui-sortable'],
290
-            EVENT_ESPRESSO_VERSION,
291
-            true
292
-        );
293
-        wp_enqueue_script('espresso_registration_form_single');
294
-        wp_localize_script(
295
-            'espresso_registration_form_single',
296
-            'ee_question_data',
297
-            [
298
-                'question_types_with_max'    => EEM_Question::instance()->questionTypesWithMaxLength(),
299
-                'question_type_with_options' => EEM_Question::instance()->question_types_with_options(),
300
-            ]
301
-        );
302
-    }
303
-
304
-
305
-    public function recaptcha_info_help_tab()
306
-    {
307
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
308
-        EEH_Template::display_template($template, []);
309
-    }
310
-
311
-
312
-    public function load_scripts_styles_forms()
313
-    {
314
-        // styles
315
-        wp_enqueue_style('espresso-ui-theme');
316
-        // scripts
317
-        wp_enqueue_script('ee_admin_js');
318
-    }
319
-
320
-
321
-    protected function _set_list_table_views_default()
322
-    {
323
-        $this->_views = [
324
-            'all' => [
325
-                'slug'  => 'all',
326
-                'label' => esc_html__('View All Questions', 'event_espresso'),
327
-                'count' => 0,
328
-            ],
329
-        ];
330
-
331
-        if (
332
-            EE_Registry::instance()->CAP->current_user_can(
333
-                'ee_delete_questions',
334
-                'espresso_registration_form_trash_questions'
335
-            )
336
-        ) {
337
-            $this->_views['trash'] = [
338
-                'slug'  => 'trash',
339
-                'label' => esc_html__('Trash', 'event_espresso'),
340
-                'count' => 0,
341
-            ];
342
-        }
343
-    }
344
-
345
-
346
-    /**
347
-     * This just previews the question groups tab that comes in caffeinated.
348
-     *
349
-     * @return void html
350
-     * @throws EE_Error
351
-     */
352
-    protected function _questions_groups_preview()
353
-    {
354
-        $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
355
-        $this->_template_args['preview_img']  =
356
-            '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
357
-            . esc_attr__(
358
-                'Preview Question Groups Overview List Table screenshot',
359
-                'event_espresso'
360
-            ) . '" />';
361
-        $this->_template_args['preview_text'] = '<strong>'
362
-                                                . esc_html__(
363
-                                                    'Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
364
-                                                    'event_espresso'
365
-                                                ) . '</strong>';
366
-        $this->display_admin_caf_preview_page('question_groups_tab');
367
-    }
368
-
369
-
370
-    /**
371
-     * Extracts the question field's values from the POST request to update or insert them
372
-     *
373
-     * @param EEM_Base $model
374
-     * @return array where each key is the name of a model's field/db column, and each value is its value.
375
-     * @throws EE_Error
376
-     */
377
-    protected function _set_column_values_for(EEM_Base $model)
378
-    {
379
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
380
-        $set_column_values = [];
381
-
382
-        // some initial checks for proper values.
383
-        // if QST_admin_only, then no matter what QST_required is we disable.
384
-        if (! empty($this->_req_data['QST_admin_only'])) {
385
-            $this->_req_data['QST_required'] = 0;
386
-        }
387
-        // if the question shouldn't have a max length, don't let them set one
388
-        if (
389
-            ! isset(
390
-                $this->_req_data['QST_type'],
391
-                $this->_req_data['QST_max']
392
-            )
393
-            || ! in_array(
394
-                $this->_req_data['QST_type'],
395
-                EEM_Question::instance()->questionTypesWithMaxLength(),
396
-                true
397
-            )
398
-        ) {
399
-            // they're not allowed to set the max
400
-            $this->_req_data['QST_max'] = null;
401
-        }
402
-        foreach ($model->field_settings() as $fieldName => $settings) {
403
-            // basically if QSG_identifier is empty or not set
404
-            if (
405
-                $fieldName === 'QSG_identifier'
406
-                && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))
407
-            ) {
408
-                $QSG_name = isset($this->_req_data['QSG_name'])
409
-                    ? $this->_req_data['QSG_name']
410
-                    : '';
411
-                $set_column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
412
-            } elseif (
413
-                $fieldName === 'QST_admin_label'
414
-                && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))
415
-            ) {
416
-                // the admin label is blank, use a slug version of the question text
417
-                $QST_text                        =
418
-                    isset($this->_req_data['QST_display_text'])
419
-                        ? $this->_req_data['QST_display_text']
420
-                        : '';
421
-                $set_column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
422
-            } elseif ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
423
-                $set_column_values[ $fieldName ] = 0;
424
-            } elseif ($fieldName === 'QST_max') {
425
-                $qst_system = EEM_Question::instance()->get_var(
426
-                    [
427
-                        [
428
-                            'QST_ID' => isset($this->_req_data['QST_ID'])
429
-                                ? $this->_req_data['QST_ID']
430
-                                : 0,
431
-                        ],
432
-                    ],
433
-                    'QST_system'
434
-                );
435
-                $max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
436
-                if (
437
-                    empty($this->_req_data['QST_max']) || $this->_req_data['QST_max'] > $max_max
438
-                ) {
439
-                    $set_column_values[ $fieldName ] = $max_max;
440
-                }
441
-            }
442
-
443
-
444
-            // only add a property to the array if it's not null (otherwise the model should just use the default value)
445
-            if (
446
-                ! isset($set_column_values[ $fieldName ]) && isset($this->_req_data[ $fieldName ])
447
-            ) {
448
-                $set_column_values[ $fieldName ] = $this->_req_data[ $fieldName ];
449
-            }
450
-        }
451
-        return $set_column_values;// validation fo this data to be performed by the model before insertion.
452
-    }
453
-
454
-
455
-    /**
456
-     *_questions_overview_list_table
457
-     *
458
-     * @throws EE_Error
459
-     */
460
-    protected function _questions_overview_list_table()
461
-    {
462
-        $this->_search_btn_label = esc_html__('Questions', 'event_espresso');
463
-        $this->display_admin_list_table_page_with_sidebar();
464
-    }
465
-
466
-
467
-    /**
468
-     * _edit_question
469
-     *
470
-     * @throws EE_Error
471
-     * @throws ReflectionException
472
-     */
473
-    protected function _edit_question()
474
-    {
475
-        $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
476
-            ? absint($this->_req_data['QST_ID'])
477
-            : false;
478
-
479
-        switch ($this->_req_action) {
480
-            case 'add_question':
481
-                $this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
482
-                break;
483
-            case 'edit_question':
484
-                $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
485
-                break;
486
-            default:
487
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
488
-        }
489
-
490
-        // add PRC_ID to title if editing
491
-        $this->_admin_page_title =
492
-            $ID
493
-                ? $this->_admin_page_title . ' # ' . $ID
494
-                : $this->_admin_page_title;
495
-        if ($ID) {
496
-            $question                 = $this->_question_model->get_one_by_ID($ID);
497
-            $additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
498
-            $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
499
-        } else {
500
-            $question = EE_Question::new_instance();
501
-            $question->set_order_to_latest();
502
-            $this->_set_add_edit_form_tags('insert_question');
503
-        }
504
-        if ($question->system_ID() === EEM_Attendee::system_question_phone) {
505
-            $question_types = array_intersect_key(
506
-                EEM_Question::instance()->allowed_question_types(),
507
-                array_flip(
508
-                    [
509
-                        EEM_Question::QST_type_text,
510
-                        EEM_Question::QST_type_us_phone,
511
-                    ]
512
-                )
513
-            );
514
-        } else {
515
-            $question_types = $question->has_answers()
516
-                ? $this->_question_model->question_types_in_same_category($question->type())
517
-                : $this->_question_model->allowed_question_types();
518
-        }
519
-        $this->_template_args['QST_ID']                     = $ID;
520
-        $this->_template_args['question']                   = $question;
521
-        $this->_template_args['question_types']             = $question_types;
522
-        $this->_template_args['max_max']                    =
523
-            EEM_Question::instance()->absolute_max_for_system_question(
524
-                $question->system_ID()
525
-            );
526
-        $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
527
-        $this->_set_publish_post_box_vars('id', $ID);
528
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
529
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
530
-            $this->_template_args,
531
-            true
532
-        );
533
-
534
-        // the details template wrapper
535
-        $this->display_admin_page_with_sidebar();
536
-    }
537
-
538
-
539
-    /**
540
-     * @return string
541
-     * @throws EE_Error
542
-     * @throws ReflectionException
543
-     */
544
-    protected function _get_question_type_descriptions()
545
-    {
546
-        EE_Registry::instance()->load_helper('HTML');
547
-        $descriptions               = '';
548
-        $question_type_descriptions = EEM_Question::instance()->question_descriptions();
549
-        foreach ($question_type_descriptions as $type => $question_type_description) {
550
-            if ($type == 'HTML_TEXTAREA') {
551
-                $html                      = new EE_Simple_HTML_Validation_Strategy();
552
-                $question_type_description .= sprintf(
553
-                    esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
554
-                    '<br/>',
555
-                    $html->get_list_of_allowed_tags()
556
-                );
557
-            }
558
-            $descriptions .= EEH_HTML::p(
559
-                $question_type_description,
560
-                'question_type_description-' . $type,
561
-                'question_type_description description',
562
-                'display:none;'
563
-            );
564
-        }
565
-        return $descriptions;
566
-    }
567
-
568
-
569
-    /**
570
-     * @param bool|true $new_question
571
-     * @throws EE_Error
572
-     * @throws ReflectionException
573
-     */
574
-    protected function _insert_or_update_question($new_question = true)
575
-    {
576
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
577
-        $set_column_values = $this->_set_column_values_for($this->_question_model);
578
-        if ($new_question) {
579
-            $question    = EE_Question::new_instance($set_column_values);
580
-            $action_desc = 'added';
581
-        } else {
582
-            $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
583
-            foreach ($set_column_values as $field => $new_value) {
584
-                $question->set($field, $new_value);
585
-            }
586
-            $action_desc = 'updated';
587
-        }
588
-        $success = $question->save();
589
-        $ID      = $question->ID();
590
-        if ($ID && $question->should_have_question_options()) {
591
-            // save the related options
592
-            // trash removed options, save old ones
593
-            // get list of all options
594
-            $options = $question->options();
595
-            if (! empty($options)) {
596
-                foreach ($options as $option_ID => $option) {
597
-                    $option_req_index = $this->_get_option_req_data_index($option_ID);
598
-                    if ($option_req_index !== false) {
599
-                        $option->save($this->_req_data['question_options'][ $option_req_index ]);
600
-                    } else {
601
-                        // not found, remove it
602
-                        $option->delete();
603
-                    }
604
-                }
605
-            }
606
-            // save new related options
607
-            foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
608
-                // skip $index that is from our sample
609
-                if ($index === 'xxcountxx') {
610
-                    continue;
611
-                }
612
-                // note we allow saving blank options.
613
-                if (empty($option_req_data['QSO_ID'])) {
614
-                    // no ID! save it!
615
-                    $new_option = EE_Question_Option::new_instance(
616
-                        [
617
-                            'QSO_value' => $option_req_data['QSO_value'],
618
-                            'QSO_desc'  => $option_req_data['QSO_desc'],
619
-                            'QSO_order' => $option_req_data['QSO_order'],
620
-                            'QST_ID'    => $question->ID(),
621
-                        ]
622
-                    );
623
-                    $new_option->save();
624
-                }
625
-            }
626
-        }
627
-        $query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
628
-        if ($success !== 0) {
629
-            $msg = $new_question
630
-                ? sprintf(
631
-                    esc_html__('The %s has been created', 'event_espresso'),
632
-                    $this->_question_model->item_name()
633
-                )
634
-                : sprintf(
635
-                    esc_html__('The %s has been updated', 'event_espresso'),
636
-                    $this->_question_model->item_name()
637
-                );
638
-            EE_Error::add_success($msg);
639
-        }
640
-
641
-        $this->_redirect_after_action(false, '', $action_desc, $query_args, true);
642
-    }
643
-
644
-
645
-    /**
646
-     * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
647
-     * by ID
648
-     * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
649
-     * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
650
-     *
651
-     * @param int $ID of the question option to find
652
-     * @return int index in question_options array if successful, FALSE if unsuccessful
653
-     */
654
-    protected function _get_option_req_data_index($ID)
655
-    {
656
-        $req_data_for_question_options = $this->_req_data['question_options'];
657
-        foreach ($req_data_for_question_options as $num => $option_data) {
658
-            if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
659
-                return $num;
660
-            }
661
-        }
662
-        return false;
663
-    }
664
-
665
-
666
-
667
-
668
-    /***********/
669
-    /* QUERIES */
670
-    /**
671
-     * For internal use in getting all the query parameters
672
-     * (because it's pretty well the same between question, question groups,
673
-     * and for both when searching for trashed and untrashed ones)
674
-     *
675
-     * @param EEM_Base $model either EEM_Question or EEM_Question_Group
676
-     * @param int      $per_page
677
-     * @param int      $current_page
678
-     * @return array model query params, @see
679
-     *               https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
680
-     */
681
-    protected function get_query_params($model, $per_page = 10, $current_page = 10)
682
-    {
683
-        $query_params             = [];
684
-        $offset                   = ($current_page - 1) * $per_page;
685
-        $query_params['limit']    = [$offset, $per_page];
686
-        $order                    =
687
-            (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
688
-                ? $this->_req_data['order']
689
-                : 'ASC';
690
-        $orderby_field            =
691
-            $model instanceof EEM_Question
692
-                ? 'QST_ID'
693
-                : 'QSG_order';
694
-        $field_to_order_by        =
695
-            empty($this->_req_data['orderby'])
696
-                ? $orderby_field
697
-                : $this->_req_data['orderby'];
698
-        $query_params['order_by'] = [$field_to_order_by => $order];
699
-        $search_string            =
700
-            array_key_exists('s', $this->_req_data)
701
-                ? $this->_req_data['s']
702
-                : null;
703
-        if (! empty($search_string)) {
704
-            if ($model instanceof EEM_Question_Group) {
705
-                $query_params[0] = [
706
-                    'OR' => [
707
-                        'QSG_name' => ['LIKE', "%$search_string%"],
708
-                        'QSG_desc' => ['LIKE', "%$search_string%"],
709
-                    ],
710
-                ];
711
-            } else {
712
-                $query_params[0] = [
713
-                    'QST_display_text' => ['LIKE', "%$search_string%"],
714
-                ];
715
-            }
716
-        }
717
-
718
-        // capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
719
-        /*if ( $model instanceof EEM_Question_Group ) {
19
+	/**
20
+	 * holds the specific question object for the question details screen
21
+	 *
22
+	 * @var EE_Question $_question
23
+	 */
24
+	protected $_question;
25
+
26
+	/**
27
+	 * holds the specific question group object for the question group details screen
28
+	 *
29
+	 * @var EE_Question_Group $_question_group
30
+	 */
31
+	protected $_question_group;
32
+
33
+	/**
34
+	 *_question_model EEM_Question model instance (for queries)
35
+	 *
36
+	 * @var EEM_Question $_question_model ;
37
+	 */
38
+	protected $_question_model;
39
+
40
+	/**
41
+	 * _question_group_model EEM_Question_group instance (for queries)
42
+	 *
43
+	 * @var EEM_Question_Group $_question_group_model
44
+	 */
45
+	protected $_question_group_model;
46
+
47
+
48
+	/**
49
+	 * @Constructor
50
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
51
+	 * @throws EE_Error
52
+	 * @throws ReflectionException
53
+	 */
54
+	public function __construct($routing = true)
55
+	{
56
+		require_once(EE_MODELS . 'EEM_Question.model.php');
57
+		require_once(EE_MODELS . 'EEM_Question_Group.model.php');
58
+		$this->_question_model       = EEM_Question::instance();
59
+		$this->_question_group_model = EEM_Question_Group::instance();
60
+		parent::__construct($routing);
61
+	}
62
+
63
+
64
+	protected function _init_page_props()
65
+	{
66
+		$this->page_slug        = REGISTRATION_FORM_PG_SLUG;
67
+		$this->page_label       = esc_html__('Registration Form', 'event_espresso');
68
+		$this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
69
+		$this->_admin_base_path = REGISTRATION_FORM_ADMIN;
70
+	}
71
+
72
+
73
+	protected function _ajax_hooks()
74
+	{
75
+	}
76
+
77
+
78
+	protected function _define_page_props()
79
+	{
80
+		$this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
81
+		$this->_labels           = [
82
+			'buttons' => [
83
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
84
+			],
85
+		];
86
+	}
87
+
88
+
89
+	/**
90
+	 *_set_page_routes
91
+	 */
92
+	protected function _set_page_routes()
93
+	{
94
+		$qst_id             =
95
+			! empty($this->_req_data['QST_ID'])
96
+				? $this->_req_data['QST_ID']
97
+				: 0;
98
+		$this->_page_routes = [
99
+			'default' => [
100
+				'func'       => '_questions_overview_list_table',
101
+				'capability' => 'ee_read_questions',
102
+			],
103
+
104
+			'edit_question' => [
105
+				'func'       => '_edit_question',
106
+				'capability' => 'ee_edit_question',
107
+				'obj_id'     => $qst_id,
108
+				'args'       => ['edit'],
109
+			],
110
+
111
+			'question_groups' => [
112
+				'func'       => '_questions_groups_preview',
113
+				'capability' => 'ee_read_question_groups',
114
+			],
115
+
116
+			'update_question' => [
117
+				'func'       => '_insert_or_update_question',
118
+				'args'       => ['new_question' => false],
119
+				'capability' => 'ee_edit_question',
120
+				'obj_id'     => $qst_id,
121
+				'noheader'   => true,
122
+			],
123
+		];
124
+	}
125
+
126
+
127
+	protected function _set_page_config()
128
+	{
129
+		$this->_page_config = [
130
+			'default' => [
131
+				'nav'           => [
132
+					'label' => esc_html__('Questions', 'event_espresso'),
133
+					'order' => 10,
134
+				],
135
+				'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
136
+				'metaboxes'     => $this->_default_espresso_metaboxes,
137
+				'help_tabs'     => [
138
+					'registration_form_questions_overview_help_tab'                           => [
139
+						'title'    => esc_html__('Questions Overview', 'event_espresso'),
140
+						'filename' => 'registration_form_questions_overview',
141
+					],
142
+					'registration_form_questions_overview_table_column_headings_help_tab'     => [
143
+						'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
144
+						'filename' => 'registration_form_questions_overview_table_column_headings',
145
+					],
146
+					'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
147
+						'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
148
+						'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
149
+					],
150
+				],
151
+				'require_nonce' => false,
152
+				'qtips'         => [
153
+					'EE_Registration_Form_Tips',
154
+				]/**/
155
+			],
156
+
157
+			'question_groups' => [
158
+				'nav'           => [
159
+					'label' => esc_html__('Question Groups', 'event_espresso'),
160
+					'order' => 20,
161
+				],
162
+				'metaboxes'     => $this->_default_espresso_metaboxes,
163
+				'help_tabs'     => [
164
+					'registration_form_question_groups_help_tab' => [
165
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
166
+						'filename' => 'registration_form_question_groups',
167
+					],
168
+				],
169
+				'require_nonce' => false,
170
+			],
171
+
172
+			'edit_question' => [
173
+				'nav'           => [
174
+					'label'      => esc_html__('Edit Question', 'event_espresso'),
175
+					'order'      => 15,
176
+					'persistent' => false,
177
+					'url'        => isset($this->_req_data['question_id'])
178
+						? add_query_arg(
179
+							['question_id' => $this->_req_data['question_id']],
180
+							$this->_current_page_view_url
181
+						)
182
+						: $this->_admin_base_url,
183
+				],
184
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
185
+				'help_tabs'     => [
186
+					'registration_form_edit_question_group_help_tab' => [
187
+						'title'    => esc_html__('Edit Question', 'event_espresso'),
188
+						'filename' => 'registration_form_edit_question',
189
+					],
190
+				],
191
+				'require_nonce' => false,
192
+			],
193
+		];
194
+	}
195
+
196
+
197
+	protected function _add_screen_options()
198
+	{
199
+		// todo
200
+	}
201
+
202
+
203
+	protected function _add_screen_options_default()
204
+	{
205
+		$page_title              = $this->_admin_page_title;
206
+		$this->_admin_page_title = esc_html__('Questions', 'event_espresso');
207
+		$this->_per_page_screen_option();
208
+		$this->_admin_page_title = $page_title;
209
+	}
210
+
211
+
212
+	protected function _add_screen_options_question_groups()
213
+	{
214
+		$page_title              = $this->_admin_page_title;
215
+		$this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
216
+		$this->_per_page_screen_option();
217
+		$this->_admin_page_title = $page_title;
218
+	}
219
+
220
+
221
+	// none of the below group are currently used for Event Categories
222
+	protected function _add_feature_pointers()
223
+	{
224
+	}
225
+
226
+
227
+	public function load_scripts_styles()
228
+	{
229
+		wp_register_style(
230
+			'espresso_registration',
231
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
232
+			[],
233
+			EVENT_ESPRESSO_VERSION
234
+		);
235
+		wp_enqueue_style('espresso_registration');
236
+	}
237
+
238
+
239
+	public function admin_init()
240
+	{
241
+	}
242
+
243
+
244
+	public function admin_notices()
245
+	{
246
+	}
247
+
248
+
249
+	public function admin_footer_scripts()
250
+	{
251
+	}
252
+
253
+
254
+	public function load_scripts_styles_default()
255
+	{
256
+	}
257
+
258
+
259
+	/**
260
+	 * @throws EE_Error
261
+	 */
262
+	public function load_scripts_styles_add_question()
263
+	{
264
+		$this->load_scripts_styles_question_details();
265
+	}
266
+
267
+
268
+	/**
269
+	 * @throws EE_Error
270
+	 */
271
+	public function load_scripts_styles_edit_question()
272
+	{
273
+		$this->load_scripts_styles_question_details();
274
+	}
275
+
276
+
277
+	/**
278
+	 * Loads the JS required for adding or editing a question
279
+	 *
280
+	 * @throws EE_Error
281
+	 * @throws EE_Error
282
+	 */
283
+	protected function load_scripts_styles_question_details()
284
+	{
285
+		$this->load_scripts_styles_forms();
286
+		wp_register_script(
287
+			'espresso_registration_form_single',
288
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
289
+			['jquery-ui-sortable'],
290
+			EVENT_ESPRESSO_VERSION,
291
+			true
292
+		);
293
+		wp_enqueue_script('espresso_registration_form_single');
294
+		wp_localize_script(
295
+			'espresso_registration_form_single',
296
+			'ee_question_data',
297
+			[
298
+				'question_types_with_max'    => EEM_Question::instance()->questionTypesWithMaxLength(),
299
+				'question_type_with_options' => EEM_Question::instance()->question_types_with_options(),
300
+			]
301
+		);
302
+	}
303
+
304
+
305
+	public function recaptcha_info_help_tab()
306
+	{
307
+		$template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
308
+		EEH_Template::display_template($template, []);
309
+	}
310
+
311
+
312
+	public function load_scripts_styles_forms()
313
+	{
314
+		// styles
315
+		wp_enqueue_style('espresso-ui-theme');
316
+		// scripts
317
+		wp_enqueue_script('ee_admin_js');
318
+	}
319
+
320
+
321
+	protected function _set_list_table_views_default()
322
+	{
323
+		$this->_views = [
324
+			'all' => [
325
+				'slug'  => 'all',
326
+				'label' => esc_html__('View All Questions', 'event_espresso'),
327
+				'count' => 0,
328
+			],
329
+		];
330
+
331
+		if (
332
+			EE_Registry::instance()->CAP->current_user_can(
333
+				'ee_delete_questions',
334
+				'espresso_registration_form_trash_questions'
335
+			)
336
+		) {
337
+			$this->_views['trash'] = [
338
+				'slug'  => 'trash',
339
+				'label' => esc_html__('Trash', 'event_espresso'),
340
+				'count' => 0,
341
+			];
342
+		}
343
+	}
344
+
345
+
346
+	/**
347
+	 * This just previews the question groups tab that comes in caffeinated.
348
+	 *
349
+	 * @return void html
350
+	 * @throws EE_Error
351
+	 */
352
+	protected function _questions_groups_preview()
353
+	{
354
+		$this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
355
+		$this->_template_args['preview_img']  =
356
+			'<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
357
+			. esc_attr__(
358
+				'Preview Question Groups Overview List Table screenshot',
359
+				'event_espresso'
360
+			) . '" />';
361
+		$this->_template_args['preview_text'] = '<strong>'
362
+												. esc_html__(
363
+													'Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
364
+													'event_espresso'
365
+												) . '</strong>';
366
+		$this->display_admin_caf_preview_page('question_groups_tab');
367
+	}
368
+
369
+
370
+	/**
371
+	 * Extracts the question field's values from the POST request to update or insert them
372
+	 *
373
+	 * @param EEM_Base $model
374
+	 * @return array where each key is the name of a model's field/db column, and each value is its value.
375
+	 * @throws EE_Error
376
+	 */
377
+	protected function _set_column_values_for(EEM_Base $model)
378
+	{
379
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
380
+		$set_column_values = [];
381
+
382
+		// some initial checks for proper values.
383
+		// if QST_admin_only, then no matter what QST_required is we disable.
384
+		if (! empty($this->_req_data['QST_admin_only'])) {
385
+			$this->_req_data['QST_required'] = 0;
386
+		}
387
+		// if the question shouldn't have a max length, don't let them set one
388
+		if (
389
+			! isset(
390
+				$this->_req_data['QST_type'],
391
+				$this->_req_data['QST_max']
392
+			)
393
+			|| ! in_array(
394
+				$this->_req_data['QST_type'],
395
+				EEM_Question::instance()->questionTypesWithMaxLength(),
396
+				true
397
+			)
398
+		) {
399
+			// they're not allowed to set the max
400
+			$this->_req_data['QST_max'] = null;
401
+		}
402
+		foreach ($model->field_settings() as $fieldName => $settings) {
403
+			// basically if QSG_identifier is empty or not set
404
+			if (
405
+				$fieldName === 'QSG_identifier'
406
+				&& (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))
407
+			) {
408
+				$QSG_name = isset($this->_req_data['QSG_name'])
409
+					? $this->_req_data['QSG_name']
410
+					: '';
411
+				$set_column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
412
+			} elseif (
413
+				$fieldName === 'QST_admin_label'
414
+				&& (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))
415
+			) {
416
+				// the admin label is blank, use a slug version of the question text
417
+				$QST_text                        =
418
+					isset($this->_req_data['QST_display_text'])
419
+						? $this->_req_data['QST_display_text']
420
+						: '';
421
+				$set_column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
422
+			} elseif ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
423
+				$set_column_values[ $fieldName ] = 0;
424
+			} elseif ($fieldName === 'QST_max') {
425
+				$qst_system = EEM_Question::instance()->get_var(
426
+					[
427
+						[
428
+							'QST_ID' => isset($this->_req_data['QST_ID'])
429
+								? $this->_req_data['QST_ID']
430
+								: 0,
431
+						],
432
+					],
433
+					'QST_system'
434
+				);
435
+				$max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
436
+				if (
437
+					empty($this->_req_data['QST_max']) || $this->_req_data['QST_max'] > $max_max
438
+				) {
439
+					$set_column_values[ $fieldName ] = $max_max;
440
+				}
441
+			}
442
+
443
+
444
+			// only add a property to the array if it's not null (otherwise the model should just use the default value)
445
+			if (
446
+				! isset($set_column_values[ $fieldName ]) && isset($this->_req_data[ $fieldName ])
447
+			) {
448
+				$set_column_values[ $fieldName ] = $this->_req_data[ $fieldName ];
449
+			}
450
+		}
451
+		return $set_column_values;// validation fo this data to be performed by the model before insertion.
452
+	}
453
+
454
+
455
+	/**
456
+	 *_questions_overview_list_table
457
+	 *
458
+	 * @throws EE_Error
459
+	 */
460
+	protected function _questions_overview_list_table()
461
+	{
462
+		$this->_search_btn_label = esc_html__('Questions', 'event_espresso');
463
+		$this->display_admin_list_table_page_with_sidebar();
464
+	}
465
+
466
+
467
+	/**
468
+	 * _edit_question
469
+	 *
470
+	 * @throws EE_Error
471
+	 * @throws ReflectionException
472
+	 */
473
+	protected function _edit_question()
474
+	{
475
+		$ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
476
+			? absint($this->_req_data['QST_ID'])
477
+			: false;
478
+
479
+		switch ($this->_req_action) {
480
+			case 'add_question':
481
+				$this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
482
+				break;
483
+			case 'edit_question':
484
+				$this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
485
+				break;
486
+			default:
487
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
488
+		}
489
+
490
+		// add PRC_ID to title if editing
491
+		$this->_admin_page_title =
492
+			$ID
493
+				? $this->_admin_page_title . ' # ' . $ID
494
+				: $this->_admin_page_title;
495
+		if ($ID) {
496
+			$question                 = $this->_question_model->get_one_by_ID($ID);
497
+			$additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
498
+			$this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
499
+		} else {
500
+			$question = EE_Question::new_instance();
501
+			$question->set_order_to_latest();
502
+			$this->_set_add_edit_form_tags('insert_question');
503
+		}
504
+		if ($question->system_ID() === EEM_Attendee::system_question_phone) {
505
+			$question_types = array_intersect_key(
506
+				EEM_Question::instance()->allowed_question_types(),
507
+				array_flip(
508
+					[
509
+						EEM_Question::QST_type_text,
510
+						EEM_Question::QST_type_us_phone,
511
+					]
512
+				)
513
+			);
514
+		} else {
515
+			$question_types = $question->has_answers()
516
+				? $this->_question_model->question_types_in_same_category($question->type())
517
+				: $this->_question_model->allowed_question_types();
518
+		}
519
+		$this->_template_args['QST_ID']                     = $ID;
520
+		$this->_template_args['question']                   = $question;
521
+		$this->_template_args['question_types']             = $question_types;
522
+		$this->_template_args['max_max']                    =
523
+			EEM_Question::instance()->absolute_max_for_system_question(
524
+				$question->system_ID()
525
+			);
526
+		$this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
527
+		$this->_set_publish_post_box_vars('id', $ID);
528
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
529
+			REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
530
+			$this->_template_args,
531
+			true
532
+		);
533
+
534
+		// the details template wrapper
535
+		$this->display_admin_page_with_sidebar();
536
+	}
537
+
538
+
539
+	/**
540
+	 * @return string
541
+	 * @throws EE_Error
542
+	 * @throws ReflectionException
543
+	 */
544
+	protected function _get_question_type_descriptions()
545
+	{
546
+		EE_Registry::instance()->load_helper('HTML');
547
+		$descriptions               = '';
548
+		$question_type_descriptions = EEM_Question::instance()->question_descriptions();
549
+		foreach ($question_type_descriptions as $type => $question_type_description) {
550
+			if ($type == 'HTML_TEXTAREA') {
551
+				$html                      = new EE_Simple_HTML_Validation_Strategy();
552
+				$question_type_description .= sprintf(
553
+					esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
554
+					'<br/>',
555
+					$html->get_list_of_allowed_tags()
556
+				);
557
+			}
558
+			$descriptions .= EEH_HTML::p(
559
+				$question_type_description,
560
+				'question_type_description-' . $type,
561
+				'question_type_description description',
562
+				'display:none;'
563
+			);
564
+		}
565
+		return $descriptions;
566
+	}
567
+
568
+
569
+	/**
570
+	 * @param bool|true $new_question
571
+	 * @throws EE_Error
572
+	 * @throws ReflectionException
573
+	 */
574
+	protected function _insert_or_update_question($new_question = true)
575
+	{
576
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
577
+		$set_column_values = $this->_set_column_values_for($this->_question_model);
578
+		if ($new_question) {
579
+			$question    = EE_Question::new_instance($set_column_values);
580
+			$action_desc = 'added';
581
+		} else {
582
+			$question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
583
+			foreach ($set_column_values as $field => $new_value) {
584
+				$question->set($field, $new_value);
585
+			}
586
+			$action_desc = 'updated';
587
+		}
588
+		$success = $question->save();
589
+		$ID      = $question->ID();
590
+		if ($ID && $question->should_have_question_options()) {
591
+			// save the related options
592
+			// trash removed options, save old ones
593
+			// get list of all options
594
+			$options = $question->options();
595
+			if (! empty($options)) {
596
+				foreach ($options as $option_ID => $option) {
597
+					$option_req_index = $this->_get_option_req_data_index($option_ID);
598
+					if ($option_req_index !== false) {
599
+						$option->save($this->_req_data['question_options'][ $option_req_index ]);
600
+					} else {
601
+						// not found, remove it
602
+						$option->delete();
603
+					}
604
+				}
605
+			}
606
+			// save new related options
607
+			foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
608
+				// skip $index that is from our sample
609
+				if ($index === 'xxcountxx') {
610
+					continue;
611
+				}
612
+				// note we allow saving blank options.
613
+				if (empty($option_req_data['QSO_ID'])) {
614
+					// no ID! save it!
615
+					$new_option = EE_Question_Option::new_instance(
616
+						[
617
+							'QSO_value' => $option_req_data['QSO_value'],
618
+							'QSO_desc'  => $option_req_data['QSO_desc'],
619
+							'QSO_order' => $option_req_data['QSO_order'],
620
+							'QST_ID'    => $question->ID(),
621
+						]
622
+					);
623
+					$new_option->save();
624
+				}
625
+			}
626
+		}
627
+		$query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
628
+		if ($success !== 0) {
629
+			$msg = $new_question
630
+				? sprintf(
631
+					esc_html__('The %s has been created', 'event_espresso'),
632
+					$this->_question_model->item_name()
633
+				)
634
+				: sprintf(
635
+					esc_html__('The %s has been updated', 'event_espresso'),
636
+					$this->_question_model->item_name()
637
+				);
638
+			EE_Error::add_success($msg);
639
+		}
640
+
641
+		$this->_redirect_after_action(false, '', $action_desc, $query_args, true);
642
+	}
643
+
644
+
645
+	/**
646
+	 * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
647
+	 * by ID
648
+	 * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
649
+	 * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
650
+	 *
651
+	 * @param int $ID of the question option to find
652
+	 * @return int index in question_options array if successful, FALSE if unsuccessful
653
+	 */
654
+	protected function _get_option_req_data_index($ID)
655
+	{
656
+		$req_data_for_question_options = $this->_req_data['question_options'];
657
+		foreach ($req_data_for_question_options as $num => $option_data) {
658
+			if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
659
+				return $num;
660
+			}
661
+		}
662
+		return false;
663
+	}
664
+
665
+
666
+
667
+
668
+	/***********/
669
+	/* QUERIES */
670
+	/**
671
+	 * For internal use in getting all the query parameters
672
+	 * (because it's pretty well the same between question, question groups,
673
+	 * and for both when searching for trashed and untrashed ones)
674
+	 *
675
+	 * @param EEM_Base $model either EEM_Question or EEM_Question_Group
676
+	 * @param int      $per_page
677
+	 * @param int      $current_page
678
+	 * @return array model query params, @see
679
+	 *               https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
680
+	 */
681
+	protected function get_query_params($model, $per_page = 10, $current_page = 10)
682
+	{
683
+		$query_params             = [];
684
+		$offset                   = ($current_page - 1) * $per_page;
685
+		$query_params['limit']    = [$offset, $per_page];
686
+		$order                    =
687
+			(isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
688
+				? $this->_req_data['order']
689
+				: 'ASC';
690
+		$orderby_field            =
691
+			$model instanceof EEM_Question
692
+				? 'QST_ID'
693
+				: 'QSG_order';
694
+		$field_to_order_by        =
695
+			empty($this->_req_data['orderby'])
696
+				? $orderby_field
697
+				: $this->_req_data['orderby'];
698
+		$query_params['order_by'] = [$field_to_order_by => $order];
699
+		$search_string            =
700
+			array_key_exists('s', $this->_req_data)
701
+				? $this->_req_data['s']
702
+				: null;
703
+		if (! empty($search_string)) {
704
+			if ($model instanceof EEM_Question_Group) {
705
+				$query_params[0] = [
706
+					'OR' => [
707
+						'QSG_name' => ['LIKE', "%$search_string%"],
708
+						'QSG_desc' => ['LIKE', "%$search_string%"],
709
+					],
710
+				];
711
+			} else {
712
+				$query_params[0] = [
713
+					'QST_display_text' => ['LIKE', "%$search_string%"],
714
+				];
715
+			}
716
+		}
717
+
718
+		// capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
719
+		/*if ( $model instanceof EEM_Question_Group ) {
720 720
             if ( ! EE_Registry::instance()->CAP->current_user_can( 'edit_others_question_groups', 'espresso_registration_form_edit_question_group' ) ) {
721 721
                 $query_params[0] = array(
722 722
                     'AND' => array(
@@ -746,67 +746,67 @@  discard block
 block discarded – undo
746 746
             }
747 747
         }/**/
748 748
 
749
-        return $query_params;
750
-    }
751
-
752
-
753
-    /**
754
-     * @param int        $per_page
755
-     * @param int        $current_page
756
-     * @param bool|false $count
757
-     * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]|int
758
-     * @throws EE_Error
759
-     */
760
-    public function get_questions($per_page = 10, $current_page = 1, $count = false)
761
-    {
762
-        $QST          = EEM_Question::instance();
763
-        $query_params = $this->get_query_params($QST, $per_page, $current_page);
764
-        if ($count) {
765
-            $where   =
766
-                isset($query_params[0])
767
-                    ? [$query_params[0]]
768
-                    : [];
769
-            $results = $QST->count($where);
770
-        } else {
771
-            $results = $QST->get_all($query_params);
772
-        }
773
-        return $results;
774
-    }
775
-
776
-
777
-    /**
778
-     * @param            $per_page
779
-     * @param int        $current_page
780
-     * @param bool|false $count
781
-     * @return EE_Soft_Delete_Base_Class[]|int
782
-     * @throws EE_Error
783
-     */
784
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
785
-    {
786
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
787
-        $where        =
788
-            isset($query_params[0])
789
-                ? [$query_params[0]]
790
-                : [];
791
-        return $count
792
-            ? EEM_Question::instance()->count_deleted($where)
793
-            : EEM_Question::instance()->get_all_deleted($query_params);
794
-    }
795
-
796
-
797
-    /**
798
-     * @param            $per_page
799
-     * @param int        $current_page
800
-     * @param bool|false $count
801
-     * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]
802
-     * @throws EE_Error
803
-     */
804
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
805
-    {
806
-        $questionGroupModel = EEM_Question_Group::instance();
807
-        // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
808
-        return $questionGroupModel->get_all(
809
-            $this->get_query_params($questionGroupModel, $per_page, $current_page)
810
-        );
811
-    }
749
+		return $query_params;
750
+	}
751
+
752
+
753
+	/**
754
+	 * @param int        $per_page
755
+	 * @param int        $current_page
756
+	 * @param bool|false $count
757
+	 * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]|int
758
+	 * @throws EE_Error
759
+	 */
760
+	public function get_questions($per_page = 10, $current_page = 1, $count = false)
761
+	{
762
+		$QST          = EEM_Question::instance();
763
+		$query_params = $this->get_query_params($QST, $per_page, $current_page);
764
+		if ($count) {
765
+			$where   =
766
+				isset($query_params[0])
767
+					? [$query_params[0]]
768
+					: [];
769
+			$results = $QST->count($where);
770
+		} else {
771
+			$results = $QST->get_all($query_params);
772
+		}
773
+		return $results;
774
+	}
775
+
776
+
777
+	/**
778
+	 * @param            $per_page
779
+	 * @param int        $current_page
780
+	 * @param bool|false $count
781
+	 * @return EE_Soft_Delete_Base_Class[]|int
782
+	 * @throws EE_Error
783
+	 */
784
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
785
+	{
786
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
787
+		$where        =
788
+			isset($query_params[0])
789
+				? [$query_params[0]]
790
+				: [];
791
+		return $count
792
+			? EEM_Question::instance()->count_deleted($where)
793
+			: EEM_Question::instance()->get_all_deleted($query_params);
794
+	}
795
+
796
+
797
+	/**
798
+	 * @param            $per_page
799
+	 * @param int        $current_page
800
+	 * @param bool|false $count
801
+	 * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]
802
+	 * @throws EE_Error
803
+	 */
804
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
805
+	{
806
+		$questionGroupModel = EEM_Question_Group::instance();
807
+		// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
808
+		return $questionGroupModel->get_all(
809
+			$this->get_query_params($questionGroupModel, $per_page, $current_page)
810
+		);
811
+	}
812 812
 }
Please login to merge, or discard this patch.
registration_form/help_tabs/registration_form_add_question.help_tab.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -8,34 +8,34 @@  discard block
 block discarded – undo
8 8
 </p>
9 9
 <p>
10 10
     <?php printf(
11
-        esc_html__('This page allows you to add a new question for %s.', 'event_espresso'),
12
-        Domain::brandName()
13
-    ); ?>
11
+		esc_html__('This page allows you to add a new question for %s.', 'event_espresso'),
12
+		Domain::brandName()
13
+	); ?>
14 14
 </p>
15 15
 <ul>
16 16
     <li>
17 17
         <strong><?php esc_html_e('Question Text', 'event_espresso'); ?></strong>
18 18
         <br />
19 19
         <?php esc_html_e(
20
-            'This shows the question as it will be displayed on the registration form. HTML can be used here.',
21
-            'event_espresso'
22
-        ); ?>
20
+			'This shows the question as it will be displayed on the registration form. HTML can be used here.',
21
+			'event_espresso'
22
+		); ?>
23 23
     </li>
24 24
     <li>
25 25
         <strong><?php esc_html_e('Question Label (admin-only)', 'event_espresso'); ?></strong>
26 26
         <br />
27 27
         <?php esc_html_e(
28
-            'This field is only shown to the admin. It is useful for understanding the difference between questions that appear to be similar but are used in various situations. HTML cannot be used.',
29
-            'event_espresso'
30
-        ); ?>
28
+			'This field is only shown to the admin. It is useful for understanding the difference between questions that appear to be similar but are used in various situations. HTML cannot be used.',
29
+			'event_espresso'
30
+		); ?>
31 31
     </li>
32 32
     <li>
33 33
         <strong><?php esc_html_e('Question Order', 'event_espresso'); ?></strong>
34 34
         <br />
35 35
         <?php esc_html_e(
36
-            'Questions can be sorted by using the drag and drop feature on the Questions Overview page. Another way to sort questions is to adjust their order of application by using this field. A smaller order of application will be shown first. For example, a question with an order of application of 1 will appear before one that has an order of application of 5.',
37
-            'event_espresso'
38
-        ); ?>
36
+			'Questions can be sorted by using the drag and drop feature on the Questions Overview page. Another way to sort questions is to adjust their order of application by using this field. A smaller order of application will be shown first. For example, a question with an order of application of 1 will appear before one that has an order of application of 5.',
37
+			'event_espresso'
38
+		); ?>
39 39
     </li>
40 40
     <li>
41 41
         <strong><?php esc_html_e('Admin-Only Question?', 'event_espresso'); ?></strong>
@@ -46,9 +46,9 @@  discard block
 block discarded – undo
46 46
         <strong><?php esc_html_e('Question Type', 'event_espresso'); ?></strong>
47 47
         <br />
48 48
         <?php esc_html_e(
49
-            'This shows the type of question. Available options are Text, Textarea, Checkboxes, Radio Buttons, Dropdown, State/Province Dropdown, Country Dropdown, and Date Picker.',
50
-            'event_espresso'
51
-        ); ?>
49
+			'This shows the type of question. Available options are Text, Textarea, Checkboxes, Radio Buttons, Dropdown, State/Province Dropdown, Country Dropdown, and Date Picker.',
50
+			'event_espresso'
51
+		); ?>
52 52
     </li>
53 53
     <li>
54 54
         <strong><?php esc_html_e('Answer Options (for applicable question types)', 'event_espresso'); ?></strong>
@@ -64,24 +64,24 @@  discard block
 block discarded – undo
64 64
         <strong><?php esc_html_e('Required Text', 'event_espresso'); ?></strong>
65 65
         <br />
66 66
         <?php esc_html_e(
67
-            'This text is displayed when a registrant does not answer a question but is required to do so. The default message will show "this field is required."',
68
-            'event_espresso'
69
-        ); ?>
67
+			'This text is displayed when a registrant does not answer a question but is required to do so. The default message will show "this field is required."',
68
+			'event_espresso'
69
+		); ?>
70 70
     </li>
71 71
 </ul>
72 72
 <p>
73 73
     <strong><?php esc_html_e('Recommendations', 'event_espresso'); ?></strong>
74 74
     <br />
75 75
     <?php esc_html_e(
76
-        'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
77
-        'event_espresso'
78
-    ); ?>
76
+		'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
77
+		'event_espresso'
78
+	); ?>
79 79
 </p>
80 80
 <p>
81 81
     <strong><?php esc_html_e('Screen Options', 'event_espresso'); ?></strong>
82 82
     <br />
83 83
     <?php esc_html_e(
84
-        'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
85
-        'event_espresso'
86
-    ); ?>
84
+		'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
85
+		'event_espresso'
86
+	); ?>
87 87
 </p>
88 88
\ No newline at end of file
Please login to merge, or discard this patch.
help_tabs/registration_form_reg_form_settings.help_tab.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -3,9 +3,9 @@  discard block
 block discarded – undo
3 3
 </p>
4 4
 <p>
5 5
     <?php esc_html_e(
6
-        'This page shows options for Email Validation, the EE "Bot Trap" and reCAPTCHA which can help prevent SPAM registrations on your site.',
7
-        'event_espresso'
8
-    ); ?>
6
+		'This page shows options for Email Validation, the EE "Bot Trap" and reCAPTCHA which can help prevent SPAM registrations on your site.',
7
+		'event_espresso'
8
+	); ?>
9 9
 </p>
10 10
 <div id="email_validation_info">
11 11
     <p>
@@ -13,9 +13,9 @@  discard block
 block discarded – undo
13 13
     </p>
14 14
     <p>
15 15
         <?php esc_html_e(
16
-            "Validating an email address is extremely difficult to do correctly. Your server's configuration, as well as your own tolerances and needs, can affect the type of validation needed. We offer different types of validation so that you can control how strict your registration form responds to entered email addresses. If you are receiving too many bogus email addresses, then you can try the WordPress Default validation setting. If you find that the form validation is blocking a valid email address you can try the Basic setting, or if available, the International validation settings.",
17
-            'event_espresso'
18
-        ); ?>
16
+			"Validating an email address is extremely difficult to do correctly. Your server's configuration, as well as your own tolerances and needs, can affect the type of validation needed. We offer different types of validation so that you can control how strict your registration form responds to entered email addresses. If you are receiving too many bogus email addresses, then you can try the WordPress Default validation setting. If you find that the form validation is blocking a valid email address you can try the Basic setting, or if available, the International validation settings.",
17
+			'event_espresso'
18
+		); ?>
19 19
     </p>
20 20
     <p>
21 21
         <strong><?php esc_html_e('Validation Options:', 'event_espresso'); ?></strong>
@@ -23,27 +23,27 @@  discard block
 block discarded – undo
23 23
     <ul>
24 24
         <li>
25 25
             <?php esc_html_e(
26
-                '"Basic" - only checks that an email address follows the most basic structure guidelines ( ie: [email protected] ). Will work with the widest range of email addresses but will also allow the most garbage through.',
27
-                'event_espresso'
28
-            ); ?>
26
+				'"Basic" - only checks that an email address follows the most basic structure guidelines ( ie: [email protected] ). Will work with the widest range of email addresses but will also allow the most garbage through.',
27
+				'event_espresso'
28
+			); ?>
29 29
         </li>
30 30
         <li>
31 31
             <?php esc_html_e(
32
-                '"WordPress Default" - uses built in WordPress email validation, but does not support unicode characters (ie: international characters from non-latin based languages).',
33
-                'event_espresso'
34
-            ); ?>
32
+				'"WordPress Default" - uses built in WordPress email validation, but does not support unicode characters (ie: international characters from non-latin based languages).',
33
+				'event_espresso'
34
+			); ?>
35 35
         </li>
36 36
         <li>
37 37
             <?php esc_html_e(
38
-                '"International" - supports unicode characters but may not be supported by all server configurations. Try this first if you need to international language support, but drop back down to "Basic" if your server configuration conflicts.',
39
-                'event_espresso'
40
-            ); ?>
38
+				'"International" - supports unicode characters but may not be supported by all server configurations. Try this first if you need to international language support, but drop back down to "Basic" if your server configuration conflicts.',
39
+				'event_espresso'
40
+			); ?>
41 41
         </li>
42 42
         <li>
43 43
             <?php esc_html_e(
44
-                '"International + DNS Check" - same as "International" but also performs MX and A record DNS checks to verify that the email address domain exists (ie: the portion of the address after the "@"). Can not verify that the local portion of the email address is valid (ie: the first portion of the address before the "@").',
45
-                'event_espresso'
46
-            ); ?>
44
+				'"International + DNS Check" - same as "International" but also performs MX and A record DNS checks to verify that the email address domain exists (ie: the portion of the address after the "@"). Can not verify that the local portion of the email address is valid (ie: the first portion of the address before the "@").',
45
+				'event_espresso'
46
+			); ?>
47 47
         </li>
48 48
     </ul>
49 49
 </div>
@@ -51,21 +51,21 @@  discard block
 block discarded – undo
51 51
     <p><strong><?php esc_html_e('reCAPTCHA Information', 'event_espresso'); ?></strong></p>
52 52
     <p>
53 53
         <?php printf(
54
-            esc_html__(
55
-                '%s helps prevent automated abuse of your site (such as comment spam or bogus registrations) by using a reCAPTCHA to ensure that only humans perform certain actions.',
56
-                'event_espresso'
57
-            ),
58
-            '<a href="https://www.google.com/recaptcha/intro/index.html" target="_blank" rel="noopener noreferrer">reCAPTCHA</a>'
59
-        ); ?>
54
+			esc_html__(
55
+				'%s helps prevent automated abuse of your site (such as comment spam or bogus registrations) by using a reCAPTCHA to ensure that only humans perform certain actions.',
56
+				'event_espresso'
57
+			),
58
+			'<a href="https://www.google.com/recaptcha/intro/index.html" target="_blank" rel="noopener noreferrer">reCAPTCHA</a>'
59
+		); ?>
60 60
     </p>
61 61
     <p>
62 62
         <?php printf(
63
-            esc_html__(
64
-                'You must sign up for a free %s account to use it with this plugin. If you already have a reCAPTCHA account enter your "Public" and "Private" keys on this page.',
65
-                'event_espresso'
66
-            ),
67
-            '<a href="https://www.google.com/recaptcha/admin#createsite" target="_blank" rel="noopener noreferrer">reCAPTCHA</a>'
68
-        ); ?>
63
+			esc_html__(
64
+				'You must sign up for a free %s account to use it with this plugin. If you already have a reCAPTCHA account enter your "Public" and "Private" keys on this page.',
65
+				'event_espresso'
66
+			),
67
+			'<a href="https://www.google.com/recaptcha/admin#createsite" target="_blank" rel="noopener noreferrer">reCAPTCHA</a>'
68
+		); ?>
69 69
     </p>
70 70
     <p><strong><?php esc_html_e('Helpful Information:', 'event_espresso'); ?></strong></p>
71 71
     <ul>
@@ -82,14 +82,14 @@  discard block
 block discarded – undo
82 82
 <p>
83 83
     <strong><?php esc_html_e('Recommendations', 'event_espresso'); ?></strong><br />
84 84
     <?php esc_html_e(
85
-        'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
86
-        'event_espresso'
87
-    ); ?>
85
+		'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
86
+		'event_espresso'
87
+	); ?>
88 88
 </p>
89 89
 <p>
90 90
     <strong><?php esc_html_e('Screen Options', 'event_espresso'); ?></strong><br />
91 91
     <?php esc_html_e(
92
-        'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
93
-        'event_espresso'
94
-    ); ?>
92
+		'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
93
+		'event_espresso'
94
+	); ?>
95 95
 </p>
Please login to merge, or discard this patch.
help_tabs/registration_form_edit_question_group.help_tab.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -7,38 +7,38 @@  discard block
 block discarded – undo
7 7
 <p>
8 8
     <strong><?php esc_html_e('Notice', 'event_espresso'); ?></strong><br />
9 9
     <?php esc_html_e(
10
-        'System questions groups may have some options disabled. This is to ensure that your registrations don\'t break from accidental changes.',
11
-        'event_espresso'
12
-    ); ?>
10
+		'System questions groups may have some options disabled. This is to ensure that your registrations don\'t break from accidental changes.',
11
+		'event_espresso'
12
+	); ?>
13 13
 </p>
14 14
 <ul>
15 15
     <li>
16 16
         <strong><?php esc_html_e('Group Name', 'event_espresso'); ?></strong><br />
17 17
         <?php esc_html_e(
18
-            'This is the name (title) of the question group as it will be displayed on the registration form. HTML cannot be used.',
19
-            'event_espresso'
20
-        ); ?>
18
+			'This is the name (title) of the question group as it will be displayed on the registration form. HTML cannot be used.',
19
+			'event_espresso'
20
+		); ?>
21 21
     </li>
22 22
     <li>
23 23
         <strong><?php esc_html_e('Group Identifier', 'event_espresso'); ?></strong><br />
24 24
         <?php esc_html_e(
25
-            'This is a unique name (slug) for this group. It helps you tell the difference between this group and other groups that may appear to be similar. It is not shown to registrants and HTML cannot be used.',
26
-            'event_espresso'
27
-        ); ?>
25
+			'This is a unique name (slug) for this group. It helps you tell the difference between this group and other groups that may appear to be similar. It is not shown to registrants and HTML cannot be used.',
26
+			'event_espresso'
27
+		); ?>
28 28
     </li>
29 29
     <li>
30 30
         <strong><?php esc_html_e('Group Description', 'event_espresso'); ?></strong><br />
31 31
         <?php esc_html_e(
32
-            'This is the description for the question group as it will be shown on the registration form. This can be shown to registrants and HTML is allowed.',
33
-            'event_espresso'
34
-        ); ?>
32
+			'This is the description for the question group as it will be shown on the registration form. This can be shown to registrants and HTML is allowed.',
33
+			'event_espresso'
34
+		); ?>
35 35
     </li>
36 36
     <li>
37 37
         <strong><?php esc_html_e('Question Group Order', 'event_espresso'); ?></strong><br />
38 38
         <?php esc_html_e(
39
-            'Question Groups can be sorted by using the drag and drop feature on the Questions Group page. Another way to sort question groups is to adjust their order of application by using this field. A smaller order of application will be shown first. For example, a question group with an order of application of 1 will appear before one that has an order of application of 5.',
40
-            'event_espresso'
41
-        ); ?>
39
+			'Question Groups can be sorted by using the drag and drop feature on the Questions Group page. Another way to sort question groups is to adjust their order of application by using this field. A smaller order of application will be shown first. For example, a question group with an order of application of 1 will appear before one that has an order of application of 5.',
40
+			'event_espresso'
41
+		); ?>
42 42
     </li>
43 43
     <li>
44 44
         <strong><?php esc_html_e('Show Name', 'event_espresso'); ?></strong><br />
@@ -47,29 +47,29 @@  discard block
 block discarded – undo
47 47
     <li>
48 48
         <strong><?php esc_html_e('Show Description', 'event_espresso'); ?></strong><br />
49 49
         <?php esc_html_e(
50
-            'Whether the description for the question group be will displayed on the registration form.',
51
-            'event_espresso'
52
-        ); ?>
50
+			'Whether the description for the question group be will displayed on the registration form.',
51
+			'event_espresso'
52
+		); ?>
53 53
     </li>
54 54
     <li>
55 55
         <strong><?php esc_html_e('Questions that appear in this group', 'event_espresso'); ?></strong><br />
56 56
         <?php esc_html_e(
57
-            'This shows all available custom questions. If checked, then that question will appear with this question group. Questions that appear here can also be sorted using drag and drop.',
58
-            'event_espresso'
59
-        ); ?>
57
+			'This shows all available custom questions. If checked, then that question will appear with this question group. Questions that appear here can also be sorted using drag and drop.',
58
+			'event_espresso'
59
+		); ?>
60 60
     </li>
61 61
 </ul>
62 62
 <p>
63 63
     <strong><?php esc_html_e('Recommendations', 'event_espresso'); ?></strong><br />
64 64
     <?php esc_html_e(
65
-        'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
66
-        'event_espresso'
67
-    ); ?>
65
+		'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
66
+		'event_espresso'
67
+	); ?>
68 68
 </p>
69 69
 <p>
70 70
     <strong><?php esc_html_e('Screen Options', 'event_espresso'); ?></strong><br />
71 71
     <?php esc_html_e(
72
-        'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
73
-        'event_espresso'
74
-    ); ?>
72
+		'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
73
+		'event_espresso'
74
+	); ?>
75 75
 </p>
76 76
\ No newline at end of file
Please login to merge, or discard this patch.
registration_form/help_tabs/registration_form_question_groups.help_tab.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -3,23 +3,23 @@
 block discarded – undo
3 3
 </p>
4 4
 <p>
5 5
     <?php esc_html_e(
6
-        "This page shows all Question Groups that have been created for Event Espresso. Question Groups allow you to create modular registration forms. Each registration form consists of one or more question groups, and these are allocated on a per event basis.",
7
-        'event_espresso'
8
-    ); ?>
6
+		"This page shows all Question Groups that have been created for Event Espresso. Question Groups allow you to create modular registration forms. Each registration form consists of one or more question groups, and these are allocated on a per event basis.",
7
+		'event_espresso'
8
+	); ?>
9 9
 </p>
10 10
 <p>
11 11
     <strong><?php esc_html_e('Recommendations', 'event_espresso'); ?></strong>
12 12
     <br />
13 13
     <?php esc_html_e(
14
-        'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
15
-        'event_espresso'
16
-    ); ?>
14
+		'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
15
+		'event_espresso'
16
+	); ?>
17 17
 </p>
18 18
 <p>
19 19
     <strong><?php esc_html_e('Screen Options', 'event_espresso'); ?></strong>
20 20
     <br />
21 21
     <?php esc_html_e(
22
-        'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
23
-        'event_espresso'
24
-    ); ?>
22
+		'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
23
+		'event_espresso'
24
+	); ?>
25 25
 </p>
26 26
\ No newline at end of file
Please login to merge, or discard this patch.
registration_form/help_tabs/registration_form_edit_question.help_tab.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -8,34 +8,34 @@  discard block
 block discarded – undo
8 8
     <strong><?php esc_html_e('Notice', 'event_espresso'); ?></strong>
9 9
     <br />
10 10
     <?php esc_html_e(
11
-        'System questions may have some options disabled. This is to ensure that your registrations don\'t break from accidental changes.',
12
-        'event_espresso'
13
-    ); ?>
11
+		'System questions may have some options disabled. This is to ensure that your registrations don\'t break from accidental changes.',
12
+		'event_espresso'
13
+	); ?>
14 14
 </p>
15 15
 <ul>
16 16
     <li>
17 17
         <strong><?php esc_html_e('Question Text', 'event_espresso'); ?></strong>
18 18
         <br />
19 19
         <?php esc_html_e(
20
-            'This shows the question as it will be displayed on the registration form. HTML can be used here.',
21
-            'event_espresso'
22
-        ); ?>
20
+			'This shows the question as it will be displayed on the registration form. HTML can be used here.',
21
+			'event_espresso'
22
+		); ?>
23 23
     </li>
24 24
     <li>
25 25
         <strong><?php esc_html_e('Question Label (admin-only)', 'event_espresso'); ?></strong>
26 26
         <br />
27 27
         <?php esc_html_e(
28
-            'This field is only shown to the admin. It is useful for understanding the difference between questions that appear to be similar but are used in various situations. HTML cannot be used.',
29
-            'event_espresso'
30
-        ); ?>
28
+			'This field is only shown to the admin. It is useful for understanding the difference between questions that appear to be similar but are used in various situations. HTML cannot be used.',
29
+			'event_espresso'
30
+		); ?>
31 31
     </li>
32 32
     <li>
33 33
         <strong><?php esc_html_e('Question Order', 'event_espresso'); ?></strong>
34 34
         <br />
35 35
         <?php esc_html_e(
36
-            'Questions are now sorted per question group.  To order the questions edit a question group and you can reorder the questions attached to that group.',
37
-            'event_espresso'
38
-        ); ?>
36
+			'Questions are now sorted per question group.  To order the questions edit a question group and you can reorder the questions attached to that group.',
37
+			'event_espresso'
38
+		); ?>
39 39
     </li>
40 40
     <li>
41 41
         <strong><?php esc_html_e('Admin-Only Question?', 'event_espresso'); ?></strong>
@@ -46,17 +46,17 @@  discard block
 block discarded – undo
46 46
         <strong><?php esc_html_e('Question Type', 'event_espresso'); ?></strong>
47 47
         <br />
48 48
         <?php esc_html_e(
49
-            'This shows the type of question. Available options are Text, Textarea, Checkboxes, Radio Buttons, Dropdown, State/Province Dropdown, Country Dropdown, Date Picker, and HTML Textarea (allowed tags: a, abbr, acronym, b, br, blockquote ,cite, code, del ,em, i, li, ol, p, q, s, strike, strong, ul).',
50
-            'event_espresso'
51
-        ); ?>
49
+			'This shows the type of question. Available options are Text, Textarea, Checkboxes, Radio Buttons, Dropdown, State/Province Dropdown, Country Dropdown, Date Picker, and HTML Textarea (allowed tags: a, abbr, acronym, b, br, blockquote ,cite, code, del ,em, i, li, ol, p, q, s, strike, strong, ul).',
50
+			'event_espresso'
51
+		); ?>
52 52
     </li>
53 53
     <li>
54 54
         <strong><?php esc_html_e('Answer Options (for applicable question types)', 'event_espresso'); ?></strong>
55 55
         <strong>
56 56
             <?php esc_html_e(
57
-                'Values do not allow any HTML, however, descriptions do allow HTML.',
58
-                'event_espresso'
59
-            ); ?>
57
+				'Values do not allow any HTML, however, descriptions do allow HTML.',
58
+				'event_espresso'
59
+			); ?>
60 60
         </strong>
61 61
     </li>
62 62
     <li>
@@ -68,24 +68,24 @@  discard block
 block discarded – undo
68 68
         <strong><?php esc_html_e('Required Text', 'event_espresso'); ?></strong>
69 69
         <br />
70 70
         <?php esc_html_e(
71
-            'This text is displayed when a registrant does not answer a question but is required to do so. The default message will show "this field is required."',
72
-            'event_espresso'
73
-        ); ?>
71
+			'This text is displayed when a registrant does not answer a question but is required to do so. The default message will show "this field is required."',
72
+			'event_espresso'
73
+		); ?>
74 74
     </li>
75 75
 </ul>
76 76
 <p>
77 77
     <strong><?php esc_html_e('Recommendations', 'event_espresso'); ?></strong>
78 78
     <br />
79 79
     <?php esc_html_e(
80
-        'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
81
-        'event_espresso'
82
-    ); ?>
80
+		'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
81
+		'event_espresso'
82
+	); ?>
83 83
 </p>
84 84
 <p>
85 85
     <strong><?php esc_html_e('Screen Options', 'event_espresso'); ?></strong>
86 86
     <br />
87 87
     <?php esc_html_e(
88
-        'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
89
-        'event_espresso'
90
-    ); ?>
88
+		'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
89
+		'event_espresso'
90
+	); ?>
91 91
 </p>
92 92
\ No newline at end of file
Please login to merge, or discard this patch.
help_tabs/registration_form_add_question_group.help_tab.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -8,81 +8,81 @@
 block discarded – undo
8 8
 </p>
9 9
 <p>
10 10
     <?php printf(
11
-        esc_html__('This page allows you to add a new question group for %s.', 'event_espresso'),
12
-        Domain::brandName()
13
-    ); ?>
11
+		esc_html__('This page allows you to add a new question group for %s.', 'event_espresso'),
12
+		Domain::brandName()
13
+	); ?>
14 14
 </p>
15 15
 <ul>
16 16
     <li>
17 17
         <strong><?php esc_html_e('Group Name', 'event_espresso'); ?></strong>
18 18
         <br />
19 19
         <?php esc_html_e(
20
-            'This is the name (title) of the question group as it will be displayed on the registration form. HTML cannot be used.',
21
-            'event_espresso'
22
-        ); ?>
20
+			'This is the name (title) of the question group as it will be displayed on the registration form. HTML cannot be used.',
21
+			'event_espresso'
22
+		); ?>
23 23
     </li>
24 24
     <li>
25 25
         <strong><?php esc_html_e('Group Identifier', 'event_espresso'); ?></strong>
26 26
         <br />
27 27
         <?php esc_html_e(
28
-            'This is a unique name (slug) for this group. It helps you tell the difference between this group and other groups that may appear to be similar. It is not shown to registrants and HTML cannot be used.',
29
-            'event_espresso'
30
-        ); ?>
28
+			'This is a unique name (slug) for this group. It helps you tell the difference between this group and other groups that may appear to be similar. It is not shown to registrants and HTML cannot be used.',
29
+			'event_espresso'
30
+		); ?>
31 31
     </li>
32 32
     <li>
33 33
         <strong><?php esc_html_e('Group Description', 'event_espresso'); ?></strong>
34 34
         <br />
35 35
         <?php esc_html_e(
36
-            'This is the description for the question group as it will be shown on the registration form. This can be shown to registrants and HTML is allowed.',
37
-            'event_espresso'
38
-        ); ?>
36
+			'This is the description for the question group as it will be shown on the registration form. This can be shown to registrants and HTML is allowed.',
37
+			'event_espresso'
38
+		); ?>
39 39
     </li>
40 40
     <li>
41 41
         <strong><?php esc_html_e('Question Group Order', 'event_espresso'); ?></strong>
42 42
         <br />
43 43
         <?php esc_html_e(
44
-            'Question Groups can be sorted by using the drag and drop feature on the Questions Group page. Another way to sort question groups is to adjust their order of application by using this field. A smaller order of application will be shown first. For example, a question group with an order of application of 1 will appear before one that has an order of application of 5.',
45
-            'event_espresso'
46
-        ); ?>
44
+			'Question Groups can be sorted by using the drag and drop feature on the Questions Group page. Another way to sort question groups is to adjust their order of application by using this field. A smaller order of application will be shown first. For example, a question group with an order of application of 1 will appear before one that has an order of application of 5.',
45
+			'event_espresso'
46
+		); ?>
47 47
     </li>
48 48
     <li>
49 49
         <strong><?php esc_html_e('Show Name', 'event_espresso'); ?></strong>
50 50
         <br />
51 51
         <?php esc_html_e(
52
-            'Whether the group name will be displayed on the registration form.',
53
-            'event_espresso'
54
-        ); ?>
52
+			'Whether the group name will be displayed on the registration form.',
53
+			'event_espresso'
54
+		); ?>
55 55
     </li>
56 56
     <li>
57 57
         <strong><?php esc_html_e('Show Description', 'event_espresso'); ?></strong>
58 58
         <br />
59 59
         <?php esc_html_e(
60
-            'Whether the description for the question group be will displayed on the registration form.',
61
-            'event_espresso'
62
-        ); ?>
60
+			'Whether the description for the question group be will displayed on the registration form.',
61
+			'event_espresso'
62
+		); ?>
63 63
     </li>
64 64
     <li>
65 65
         <strong><?php esc_html_e('Questions that appear in this group', 'event_espresso'); ?></strong>
66 66
         <br />
67 67
         <?php esc_html_e(
68
-            'This shows all available custom questions. If checked, then that question will appear with this question group.',
69
-            'event_espresso'
70
-        ); ?>
68
+			'This shows all available custom questions. If checked, then that question will appear with this question group.',
69
+			'event_espresso'
70
+		); ?>
71 71
     </li>
72 72
 </ul>
73 73
 <p>
74 74
     <strong><?php esc_html_e('Recommendations', 'event_espresso'); ?></strong>
75 75
     <br />
76 76
     <?php esc_html_e(
77
-        'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
78
-        'event_espresso'
79
-    ); ?>
77
+		'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
78
+		'event_espresso'
79
+	); ?>
80 80
 </p>
81 81
 <p>
82 82
     <strong><?php esc_html_e('Screen Options', 'event_espresso'); ?></strong>
83 83
     <br />
84 84
     <?php esc_html_e(
85
-        'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
86
-        'event_espresso'
87
-    ); ?>
85
+		'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content.',
86
+		'event_espresso'
87
+	); ?>
88 88
 </p>
89 89
\ No newline at end of file
Please login to merge, or discard this patch.
help_tabs/registration_form_questions_overview.help_tab.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -8,15 +8,15 @@
 block discarded – undo
8 8
     <strong><?php esc_html_e('Recommendations', 'event_espresso'); ?></strong>
9 9
     <br />
10 10
     <?php esc_html_e(
11
-        'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
12
-        'event_espresso'
13
-    ); ?>
11
+		'To learn more about the options on this page, take a look at the different tabs that appear on the left side of the page.',
12
+		'event_espresso'
13
+	); ?>
14 14
 </p>
15 15
 <p>
16 16
     <strong><?php esc_html_e('Screen Options', 'event_espresso'); ?></strong>
17 17
     <br />
18 18
     <?php esc_html_e(
19
-        'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content and even adjust the pagination for questions.',
20
-        'event_espresso'
21
-    ); ?>
19
+		'You can customize the information that is shown on this page by toggling the Screen Options tab. Then you can add or remove checkmarks to hide or show certain content and even adjust the pagination for questions.',
20
+		'event_espresso'
21
+	); ?>
22 22
 </p>
23 23
\ No newline at end of file
Please login to merge, or discard this patch.
admin/extend/registration_form/Extend_Registration_Form_Admin_Page.core.php 1 patch
Indentation   +1432 added lines, -1432 removed lines patch added patch discarded remove patch
@@ -14,1436 +14,1436 @@
 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/');
23
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
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/');
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
-                'metaboxes'     => $this->_default_espresso_metaboxes,
218
-                'require_nonce' => false,
219
-                'qtips'         => array(
220
-                    'EE_Registration_Form_Tips',
221
-                ),
222
-            ),
223
-
224
-            'add_question' => array(
225
-                'nav'           => array(
226
-                    'label'      => esc_html__('Add Question', 'event_espresso'),
227
-                    'order'      => 5,
228
-                    'persistent' => false,
229
-                ),
230
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
231
-                'help_tabs'     => array(
232
-                    'registration_form_add_question_help_tab' => array(
233
-                        'title'    => esc_html__('Add Question', 'event_espresso'),
234
-                        'filename' => 'registration_form_add_question',
235
-                    ),
236
-                ),
237
-                'require_nonce' => false,
238
-            ),
239
-
240
-            'add_question_group' => array(
241
-                'nav'           => array(
242
-                    'label'      => esc_html__('Add Question Group', 'event_espresso'),
243
-                    'order'      => 5,
244
-                    'persistent' => false,
245
-                ),
246
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
247
-                'help_tabs'     => array(
248
-                    'registration_form_add_question_group_help_tab' => array(
249
-                        'title'    => esc_html__('Add Question Group', 'event_espresso'),
250
-                        'filename' => 'registration_form_add_question_group',
251
-                    ),
252
-                ),
253
-                'require_nonce' => false,
254
-            ),
255
-
256
-            'edit_question_group' => array(
257
-                'nav'           => array(
258
-                    'label'      => esc_html__('Edit Question Group', 'event_espresso'),
259
-                    'order'      => 5,
260
-                    'persistent' => false,
261
-                    'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
262
-                        array('question_group_id' => $this->_req_data['question_group_id']),
263
-                        $this->_current_page_view_url
264
-                    ) : $this->_admin_base_url,
265
-                ),
266
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
267
-                'help_tabs'     => array(
268
-                    'registration_form_edit_question_group_help_tab' => array(
269
-                        'title'    => esc_html__('Edit Question Group', 'event_espresso'),
270
-                        'filename' => 'registration_form_edit_question_group',
271
-                    ),
272
-                ),
273
-                'require_nonce' => false,
274
-            ),
275
-
276
-            'view_reg_form_settings' => array(
277
-                'nav'           => array(
278
-                    'label' => esc_html__('Reg Form Settings', 'event_espresso'),
279
-                    'order' => 40,
280
-                ),
281
-                'labels'        => array(
282
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
283
-                ),
284
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
285
-                'help_tabs'     => array(
286
-                    'registration_form_reg_form_settings_help_tab' => array(
287
-                        'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
288
-                        'filename' => 'registration_form_reg_form_settings',
289
-                    ),
290
-                ),
291
-                'require_nonce' => false,
292
-            ),
293
-
294
-        );
295
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
296
-
297
-        // change the list table we're going to use so it's the NEW list table!
298
-        $this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
299
-
300
-
301
-        // additional labels
302
-        $new_labels = array(
303
-            'add_question'          => esc_html__('Add New Question', 'event_espresso'),
304
-            'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
305
-            'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
306
-            'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
307
-            'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
308
-        );
309
-        $this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
310
-    }
311
-
312
-
313
-    /**
314
-     * @return void
315
-     */
316
-    protected function _ajax_hooks()
317
-    {
318
-        add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
319
-    }
320
-
321
-
322
-    /**
323
-     * @return void
324
-     */
325
-    public function load_scripts_styles_question_groups()
326
-    {
327
-        wp_enqueue_script('espresso_ajax_table_sorting');
328
-    }
329
-
330
-
331
-    /**
332
-     * @return void
333
-     */
334
-    public function load_scripts_styles_add_question_group()
335
-    {
336
-        $this->load_scripts_styles_forms();
337
-        $this->load_sortable_question_script();
338
-    }
339
-
340
-
341
-    /**
342
-     * @return void
343
-     */
344
-    public function load_scripts_styles_edit_question_group()
345
-    {
346
-        $this->load_scripts_styles_forms();
347
-        $this->load_sortable_question_script();
348
-    }
349
-
350
-
351
-    /**
352
-     * registers and enqueues script for questions
353
-     *
354
-     * @return void
355
-     */
356
-    public function load_sortable_question_script()
357
-    {
358
-        wp_register_script(
359
-            'ee-question-sortable',
360
-            REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
361
-            array('jquery-ui-sortable'),
362
-            EVENT_ESPRESSO_VERSION,
363
-            true
364
-        );
365
-        wp_enqueue_script('ee-question-sortable');
366
-    }
367
-
368
-
369
-    /**
370
-     * @return void
371
-     */
372
-    protected function _set_list_table_views_default()
373
-    {
374
-        $this->_views = array(
375
-            'all' => array(
376
-                'slug'        => 'all',
377
-                'label'       => esc_html__('View All Questions', 'event_espresso'),
378
-                'count'       => 0,
379
-                'bulk_action' => array(
380
-                    'trash_questions' => esc_html__('Trash', 'event_espresso'),
381
-                ),
382
-            ),
383
-        );
384
-
385
-        if (
386
-            EE_Registry::instance()->CAP->current_user_can(
387
-                'ee_delete_questions',
388
-                'espresso_registration_form_trash_questions'
389
-            )
390
-        ) {
391
-            $this->_views['trash'] = array(
392
-                'slug'        => 'trash',
393
-                'label'       => esc_html__('Trash', 'event_espresso'),
394
-                'count'       => 0,
395
-                'bulk_action' => array(
396
-                    'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
397
-                    'restore_questions' => esc_html__('Restore', 'event_espresso'),
398
-                ),
399
-            );
400
-        }
401
-    }
402
-
403
-
404
-    /**
405
-     * @return void
406
-     */
407
-    protected function _set_list_table_views_question_groups()
408
-    {
409
-        $this->_views = array(
410
-            'all' => array(
411
-                'slug'        => 'all',
412
-                'label'       => esc_html__('All', 'event_espresso'),
413
-                'count'       => 0,
414
-                'bulk_action' => array(
415
-                    'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
416
-                ),
417
-            ),
418
-        );
419
-
420
-        if (
421
-            EE_Registry::instance()->CAP->current_user_can(
422
-                'ee_delete_question_groups',
423
-                'espresso_registration_form_trash_question_groups'
424
-            )
425
-        ) {
426
-            $this->_views['trash'] = array(
427
-                'slug'        => 'trash',
428
-                'label'       => esc_html__('Trash', 'event_espresso'),
429
-                'count'       => 0,
430
-                'bulk_action' => array(
431
-                    'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
432
-                    'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
433
-                ),
434
-            );
435
-        }
436
-    }
437
-
438
-
439
-    /**
440
-     * @return void
441
-     * @throws EE_Error
442
-     * @throws InvalidArgumentException
443
-     * @throws InvalidDataTypeException
444
-     * @throws InvalidInterfaceException
445
-     */
446
-    protected function _questions_overview_list_table()
447
-    {
448
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
449
-            'add_question',
450
-            'add_question',
451
-            array(),
452
-            'add-new-h2'
453
-        );
454
-        parent::_questions_overview_list_table();
455
-    }
456
-
457
-
458
-    /**
459
-     * @return void
460
-     * @throws DomainException
461
-     * @throws EE_Error
462
-     * @throws InvalidArgumentException
463
-     * @throws InvalidDataTypeException
464
-     * @throws InvalidInterfaceException
465
-     */
466
-    protected function _question_groups_overview_list_table()
467
-    {
468
-        $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
469
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
470
-            'add_question_group',
471
-            'add_question_group',
472
-            array(),
473
-            'add-new-h2'
474
-        );
475
-        $this->display_admin_list_table_page_with_sidebar();
476
-    }
477
-
478
-
479
-    /**
480
-     * @return void
481
-     * @throws EE_Error
482
-     * @throws InvalidArgumentException
483
-     * @throws InvalidDataTypeException
484
-     * @throws InvalidInterfaceException
485
-     */
486
-    protected function _delete_question()
487
-    {
488
-        $success = $this->_delete_items($this->_question_model);
489
-        $this->_redirect_after_action(
490
-            $success,
491
-            $this->_question_model->item_name($success),
492
-            'deleted',
493
-            array('action' => 'default', 'status' => 'all')
494
-        );
495
-    }
496
-
497
-
498
-    /**
499
-     * @return void
500
-     * @throws EE_Error
501
-     * @throws InvalidArgumentException
502
-     * @throws InvalidDataTypeException
503
-     * @throws InvalidInterfaceException
504
-     */
505
-    protected function _delete_questions()
506
-    {
507
-        $success = $this->_delete_items($this->_question_model);
508
-        $this->_redirect_after_action(
509
-            $success,
510
-            $this->_question_model->item_name($success),
511
-            'deleted permanently',
512
-            array('action' => 'default', 'status' => 'trash')
513
-        );
514
-    }
515
-
516
-
517
-    /**
518
-     * Performs the deletion of a single or multiple questions or question groups.
519
-     *
520
-     * @param EEM_Soft_Delete_Base $model
521
-     * @return int number of items deleted permanently
522
-     * @throws EE_Error
523
-     * @throws InvalidArgumentException
524
-     * @throws InvalidDataTypeException
525
-     * @throws InvalidInterfaceException
526
-     */
527
-    private function _delete_items(EEM_Soft_Delete_Base $model)
528
-    {
529
-        $success = 0;
530
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
531
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
532
-            // if array has more than one element than success message should be plural
533
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
534
-            // cycle thru bulk action checkboxes
535
-            while (list($ID, $value) = each($this->_req_data['checkbox'])) {
536
-                if (! $this->_delete_item($ID, $model)) {
537
-                    $success = 0;
538
-                }
539
-            }
540
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
541
-            $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
542
-        } elseif (! empty($this->_req_data['QST_ID'])) {
543
-            $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
544
-        } else {
545
-            EE_Error::add_error(
546
-                sprintf(
547
-                    esc_html__(
548
-                        "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.",
549
-                        "event_espresso"
550
-                    )
551
-                ),
552
-                __FILE__,
553
-                __FUNCTION__,
554
-                __LINE__
555
-            );
556
-        }
557
-        return $success;
558
-    }
559
-
560
-
561
-    /**
562
-     * Deletes the specified question (and its associated question options) or question group
563
-     *
564
-     * @param int                  $id
565
-     * @param EEM_Soft_Delete_Base $model
566
-     * @return boolean
567
-     * @throws EE_Error
568
-     * @throws InvalidArgumentException
569
-     * @throws InvalidDataTypeException
570
-     * @throws InvalidInterfaceException
571
-     */
572
-    protected function _delete_item($id, $model)
573
-    {
574
-        if ($model instanceof EEM_Question) {
575
-            EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
576
-        }
577
-        return $model->delete_permanently_by_ID(absint($id));
578
-    }
579
-
580
-
581
-    /******************************    QUESTION GROUPS    ******************************/
582
-
583
-
584
-    /**
585
-     * @param string $type
586
-     * @return void
587
-     * @throws DomainException
588
-     * @throws EE_Error
589
-     * @throws InvalidArgumentException
590
-     * @throws InvalidDataTypeException
591
-     * @throws InvalidInterfaceException
592
-     */
593
-    protected function _edit_question_group($type = 'add')
594
-    {
595
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
596
-        $ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
597
-            ? absint($this->_req_data['QSG_ID'])
598
-            : false;
599
-
600
-        switch ($this->_req_action) {
601
-            case 'add_question_group':
602
-                $this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
603
-                break;
604
-            case 'edit_question_group':
605
-                $this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
606
-                break;
607
-            default:
608
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
609
-        }
610
-        // add ID to title if editing
611
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
612
-        if ($ID) {
613
-            /** @var EE_Question_Group $questionGroup */
614
-            $questionGroup = $this->_question_group_model->get_one_by_ID($ID);
615
-            $additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
616
-            $this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
617
-        } else {
618
-            /** @var EE_Question_Group $questionGroup */
619
-            $questionGroup = EEM_Question_Group::instance()->create_default_object();
620
-            $questionGroup->set_order_to_latest();
621
-            $this->_set_add_edit_form_tags('insert_question_group');
622
-        }
623
-        $this->_template_args['values'] = $this->_yes_no_values;
624
-        $this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
625
-        $this->_template_args['QSG_ID'] = $ID ? $ID : true;
626
-        $this->_template_args['question_group'] = $questionGroup;
627
-
628
-        $redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
629
-        $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
630
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
631
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
632
-            $this->_template_args,
633
-            true
634
-        );
635
-
636
-        // the details template wrapper
637
-        $this->display_admin_page_with_sidebar();
638
-    }
639
-
640
-
641
-    /**
642
-     * @return void
643
-     * @throws EE_Error
644
-     * @throws InvalidArgumentException
645
-     * @throws InvalidDataTypeException
646
-     * @throws InvalidInterfaceException
647
-     */
648
-    protected function _delete_question_groups()
649
-    {
650
-        $success = $this->_delete_items($this->_question_group_model);
651
-        $this->_redirect_after_action(
652
-            $success,
653
-            $this->_question_group_model->item_name($success),
654
-            'deleted permanently',
655
-            array('action' => 'question_groups', 'status' => 'trash')
656
-        );
657
-    }
658
-
659
-
660
-    /**
661
-     * @param bool $new_question_group
662
-     * @throws EE_Error
663
-     * @throws InvalidArgumentException
664
-     * @throws InvalidDataTypeException
665
-     * @throws InvalidInterfaceException
666
-     */
667
-    protected function _insert_or_update_question_group($new_question_group = true)
668
-    {
669
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
670
-        $set_column_values = $this->_set_column_values_for($this->_question_group_model);
671
-        if ($new_question_group) {
672
-            // make sure identifier is unique
673
-            $identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
674
-            $identifier_exists = ! empty($identifier_value)
675
-                ? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
676
-                : false;
677
-            if ($identifier_exists) {
678
-                $set_column_values['QSG_identifier'] .= uniqid('id', true);
679
-            }
680
-            $QSG_ID = $this->_question_group_model->insert($set_column_values);
681
-            $success = $QSG_ID ? 1 : 0;
682
-            if ($success === 0) {
683
-                EE_Error::add_error(
684
-                    esc_html__('Something went wrong saving the question group.', 'event_espresso'),
685
-                    __FILE__,
686
-                    __FUNCTION__,
687
-                    __LINE__
688
-                );
689
-                $this->_redirect_after_action(
690
-                    false,
691
-                    '',
692
-                    '',
693
-                    array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
694
-                    true
695
-                );
696
-            }
697
-        } else {
698
-            $QSG_ID = absint($this->_req_data['QSG_ID']);
699
-            unset($set_column_values['QSG_ID']);
700
-            $success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
701
-        }
702
-
703
-        $phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
704
-            EEM_Attendee::system_question_phone
705
-        );
706
-        // update the existing related questions
707
-        // BUT FIRST...  delete the phone question from the Question_Group_Question
708
-        // if it is being added to this question group (therefore removed from the existing group)
709
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
710
-            // delete where QST ID = system phone question ID and Question Group ID is NOT this group
711
-            EEM_Question_Group_Question::instance()->delete(
712
-                array(
713
-                    array(
714
-                        'QST_ID' => $phone_question_id,
715
-                        'QSG_ID' => array('!=', $QSG_ID),
716
-                    ),
717
-                )
718
-            );
719
-        }
720
-        /** @type EE_Question_Group $question_group */
721
-        $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
722
-        $questions = $question_group->questions();
723
-        // make sure system phone question is added to list of questions for this group
724
-        if (! isset($questions[ $phone_question_id ])) {
725
-            $questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
726
-        }
727
-
728
-        foreach ($questions as $question_ID => $question) {
729
-            // first we always check for order.
730
-            if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
731
-                // update question order
732
-                $question_group->update_question_order(
733
-                    $question_ID,
734
-                    $this->_req_data['question_orders'][ $question_ID ]
735
-                );
736
-            }
737
-
738
-            // then we always check if adding or removing.
739
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
740
-                $question_group->add_question($question_ID);
741
-            } else {
742
-                // not found, remove it (but only if not a system question for the personal group
743
-                // with the exception of lname system question - we allow removal of it)
744
-                if (
745
-                    in_array(
746
-                        $question->system_ID(),
747
-                        EEM_Question::instance()->required_system_questions_in_system_question_group(
748
-                            $question_group->system_group()
749
-                        )
750
-                    )
751
-                ) {
752
-                    continue;
753
-                } else {
754
-                    $question_group->remove_question($question_ID);
755
-                }
756
-            }
757
-        }
758
-        // save new related questions
759
-        if (isset($this->_req_data['questions'])) {
760
-            foreach ($this->_req_data['questions'] as $QST_ID) {
761
-                $question_group->add_question($QST_ID);
762
-                if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
763
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
764
-                }
765
-            }
766
-        }
767
-
768
-        if ($success !== false) {
769
-            $msg = $new_question_group
770
-                ? sprintf(
771
-                    esc_html__('The %s has been created', 'event_espresso'),
772
-                    $this->_question_group_model->item_name()
773
-                )
774
-                : sprintf(
775
-                    esc_html__(
776
-                        'The %s has been updated',
777
-                        'event_espresso'
778
-                    ),
779
-                    $this->_question_group_model->item_name()
780
-                );
781
-            EE_Error::add_success($msg);
782
-        }
783
-        $this->_redirect_after_action(
784
-            false,
785
-            '',
786
-            '',
787
-            array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
788
-            true
789
-        );
790
-    }
791
-
792
-
793
-    /**
794
-     * duplicates a question and all its question options and redirects to the new question.
795
-     *
796
-     * @return void
797
-     * @throws EE_Error
798
-     * @throws InvalidArgumentException
799
-     * @throws ReflectionException
800
-     * @throws InvalidDataTypeException
801
-     * @throws InvalidInterfaceException
802
-     */
803
-    public function _duplicate_question()
804
-    {
805
-        $question_ID = (int) $this->_req_data['QST_ID'];
806
-        $question = EEM_Question::instance()->get_one_by_ID($question_ID);
807
-        if ($question instanceof EE_Question) {
808
-            $new_question = $question->duplicate();
809
-            if ($new_question instanceof EE_Question) {
810
-                $this->_redirect_after_action(
811
-                    true,
812
-                    esc_html__('Question', 'event_espresso'),
813
-                    esc_html__('Duplicated', 'event_espresso'),
814
-                    array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
815
-                    true
816
-                );
817
-            } else {
818
-                global $wpdb;
819
-                EE_Error::add_error(
820
-                    sprintf(
821
-                        esc_html__(
822
-                            'Could not duplicate question with ID %1$d because: %2$s',
823
-                            'event_espresso'
824
-                        ),
825
-                        $question_ID,
826
-                        $wpdb->last_error
827
-                    ),
828
-                    __FILE__,
829
-                    __FUNCTION__,
830
-                    __LINE__
831
-                );
832
-                $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
833
-            }
834
-        } else {
835
-            EE_Error::add_error(
836
-                sprintf(
837
-                    esc_html__(
838
-                        'Could not duplicate question with ID %d because it didn\'t exist!',
839
-                        'event_espresso'
840
-                    ),
841
-                    $question_ID
842
-                ),
843
-                __FILE__,
844
-                __FUNCTION__,
845
-                __LINE__
846
-            );
847
-            $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
848
-        }
849
-    }
850
-
851
-
852
-    /**
853
-     * @param bool $trash
854
-     * @throws EE_Error
855
-     */
856
-    protected function _trash_or_restore_question_groups($trash = true)
857
-    {
858
-        $this->_trash_or_restore_items($this->_question_group_model, $trash);
859
-    }
860
-
861
-
862
-    /**
863
-     *_trash_question
864
-     *
865
-     * @return void
866
-     * @throws EE_Error
867
-     */
868
-    protected function _trash_question()
869
-    {
870
-        $success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
871
-        $query_args = array('action' => 'default', 'status' => 'all');
872
-        $this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
873
-    }
874
-
875
-
876
-    /**
877
-     * @param bool $trash
878
-     * @throws EE_Error
879
-     */
880
-    protected function _trash_or_restore_questions($trash = true)
881
-    {
882
-        $this->_trash_or_restore_items($this->_question_model, $trash);
883
-    }
884
-
885
-
886
-    /**
887
-     * Internally used to delete or restore items, using the request data. Meant to be
888
-     * flexible between question or question groups
889
-     *
890
-     * @param EEM_Soft_Delete_Base $model
891
-     * @param boolean              $trash whether to trash or restore
892
-     * @throws EE_Error
893
-     */
894
-    private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
895
-    {
896
-
897
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
898
-
899
-        $success = 1;
900
-        // Checkboxes
901
-        // echo "trash $trash";
902
-        // var_dump($this->_req_data['checkbox']);die;
903
-        if (isset($this->_req_data['checkbox'])) {
904
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
905
-                // if array has more than one element than success message should be plural
906
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
907
-                // cycle thru bulk action checkboxes
908
-                while (list($ID, $value) = each($this->_req_data['checkbox'])) {
909
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
910
-                        $success = 0;
911
-                    }
912
-                }
913
-            } else {
914
-                // grab single id and delete
915
-                $ID = absint($this->_req_data['checkbox']);
916
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
917
-                    $success = 0;
918
-                }
919
-            }
920
-        } else {
921
-            // delete via trash link
922
-            // grab single id and delete
923
-            $ID = absint($this->_req_data[ $model->primary_key_name() ]);
924
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
925
-                $success = 0;
926
-            }
927
-        }
928
-
929
-
930
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
931
-        // echo "action :$action";
932
-        // $action = 'questions' ? 'default' : $action;
933
-        if ($trash) {
934
-            $action_desc = 'trashed';
935
-            $status = 'trash';
936
-        } else {
937
-            $action_desc = 'restored';
938
-            $status = 'all';
939
-        }
940
-        $this->_redirect_after_action(
941
-            $success,
942
-            $model->item_name($success),
943
-            $action_desc,
944
-            array('action' => $action, 'status' => $status)
945
-        );
946
-    }
947
-
948
-
949
-    /**
950
-     * @param            $per_page
951
-     * @param int        $current_page
952
-     * @param bool|false $count
953
-     * @return EE_Soft_Delete_Base_Class[]|int
954
-     * @throws EE_Error
955
-     * @throws InvalidArgumentException
956
-     * @throws InvalidDataTypeException
957
-     * @throws InvalidInterfaceException
958
-     */
959
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
960
-    {
961
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
962
-
963
-        if ($count) {
964
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
965
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
966
-            $results = $this->_question_model->count_deleted($where);
967
-        } else {
968
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
969
-            $results = $this->_question_model->get_all_deleted($query_params);
970
-        }
971
-        return $results;
972
-    }
973
-
974
-
975
-    /**
976
-     * @param            $per_page
977
-     * @param int        $current_page
978
-     * @param bool|false $count
979
-     * @return EE_Soft_Delete_Base_Class[]|int
980
-     * @throws EE_Error
981
-     * @throws InvalidArgumentException
982
-     * @throws InvalidDataTypeException
983
-     * @throws InvalidInterfaceException
984
-     */
985
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
986
-    {
987
-        $questionGroupModel = EEM_Question_Group::instance();
988
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
989
-        if ($count) {
990
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
991
-            $results = $questionGroupModel->count($where);
992
-        } else {
993
-            $results = $questionGroupModel->get_all($query_params);
994
-        }
995
-        return $results;
996
-    }
997
-
998
-
999
-    /**
1000
-     * @param      $per_page
1001
-     * @param int  $current_page
1002
-     * @param bool $count
1003
-     * @return EE_Soft_Delete_Base_Class[]|int
1004
-     * @throws EE_Error
1005
-     * @throws InvalidArgumentException
1006
-     * @throws InvalidDataTypeException
1007
-     * @throws InvalidInterfaceException
1008
-     */
1009
-    public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1010
-    {
1011
-        $questionGroupModel = EEM_Question_Group::instance();
1012
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1013
-        if ($count) {
1014
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
1015
-            $query_params['limit'] = null;
1016
-            $results = $questionGroupModel->count_deleted($where);
1017
-        } else {
1018
-            $results = $questionGroupModel->get_all_deleted($query_params);
1019
-        }
1020
-        return $results;
1021
-    }
1022
-
1023
-
1024
-    /**
1025
-     * method for performing updates to question order
1026
-     *
1027
-     * @return void results array
1028
-     * @throws EE_Error
1029
-     * @throws InvalidArgumentException
1030
-     * @throws InvalidDataTypeException
1031
-     * @throws InvalidInterfaceException
1032
-     */
1033
-    public function update_question_group_order()
1034
-    {
1035
-
1036
-        $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1037
-
1038
-        // grab our row IDs
1039
-        $row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1040
-            ? explode(',', rtrim($this->_req_data['row_ids'], ','))
1041
-            : array();
1042
-
1043
-        $perpage = ! empty($this->_req_data['perpage'])
1044
-            ? (int) $this->_req_data['perpage']
1045
-            : null;
1046
-        $curpage = ! empty($this->_req_data['curpage'])
1047
-            ? (int) $this->_req_data['curpage']
1048
-            : null;
1049
-
1050
-        if (! empty($row_ids)) {
1051
-            // figure out where we start the row_id count at for the current page.
1052
-            $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1053
-
1054
-            $row_count = count($row_ids);
1055
-            for ($i = 0; $i < $row_count; $i++) {
1056
-                // Update the questions when re-ordering
1057
-                $updated = EEM_Question_Group::instance()->update(
1058
-                    array('QSG_order' => $qsgcount),
1059
-                    array(array('QSG_ID' => $row_ids[ $i ]))
1060
-                );
1061
-                if ($updated === false) {
1062
-                    $success = false;
1063
-                }
1064
-                $qsgcount++;
1065
-            }
1066
-        } else {
1067
-            $success = false;
1068
-        }
1069
-
1070
-        $errors = ! $success
1071
-            ? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1072
-            : false;
1073
-
1074
-        echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1075
-        die();
1076
-    }
1077
-
1078
-
1079
-
1080
-    /***************************************       REGISTRATION SETTINGS       ***************************************/
1081
-
1082
-
1083
-    /**
1084
-     * @throws DomainException
1085
-     * @throws EE_Error
1086
-     * @throws InvalidArgumentException
1087
-     * @throws InvalidDataTypeException
1088
-     * @throws InvalidInterfaceException
1089
-     */
1090
-    protected function _reg_form_settings()
1091
-    {
1092
-        $this->_template_args['values'] = $this->_yes_no_values;
1093
-        add_action(
1094
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1095
-            array($this, 'email_validation_settings_form'),
1096
-            2
1097
-        );
1098
-        add_action(
1099
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1100
-            array($this, 'copy_attendee_info_settings_form'),
1101
-            4
1102
-        );
1103
-        $this->_template_args = (array) apply_filters(
1104
-            'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1105
-            $this->_template_args
1106
-        );
1107
-        $this->_set_add_edit_form_tags('update_reg_form_settings');
1108
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
1109
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1110
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1111
-            $this->_template_args,
1112
-            true
1113
-        );
1114
-        $this->display_admin_page_with_sidebar();
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     * @return void
1120
-     * @throws EE_Error
1121
-     * @throws InvalidArgumentException
1122
-     * @throws ReflectionException
1123
-     * @throws InvalidDataTypeException
1124
-     * @throws InvalidInterfaceException
1125
-     */
1126
-    protected function _update_reg_form_settings()
1127
-    {
1128
-        EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1129
-            EE_Registry::instance()->CFG->registration
1130
-        );
1131
-        EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1132
-            EE_Registry::instance()->CFG->registration
1133
-        );
1134
-        EE_Registry::instance()->CFG->registration = apply_filters(
1135
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1136
-            EE_Registry::instance()->CFG->registration
1137
-        );
1138
-        $success = $this->_update_espresso_configuration(
1139
-            esc_html__('Registration Form Options', 'event_espresso'),
1140
-            EE_Registry::instance()->CFG,
1141
-            __FILE__,
1142
-            __FUNCTION__,
1143
-            __LINE__
1144
-        );
1145
-        $this->_redirect_after_action(
1146
-            $success,
1147
-            esc_html__('Registration Form Options', 'event_espresso'),
1148
-            'updated',
1149
-            array('action' => 'view_reg_form_settings')
1150
-        );
1151
-    }
1152
-
1153
-
1154
-    /**
1155
-     * @return void
1156
-     * @throws EE_Error
1157
-     * @throws InvalidArgumentException
1158
-     * @throws InvalidDataTypeException
1159
-     * @throws InvalidInterfaceException
1160
-     */
1161
-    public function copy_attendee_info_settings_form()
1162
-    {
1163
-        echo $this->_copy_attendee_info_settings_form()->get_html();
1164
-    }
1165
-
1166
-    /**
1167
-     * _copy_attendee_info_settings_form
1168
-     *
1169
-     * @access protected
1170
-     * @return EE_Form_Section_Proper
1171
-     * @throws \EE_Error
1172
-     */
1173
-    protected function _copy_attendee_info_settings_form()
1174
-    {
1175
-        return new EE_Form_Section_Proper(
1176
-            array(
1177
-                'name'            => 'copy_attendee_info_settings',
1178
-                'html_id'         => 'copy_attendee_info_settings',
1179
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1180
-                'subsections'     => apply_filters(
1181
-                    'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1182
-                    array(
1183
-                        'copy_attendee_info_hdr'   => new EE_Form_Section_HTML(
1184
-                            EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1185
-                        ),
1186
-                        'copy_attendee_info' => new EE_Yes_No_Input(
1187
-                            array(
1188
-                                'html_label_text' => esc_html__(
1189
-                                    'Allow copy #1 attendee info to extra attendees?',
1190
-                                    'event_espresso'
1191
-                                ),
1192
-                                'html_help_text'  => esc_html__(
1193
-                                    'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1194
-                                    'event_espresso'
1195
-                                ),
1196
-                                'default'         => EE_Registry::instance()->CFG->registration->copyAttendeeInfo(),
1197
-                                'required'        => false,
1198
-                                'display_html_label_text' => false,
1199
-                            )
1200
-                        ),
1201
-                    )
1202
-                ),
1203
-            )
1204
-        );
1205
-    }
1206
-
1207
-    /**
1208
-     * @param EE_Registration_Config $EE_Registration_Config
1209
-     * @return EE_Registration_Config
1210
-     * @throws EE_Error
1211
-     * @throws InvalidArgumentException
1212
-     * @throws ReflectionException
1213
-     * @throws InvalidDataTypeException
1214
-     * @throws InvalidInterfaceException
1215
-     */
1216
-    public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1217
-    {
1218
-        $prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1219
-        try {
1220
-            $copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1221
-            // if not displaying a form, then check for form submission
1222
-            if ($copy_attendee_info_settings_form->was_submitted()) {
1223
-                // capture form data
1224
-                $copy_attendee_info_settings_form->receive_form_submission();
1225
-                // validate form data
1226
-                if ($copy_attendee_info_settings_form->is_valid()) {
1227
-                    // grab validated data from form
1228
-                    $valid_data = $copy_attendee_info_settings_form->valid_data();
1229
-                    if (isset($valid_data['copy_attendee_info'])) {
1230
-                        $EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1231
-                    } else {
1232
-                        EE_Error::add_error(
1233
-                            esc_html__(
1234
-                                'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1235
-                                'event_espresso'
1236
-                            ),
1237
-                            __FILE__,
1238
-                            __FUNCTION__,
1239
-                            __LINE__
1240
-                        );
1241
-                    }
1242
-                } else {
1243
-                    if ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1244
-                        EE_Error::add_error(
1245
-                            $copy_attendee_info_settings_form->submission_error_message(),
1246
-                            __FILE__,
1247
-                            __FUNCTION__,
1248
-                            __LINE__
1249
-                        );
1250
-                    }
1251
-                }
1252
-            }
1253
-        } catch (EE_Error $e) {
1254
-            $e->get_error();
1255
-        }
1256
-        return $EE_Registration_Config;
1257
-    }
1258
-
1259
-
1260
-    /**
1261
-     * @return void
1262
-     * @throws EE_Error
1263
-     * @throws InvalidArgumentException
1264
-     * @throws InvalidDataTypeException
1265
-     * @throws InvalidInterfaceException
1266
-     */
1267
-    public function email_validation_settings_form()
1268
-    {
1269
-        echo $this->_email_validation_settings_form()->get_html();
1270
-    }
1271
-
1272
-
1273
-    /**
1274
-     * _email_validation_settings_form
1275
-     *
1276
-     * @access protected
1277
-     * @return EE_Form_Section_Proper
1278
-     * @throws \EE_Error
1279
-     */
1280
-    protected function _email_validation_settings_form()
1281
-    {
1282
-        return new EE_Form_Section_Proper(
1283
-            array(
1284
-                'name'            => 'email_validation_settings',
1285
-                'html_id'         => 'email_validation_settings',
1286
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1287
-                'subsections'     => apply_filters(
1288
-                    'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1289
-                    array(
1290
-                        'email_validation_hdr'   => new EE_Form_Section_HTML(
1291
-                            EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1292
-                        ),
1293
-                        'email_validation_level' => new EE_Select_Input(
1294
-                            array(
1295
-                                'basic'      => esc_html__('Basic', 'event_espresso'),
1296
-                                'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1297
-                                'i18n'       => esc_html__('International', 'event_espresso'),
1298
-                                'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1299
-                            ),
1300
-                            array(
1301
-                                'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1302
-                                                     . EEH_Template::get_help_tab_link('email_validation_info'),
1303
-                                'html_help_text'  => esc_html__(
1304
-                                    '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.',
1305
-                                    'event_espresso'
1306
-                                ),
1307
-                                'default'         => isset(
1308
-                                    EE_Registry::instance()->CFG->registration->email_validation_level
1309
-                                )
1310
-                                    ? EE_Registry::instance()->CFG->registration->email_validation_level
1311
-                                    : 'wp_default',
1312
-                                'required'        => false,
1313
-                            )
1314
-                        ),
1315
-                    )
1316
-                ),
1317
-            )
1318
-        );
1319
-    }
1320
-
1321
-
1322
-    /**
1323
-     * @param EE_Registration_Config $EE_Registration_Config
1324
-     * @return EE_Registration_Config
1325
-     * @throws EE_Error
1326
-     * @throws InvalidArgumentException
1327
-     * @throws ReflectionException
1328
-     * @throws InvalidDataTypeException
1329
-     * @throws InvalidInterfaceException
1330
-     */
1331
-    public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1332
-    {
1333
-        $prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1334
-        try {
1335
-            $email_validation_settings_form = $this->_email_validation_settings_form();
1336
-            // if not displaying a form, then check for form submission
1337
-            if ($email_validation_settings_form->was_submitted()) {
1338
-                // capture form data
1339
-                $email_validation_settings_form->receive_form_submission();
1340
-                // validate form data
1341
-                if ($email_validation_settings_form->is_valid()) {
1342
-                    // grab validated data from form
1343
-                    $valid_data = $email_validation_settings_form->valid_data();
1344
-                    if (isset($valid_data['email_validation_level'])) {
1345
-                        $email_validation_level = $valid_data['email_validation_level'];
1346
-                        // now if they want to use international email addresses
1347
-                        if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1348
-                            // in case we need to reset their email validation level,
1349
-                            // make sure that the previous value wasn't already set to one of the i18n options.
1350
-                            if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1351
-                                // if so, then reset it back to "basic" since that is the only other option that,
1352
-                                // despite offering poor validation, supports i18n email addresses
1353
-                                $prev_email_validation_level = 'basic';
1354
-                            }
1355
-                            // confirm our i18n email validation will work on the server
1356
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1357
-                                // or reset email validation level to previous value
1358
-                                $email_validation_level = $prev_email_validation_level;
1359
-                            }
1360
-                        }
1361
-                        $EE_Registration_Config->email_validation_level = $email_validation_level;
1362
-                    } else {
1363
-                        EE_Error::add_error(
1364
-                            esc_html__(
1365
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1366
-                                'event_espresso'
1367
-                            ),
1368
-                            __FILE__,
1369
-                            __FUNCTION__,
1370
-                            __LINE__
1371
-                        );
1372
-                    }
1373
-                } else {
1374
-                    if ($email_validation_settings_form->submission_error_message() !== '') {
1375
-                        EE_Error::add_error(
1376
-                            $email_validation_settings_form->submission_error_message(),
1377
-                            __FILE__,
1378
-                            __FUNCTION__,
1379
-                            __LINE__
1380
-                        );
1381
-                    }
1382
-                }
1383
-            }
1384
-        } catch (EE_Error $e) {
1385
-            $e->get_error();
1386
-        }
1387
-        return $EE_Registration_Config;
1388
-    }
1389
-
1390
-
1391
-    /**
1392
-     * confirms that the server's PHP version has the PCRE module enabled,
1393
-     * and that the PCRE version works with our i18n email validation
1394
-     *
1395
-     * @param EE_Registration_Config $EE_Registration_Config
1396
-     * @param string                 $email_validation_level
1397
-     * @return bool
1398
-     */
1399
-    private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1400
-    {
1401
-        // first check that PCRE is enabled
1402
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1403
-            EE_Error::add_error(
1404
-                sprintf(
1405
-                    esc_html__(
1406
-                        '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.',
1407
-                        'event_espresso'
1408
-                    ),
1409
-                    '<br />'
1410
-                ),
1411
-                __FILE__,
1412
-                __FUNCTION__,
1413
-                __LINE__
1414
-            );
1415
-            return false;
1416
-        } else {
1417
-            // PCRE support is enabled, but let's still
1418
-            // perform a test to see if the server will support it.
1419
-            // but first, save the updated validation level to the config,
1420
-            // so that the validation strategy picks it up.
1421
-            // this will get bumped back down if it doesn't work
1422
-            $EE_Registration_Config->email_validation_level = $email_validation_level;
1423
-            try {
1424
-                $email_validator = new EE_Email_Validation_Strategy();
1425
-                $i18n_email_address = apply_filters(
1426
-                    'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1427
-                    'jägerjü[email protected]'
1428
-                );
1429
-                $email_validator->validate($i18n_email_address);
1430
-            } catch (Exception $e) {
1431
-                EE_Error::add_error(
1432
-                    sprintf(
1433
-                        esc_html__(
1434
-                            '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',
1435
-                            'event_espresso'
1436
-                        ),
1437
-                        '<br />',
1438
-                        '<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1439
-                    ),
1440
-                    __FILE__,
1441
-                    __FUNCTION__,
1442
-                    __LINE__
1443
-                );
1444
-                return false;
1445
-            }
1446
-        }
1447
-        return true;
1448
-    }
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/');
23
+		define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
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/');
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
+				'metaboxes'     => $this->_default_espresso_metaboxes,
218
+				'require_nonce' => false,
219
+				'qtips'         => array(
220
+					'EE_Registration_Form_Tips',
221
+				),
222
+			),
223
+
224
+			'add_question' => array(
225
+				'nav'           => array(
226
+					'label'      => esc_html__('Add Question', 'event_espresso'),
227
+					'order'      => 5,
228
+					'persistent' => false,
229
+				),
230
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
231
+				'help_tabs'     => array(
232
+					'registration_form_add_question_help_tab' => array(
233
+						'title'    => esc_html__('Add Question', 'event_espresso'),
234
+						'filename' => 'registration_form_add_question',
235
+					),
236
+				),
237
+				'require_nonce' => false,
238
+			),
239
+
240
+			'add_question_group' => array(
241
+				'nav'           => array(
242
+					'label'      => esc_html__('Add Question Group', 'event_espresso'),
243
+					'order'      => 5,
244
+					'persistent' => false,
245
+				),
246
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
247
+				'help_tabs'     => array(
248
+					'registration_form_add_question_group_help_tab' => array(
249
+						'title'    => esc_html__('Add Question Group', 'event_espresso'),
250
+						'filename' => 'registration_form_add_question_group',
251
+					),
252
+				),
253
+				'require_nonce' => false,
254
+			),
255
+
256
+			'edit_question_group' => array(
257
+				'nav'           => array(
258
+					'label'      => esc_html__('Edit Question Group', 'event_espresso'),
259
+					'order'      => 5,
260
+					'persistent' => false,
261
+					'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
262
+						array('question_group_id' => $this->_req_data['question_group_id']),
263
+						$this->_current_page_view_url
264
+					) : $this->_admin_base_url,
265
+				),
266
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
267
+				'help_tabs'     => array(
268
+					'registration_form_edit_question_group_help_tab' => array(
269
+						'title'    => esc_html__('Edit Question Group', 'event_espresso'),
270
+						'filename' => 'registration_form_edit_question_group',
271
+					),
272
+				),
273
+				'require_nonce' => false,
274
+			),
275
+
276
+			'view_reg_form_settings' => array(
277
+				'nav'           => array(
278
+					'label' => esc_html__('Reg Form Settings', 'event_espresso'),
279
+					'order' => 40,
280
+				),
281
+				'labels'        => array(
282
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
283
+				),
284
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
285
+				'help_tabs'     => array(
286
+					'registration_form_reg_form_settings_help_tab' => array(
287
+						'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
288
+						'filename' => 'registration_form_reg_form_settings',
289
+					),
290
+				),
291
+				'require_nonce' => false,
292
+			),
293
+
294
+		);
295
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
296
+
297
+		// change the list table we're going to use so it's the NEW list table!
298
+		$this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
299
+
300
+
301
+		// additional labels
302
+		$new_labels = array(
303
+			'add_question'          => esc_html__('Add New Question', 'event_espresso'),
304
+			'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
305
+			'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
306
+			'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
307
+			'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
308
+		);
309
+		$this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
310
+	}
311
+
312
+
313
+	/**
314
+	 * @return void
315
+	 */
316
+	protected function _ajax_hooks()
317
+	{
318
+		add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
319
+	}
320
+
321
+
322
+	/**
323
+	 * @return void
324
+	 */
325
+	public function load_scripts_styles_question_groups()
326
+	{
327
+		wp_enqueue_script('espresso_ajax_table_sorting');
328
+	}
329
+
330
+
331
+	/**
332
+	 * @return void
333
+	 */
334
+	public function load_scripts_styles_add_question_group()
335
+	{
336
+		$this->load_scripts_styles_forms();
337
+		$this->load_sortable_question_script();
338
+	}
339
+
340
+
341
+	/**
342
+	 * @return void
343
+	 */
344
+	public function load_scripts_styles_edit_question_group()
345
+	{
346
+		$this->load_scripts_styles_forms();
347
+		$this->load_sortable_question_script();
348
+	}
349
+
350
+
351
+	/**
352
+	 * registers and enqueues script for questions
353
+	 *
354
+	 * @return void
355
+	 */
356
+	public function load_sortable_question_script()
357
+	{
358
+		wp_register_script(
359
+			'ee-question-sortable',
360
+			REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
361
+			array('jquery-ui-sortable'),
362
+			EVENT_ESPRESSO_VERSION,
363
+			true
364
+		);
365
+		wp_enqueue_script('ee-question-sortable');
366
+	}
367
+
368
+
369
+	/**
370
+	 * @return void
371
+	 */
372
+	protected function _set_list_table_views_default()
373
+	{
374
+		$this->_views = array(
375
+			'all' => array(
376
+				'slug'        => 'all',
377
+				'label'       => esc_html__('View All Questions', 'event_espresso'),
378
+				'count'       => 0,
379
+				'bulk_action' => array(
380
+					'trash_questions' => esc_html__('Trash', 'event_espresso'),
381
+				),
382
+			),
383
+		);
384
+
385
+		if (
386
+			EE_Registry::instance()->CAP->current_user_can(
387
+				'ee_delete_questions',
388
+				'espresso_registration_form_trash_questions'
389
+			)
390
+		) {
391
+			$this->_views['trash'] = array(
392
+				'slug'        => 'trash',
393
+				'label'       => esc_html__('Trash', 'event_espresso'),
394
+				'count'       => 0,
395
+				'bulk_action' => array(
396
+					'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
397
+					'restore_questions' => esc_html__('Restore', 'event_espresso'),
398
+				),
399
+			);
400
+		}
401
+	}
402
+
403
+
404
+	/**
405
+	 * @return void
406
+	 */
407
+	protected function _set_list_table_views_question_groups()
408
+	{
409
+		$this->_views = array(
410
+			'all' => array(
411
+				'slug'        => 'all',
412
+				'label'       => esc_html__('All', 'event_espresso'),
413
+				'count'       => 0,
414
+				'bulk_action' => array(
415
+					'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
416
+				),
417
+			),
418
+		);
419
+
420
+		if (
421
+			EE_Registry::instance()->CAP->current_user_can(
422
+				'ee_delete_question_groups',
423
+				'espresso_registration_form_trash_question_groups'
424
+			)
425
+		) {
426
+			$this->_views['trash'] = array(
427
+				'slug'        => 'trash',
428
+				'label'       => esc_html__('Trash', 'event_espresso'),
429
+				'count'       => 0,
430
+				'bulk_action' => array(
431
+					'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
432
+					'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
433
+				),
434
+			);
435
+		}
436
+	}
437
+
438
+
439
+	/**
440
+	 * @return void
441
+	 * @throws EE_Error
442
+	 * @throws InvalidArgumentException
443
+	 * @throws InvalidDataTypeException
444
+	 * @throws InvalidInterfaceException
445
+	 */
446
+	protected function _questions_overview_list_table()
447
+	{
448
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
449
+			'add_question',
450
+			'add_question',
451
+			array(),
452
+			'add-new-h2'
453
+		);
454
+		parent::_questions_overview_list_table();
455
+	}
456
+
457
+
458
+	/**
459
+	 * @return void
460
+	 * @throws DomainException
461
+	 * @throws EE_Error
462
+	 * @throws InvalidArgumentException
463
+	 * @throws InvalidDataTypeException
464
+	 * @throws InvalidInterfaceException
465
+	 */
466
+	protected function _question_groups_overview_list_table()
467
+	{
468
+		$this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
469
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
470
+			'add_question_group',
471
+			'add_question_group',
472
+			array(),
473
+			'add-new-h2'
474
+		);
475
+		$this->display_admin_list_table_page_with_sidebar();
476
+	}
477
+
478
+
479
+	/**
480
+	 * @return void
481
+	 * @throws EE_Error
482
+	 * @throws InvalidArgumentException
483
+	 * @throws InvalidDataTypeException
484
+	 * @throws InvalidInterfaceException
485
+	 */
486
+	protected function _delete_question()
487
+	{
488
+		$success = $this->_delete_items($this->_question_model);
489
+		$this->_redirect_after_action(
490
+			$success,
491
+			$this->_question_model->item_name($success),
492
+			'deleted',
493
+			array('action' => 'default', 'status' => 'all')
494
+		);
495
+	}
496
+
497
+
498
+	/**
499
+	 * @return void
500
+	 * @throws EE_Error
501
+	 * @throws InvalidArgumentException
502
+	 * @throws InvalidDataTypeException
503
+	 * @throws InvalidInterfaceException
504
+	 */
505
+	protected function _delete_questions()
506
+	{
507
+		$success = $this->_delete_items($this->_question_model);
508
+		$this->_redirect_after_action(
509
+			$success,
510
+			$this->_question_model->item_name($success),
511
+			'deleted permanently',
512
+			array('action' => 'default', 'status' => 'trash')
513
+		);
514
+	}
515
+
516
+
517
+	/**
518
+	 * Performs the deletion of a single or multiple questions or question groups.
519
+	 *
520
+	 * @param EEM_Soft_Delete_Base $model
521
+	 * @return int number of items deleted permanently
522
+	 * @throws EE_Error
523
+	 * @throws InvalidArgumentException
524
+	 * @throws InvalidDataTypeException
525
+	 * @throws InvalidInterfaceException
526
+	 */
527
+	private function _delete_items(EEM_Soft_Delete_Base $model)
528
+	{
529
+		$success = 0;
530
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
531
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
532
+			// if array has more than one element than success message should be plural
533
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
534
+			// cycle thru bulk action checkboxes
535
+			while (list($ID, $value) = each($this->_req_data['checkbox'])) {
536
+				if (! $this->_delete_item($ID, $model)) {
537
+					$success = 0;
538
+				}
539
+			}
540
+		} elseif (! empty($this->_req_data['QSG_ID'])) {
541
+			$success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
542
+		} elseif (! empty($this->_req_data['QST_ID'])) {
543
+			$success = $this->_delete_item($this->_req_data['QST_ID'], $model);
544
+		} else {
545
+			EE_Error::add_error(
546
+				sprintf(
547
+					esc_html__(
548
+						"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.",
549
+						"event_espresso"
550
+					)
551
+				),
552
+				__FILE__,
553
+				__FUNCTION__,
554
+				__LINE__
555
+			);
556
+		}
557
+		return $success;
558
+	}
559
+
560
+
561
+	/**
562
+	 * Deletes the specified question (and its associated question options) or question group
563
+	 *
564
+	 * @param int                  $id
565
+	 * @param EEM_Soft_Delete_Base $model
566
+	 * @return boolean
567
+	 * @throws EE_Error
568
+	 * @throws InvalidArgumentException
569
+	 * @throws InvalidDataTypeException
570
+	 * @throws InvalidInterfaceException
571
+	 */
572
+	protected function _delete_item($id, $model)
573
+	{
574
+		if ($model instanceof EEM_Question) {
575
+			EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
576
+		}
577
+		return $model->delete_permanently_by_ID(absint($id));
578
+	}
579
+
580
+
581
+	/******************************    QUESTION GROUPS    ******************************/
582
+
583
+
584
+	/**
585
+	 * @param string $type
586
+	 * @return void
587
+	 * @throws DomainException
588
+	 * @throws EE_Error
589
+	 * @throws InvalidArgumentException
590
+	 * @throws InvalidDataTypeException
591
+	 * @throws InvalidInterfaceException
592
+	 */
593
+	protected function _edit_question_group($type = 'add')
594
+	{
595
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
596
+		$ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
597
+			? absint($this->_req_data['QSG_ID'])
598
+			: false;
599
+
600
+		switch ($this->_req_action) {
601
+			case 'add_question_group':
602
+				$this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
603
+				break;
604
+			case 'edit_question_group':
605
+				$this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
606
+				break;
607
+			default:
608
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
609
+		}
610
+		// add ID to title if editing
611
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
612
+		if ($ID) {
613
+			/** @var EE_Question_Group $questionGroup */
614
+			$questionGroup = $this->_question_group_model->get_one_by_ID($ID);
615
+			$additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
616
+			$this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
617
+		} else {
618
+			/** @var EE_Question_Group $questionGroup */
619
+			$questionGroup = EEM_Question_Group::instance()->create_default_object();
620
+			$questionGroup->set_order_to_latest();
621
+			$this->_set_add_edit_form_tags('insert_question_group');
622
+		}
623
+		$this->_template_args['values'] = $this->_yes_no_values;
624
+		$this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
625
+		$this->_template_args['QSG_ID'] = $ID ? $ID : true;
626
+		$this->_template_args['question_group'] = $questionGroup;
627
+
628
+		$redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
629
+		$this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
630
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
631
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
632
+			$this->_template_args,
633
+			true
634
+		);
635
+
636
+		// the details template wrapper
637
+		$this->display_admin_page_with_sidebar();
638
+	}
639
+
640
+
641
+	/**
642
+	 * @return void
643
+	 * @throws EE_Error
644
+	 * @throws InvalidArgumentException
645
+	 * @throws InvalidDataTypeException
646
+	 * @throws InvalidInterfaceException
647
+	 */
648
+	protected function _delete_question_groups()
649
+	{
650
+		$success = $this->_delete_items($this->_question_group_model);
651
+		$this->_redirect_after_action(
652
+			$success,
653
+			$this->_question_group_model->item_name($success),
654
+			'deleted permanently',
655
+			array('action' => 'question_groups', 'status' => 'trash')
656
+		);
657
+	}
658
+
659
+
660
+	/**
661
+	 * @param bool $new_question_group
662
+	 * @throws EE_Error
663
+	 * @throws InvalidArgumentException
664
+	 * @throws InvalidDataTypeException
665
+	 * @throws InvalidInterfaceException
666
+	 */
667
+	protected function _insert_or_update_question_group($new_question_group = true)
668
+	{
669
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
670
+		$set_column_values = $this->_set_column_values_for($this->_question_group_model);
671
+		if ($new_question_group) {
672
+			// make sure identifier is unique
673
+			$identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
674
+			$identifier_exists = ! empty($identifier_value)
675
+				? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
676
+				: false;
677
+			if ($identifier_exists) {
678
+				$set_column_values['QSG_identifier'] .= uniqid('id', true);
679
+			}
680
+			$QSG_ID = $this->_question_group_model->insert($set_column_values);
681
+			$success = $QSG_ID ? 1 : 0;
682
+			if ($success === 0) {
683
+				EE_Error::add_error(
684
+					esc_html__('Something went wrong saving the question group.', 'event_espresso'),
685
+					__FILE__,
686
+					__FUNCTION__,
687
+					__LINE__
688
+				);
689
+				$this->_redirect_after_action(
690
+					false,
691
+					'',
692
+					'',
693
+					array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
694
+					true
695
+				);
696
+			}
697
+		} else {
698
+			$QSG_ID = absint($this->_req_data['QSG_ID']);
699
+			unset($set_column_values['QSG_ID']);
700
+			$success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
701
+		}
702
+
703
+		$phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
704
+			EEM_Attendee::system_question_phone
705
+		);
706
+		// update the existing related questions
707
+		// BUT FIRST...  delete the phone question from the Question_Group_Question
708
+		// if it is being added to this question group (therefore removed from the existing group)
709
+		if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
710
+			// delete where QST ID = system phone question ID and Question Group ID is NOT this group
711
+			EEM_Question_Group_Question::instance()->delete(
712
+				array(
713
+					array(
714
+						'QST_ID' => $phone_question_id,
715
+						'QSG_ID' => array('!=', $QSG_ID),
716
+					),
717
+				)
718
+			);
719
+		}
720
+		/** @type EE_Question_Group $question_group */
721
+		$question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
722
+		$questions = $question_group->questions();
723
+		// make sure system phone question is added to list of questions for this group
724
+		if (! isset($questions[ $phone_question_id ])) {
725
+			$questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
726
+		}
727
+
728
+		foreach ($questions as $question_ID => $question) {
729
+			// first we always check for order.
730
+			if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
731
+				// update question order
732
+				$question_group->update_question_order(
733
+					$question_ID,
734
+					$this->_req_data['question_orders'][ $question_ID ]
735
+				);
736
+			}
737
+
738
+			// then we always check if adding or removing.
739
+			if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
740
+				$question_group->add_question($question_ID);
741
+			} else {
742
+				// not found, remove it (but only if not a system question for the personal group
743
+				// with the exception of lname system question - we allow removal of it)
744
+				if (
745
+					in_array(
746
+						$question->system_ID(),
747
+						EEM_Question::instance()->required_system_questions_in_system_question_group(
748
+							$question_group->system_group()
749
+						)
750
+					)
751
+				) {
752
+					continue;
753
+				} else {
754
+					$question_group->remove_question($question_ID);
755
+				}
756
+			}
757
+		}
758
+		// save new related questions
759
+		if (isset($this->_req_data['questions'])) {
760
+			foreach ($this->_req_data['questions'] as $QST_ID) {
761
+				$question_group->add_question($QST_ID);
762
+				if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
763
+					$question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
764
+				}
765
+			}
766
+		}
767
+
768
+		if ($success !== false) {
769
+			$msg = $new_question_group
770
+				? sprintf(
771
+					esc_html__('The %s has been created', 'event_espresso'),
772
+					$this->_question_group_model->item_name()
773
+				)
774
+				: sprintf(
775
+					esc_html__(
776
+						'The %s has been updated',
777
+						'event_espresso'
778
+					),
779
+					$this->_question_group_model->item_name()
780
+				);
781
+			EE_Error::add_success($msg);
782
+		}
783
+		$this->_redirect_after_action(
784
+			false,
785
+			'',
786
+			'',
787
+			array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
788
+			true
789
+		);
790
+	}
791
+
792
+
793
+	/**
794
+	 * duplicates a question and all its question options and redirects to the new question.
795
+	 *
796
+	 * @return void
797
+	 * @throws EE_Error
798
+	 * @throws InvalidArgumentException
799
+	 * @throws ReflectionException
800
+	 * @throws InvalidDataTypeException
801
+	 * @throws InvalidInterfaceException
802
+	 */
803
+	public function _duplicate_question()
804
+	{
805
+		$question_ID = (int) $this->_req_data['QST_ID'];
806
+		$question = EEM_Question::instance()->get_one_by_ID($question_ID);
807
+		if ($question instanceof EE_Question) {
808
+			$new_question = $question->duplicate();
809
+			if ($new_question instanceof EE_Question) {
810
+				$this->_redirect_after_action(
811
+					true,
812
+					esc_html__('Question', 'event_espresso'),
813
+					esc_html__('Duplicated', 'event_espresso'),
814
+					array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
815
+					true
816
+				);
817
+			} else {
818
+				global $wpdb;
819
+				EE_Error::add_error(
820
+					sprintf(
821
+						esc_html__(
822
+							'Could not duplicate question with ID %1$d because: %2$s',
823
+							'event_espresso'
824
+						),
825
+						$question_ID,
826
+						$wpdb->last_error
827
+					),
828
+					__FILE__,
829
+					__FUNCTION__,
830
+					__LINE__
831
+				);
832
+				$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
833
+			}
834
+		} else {
835
+			EE_Error::add_error(
836
+				sprintf(
837
+					esc_html__(
838
+						'Could not duplicate question with ID %d because it didn\'t exist!',
839
+						'event_espresso'
840
+					),
841
+					$question_ID
842
+				),
843
+				__FILE__,
844
+				__FUNCTION__,
845
+				__LINE__
846
+			);
847
+			$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
848
+		}
849
+	}
850
+
851
+
852
+	/**
853
+	 * @param bool $trash
854
+	 * @throws EE_Error
855
+	 */
856
+	protected function _trash_or_restore_question_groups($trash = true)
857
+	{
858
+		$this->_trash_or_restore_items($this->_question_group_model, $trash);
859
+	}
860
+
861
+
862
+	/**
863
+	 *_trash_question
864
+	 *
865
+	 * @return void
866
+	 * @throws EE_Error
867
+	 */
868
+	protected function _trash_question()
869
+	{
870
+		$success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
871
+		$query_args = array('action' => 'default', 'status' => 'all');
872
+		$this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
873
+	}
874
+
875
+
876
+	/**
877
+	 * @param bool $trash
878
+	 * @throws EE_Error
879
+	 */
880
+	protected function _trash_or_restore_questions($trash = true)
881
+	{
882
+		$this->_trash_or_restore_items($this->_question_model, $trash);
883
+	}
884
+
885
+
886
+	/**
887
+	 * Internally used to delete or restore items, using the request data. Meant to be
888
+	 * flexible between question or question groups
889
+	 *
890
+	 * @param EEM_Soft_Delete_Base $model
891
+	 * @param boolean              $trash whether to trash or restore
892
+	 * @throws EE_Error
893
+	 */
894
+	private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
895
+	{
896
+
897
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
898
+
899
+		$success = 1;
900
+		// Checkboxes
901
+		// echo "trash $trash";
902
+		// var_dump($this->_req_data['checkbox']);die;
903
+		if (isset($this->_req_data['checkbox'])) {
904
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
905
+				// if array has more than one element than success message should be plural
906
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
907
+				// cycle thru bulk action checkboxes
908
+				while (list($ID, $value) = each($this->_req_data['checkbox'])) {
909
+					if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
910
+						$success = 0;
911
+					}
912
+				}
913
+			} else {
914
+				// grab single id and delete
915
+				$ID = absint($this->_req_data['checkbox']);
916
+				if (! $model->delete_or_restore_by_ID($trash, $ID)) {
917
+					$success = 0;
918
+				}
919
+			}
920
+		} else {
921
+			// delete via trash link
922
+			// grab single id and delete
923
+			$ID = absint($this->_req_data[ $model->primary_key_name() ]);
924
+			if (! $model->delete_or_restore_by_ID($trash, $ID)) {
925
+				$success = 0;
926
+			}
927
+		}
928
+
929
+
930
+		$action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
931
+		// echo "action :$action";
932
+		// $action = 'questions' ? 'default' : $action;
933
+		if ($trash) {
934
+			$action_desc = 'trashed';
935
+			$status = 'trash';
936
+		} else {
937
+			$action_desc = 'restored';
938
+			$status = 'all';
939
+		}
940
+		$this->_redirect_after_action(
941
+			$success,
942
+			$model->item_name($success),
943
+			$action_desc,
944
+			array('action' => $action, 'status' => $status)
945
+		);
946
+	}
947
+
948
+
949
+	/**
950
+	 * @param            $per_page
951
+	 * @param int        $current_page
952
+	 * @param bool|false $count
953
+	 * @return EE_Soft_Delete_Base_Class[]|int
954
+	 * @throws EE_Error
955
+	 * @throws InvalidArgumentException
956
+	 * @throws InvalidDataTypeException
957
+	 * @throws InvalidInterfaceException
958
+	 */
959
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
960
+	{
961
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
962
+
963
+		if ($count) {
964
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
965
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
966
+			$results = $this->_question_model->count_deleted($where);
967
+		} else {
968
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
969
+			$results = $this->_question_model->get_all_deleted($query_params);
970
+		}
971
+		return $results;
972
+	}
973
+
974
+
975
+	/**
976
+	 * @param            $per_page
977
+	 * @param int        $current_page
978
+	 * @param bool|false $count
979
+	 * @return EE_Soft_Delete_Base_Class[]|int
980
+	 * @throws EE_Error
981
+	 * @throws InvalidArgumentException
982
+	 * @throws InvalidDataTypeException
983
+	 * @throws InvalidInterfaceException
984
+	 */
985
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
986
+	{
987
+		$questionGroupModel = EEM_Question_Group::instance();
988
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
989
+		if ($count) {
990
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
991
+			$results = $questionGroupModel->count($where);
992
+		} else {
993
+			$results = $questionGroupModel->get_all($query_params);
994
+		}
995
+		return $results;
996
+	}
997
+
998
+
999
+	/**
1000
+	 * @param      $per_page
1001
+	 * @param int  $current_page
1002
+	 * @param bool $count
1003
+	 * @return EE_Soft_Delete_Base_Class[]|int
1004
+	 * @throws EE_Error
1005
+	 * @throws InvalidArgumentException
1006
+	 * @throws InvalidDataTypeException
1007
+	 * @throws InvalidInterfaceException
1008
+	 */
1009
+	public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1010
+	{
1011
+		$questionGroupModel = EEM_Question_Group::instance();
1012
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1013
+		if ($count) {
1014
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
1015
+			$query_params['limit'] = null;
1016
+			$results = $questionGroupModel->count_deleted($where);
1017
+		} else {
1018
+			$results = $questionGroupModel->get_all_deleted($query_params);
1019
+		}
1020
+		return $results;
1021
+	}
1022
+
1023
+
1024
+	/**
1025
+	 * method for performing updates to question order
1026
+	 *
1027
+	 * @return void results array
1028
+	 * @throws EE_Error
1029
+	 * @throws InvalidArgumentException
1030
+	 * @throws InvalidDataTypeException
1031
+	 * @throws InvalidInterfaceException
1032
+	 */
1033
+	public function update_question_group_order()
1034
+	{
1035
+
1036
+		$success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1037
+
1038
+		// grab our row IDs
1039
+		$row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1040
+			? explode(',', rtrim($this->_req_data['row_ids'], ','))
1041
+			: array();
1042
+
1043
+		$perpage = ! empty($this->_req_data['perpage'])
1044
+			? (int) $this->_req_data['perpage']
1045
+			: null;
1046
+		$curpage = ! empty($this->_req_data['curpage'])
1047
+			? (int) $this->_req_data['curpage']
1048
+			: null;
1049
+
1050
+		if (! empty($row_ids)) {
1051
+			// figure out where we start the row_id count at for the current page.
1052
+			$qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1053
+
1054
+			$row_count = count($row_ids);
1055
+			for ($i = 0; $i < $row_count; $i++) {
1056
+				// Update the questions when re-ordering
1057
+				$updated = EEM_Question_Group::instance()->update(
1058
+					array('QSG_order' => $qsgcount),
1059
+					array(array('QSG_ID' => $row_ids[ $i ]))
1060
+				);
1061
+				if ($updated === false) {
1062
+					$success = false;
1063
+				}
1064
+				$qsgcount++;
1065
+			}
1066
+		} else {
1067
+			$success = false;
1068
+		}
1069
+
1070
+		$errors = ! $success
1071
+			? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1072
+			: false;
1073
+
1074
+		echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1075
+		die();
1076
+	}
1077
+
1078
+
1079
+
1080
+	/***************************************       REGISTRATION SETTINGS       ***************************************/
1081
+
1082
+
1083
+	/**
1084
+	 * @throws DomainException
1085
+	 * @throws EE_Error
1086
+	 * @throws InvalidArgumentException
1087
+	 * @throws InvalidDataTypeException
1088
+	 * @throws InvalidInterfaceException
1089
+	 */
1090
+	protected function _reg_form_settings()
1091
+	{
1092
+		$this->_template_args['values'] = $this->_yes_no_values;
1093
+		add_action(
1094
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1095
+			array($this, 'email_validation_settings_form'),
1096
+			2
1097
+		);
1098
+		add_action(
1099
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1100
+			array($this, 'copy_attendee_info_settings_form'),
1101
+			4
1102
+		);
1103
+		$this->_template_args = (array) apply_filters(
1104
+			'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1105
+			$this->_template_args
1106
+		);
1107
+		$this->_set_add_edit_form_tags('update_reg_form_settings');
1108
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
1109
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1110
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1111
+			$this->_template_args,
1112
+			true
1113
+		);
1114
+		$this->display_admin_page_with_sidebar();
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 * @return void
1120
+	 * @throws EE_Error
1121
+	 * @throws InvalidArgumentException
1122
+	 * @throws ReflectionException
1123
+	 * @throws InvalidDataTypeException
1124
+	 * @throws InvalidInterfaceException
1125
+	 */
1126
+	protected function _update_reg_form_settings()
1127
+	{
1128
+		EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1129
+			EE_Registry::instance()->CFG->registration
1130
+		);
1131
+		EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1132
+			EE_Registry::instance()->CFG->registration
1133
+		);
1134
+		EE_Registry::instance()->CFG->registration = apply_filters(
1135
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1136
+			EE_Registry::instance()->CFG->registration
1137
+		);
1138
+		$success = $this->_update_espresso_configuration(
1139
+			esc_html__('Registration Form Options', 'event_espresso'),
1140
+			EE_Registry::instance()->CFG,
1141
+			__FILE__,
1142
+			__FUNCTION__,
1143
+			__LINE__
1144
+		);
1145
+		$this->_redirect_after_action(
1146
+			$success,
1147
+			esc_html__('Registration Form Options', 'event_espresso'),
1148
+			'updated',
1149
+			array('action' => 'view_reg_form_settings')
1150
+		);
1151
+	}
1152
+
1153
+
1154
+	/**
1155
+	 * @return void
1156
+	 * @throws EE_Error
1157
+	 * @throws InvalidArgumentException
1158
+	 * @throws InvalidDataTypeException
1159
+	 * @throws InvalidInterfaceException
1160
+	 */
1161
+	public function copy_attendee_info_settings_form()
1162
+	{
1163
+		echo $this->_copy_attendee_info_settings_form()->get_html();
1164
+	}
1165
+
1166
+	/**
1167
+	 * _copy_attendee_info_settings_form
1168
+	 *
1169
+	 * @access protected
1170
+	 * @return EE_Form_Section_Proper
1171
+	 * @throws \EE_Error
1172
+	 */
1173
+	protected function _copy_attendee_info_settings_form()
1174
+	{
1175
+		return new EE_Form_Section_Proper(
1176
+			array(
1177
+				'name'            => 'copy_attendee_info_settings',
1178
+				'html_id'         => 'copy_attendee_info_settings',
1179
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1180
+				'subsections'     => apply_filters(
1181
+					'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1182
+					array(
1183
+						'copy_attendee_info_hdr'   => new EE_Form_Section_HTML(
1184
+							EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1185
+						),
1186
+						'copy_attendee_info' => new EE_Yes_No_Input(
1187
+							array(
1188
+								'html_label_text' => esc_html__(
1189
+									'Allow copy #1 attendee info to extra attendees?',
1190
+									'event_espresso'
1191
+								),
1192
+								'html_help_text'  => esc_html__(
1193
+									'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1194
+									'event_espresso'
1195
+								),
1196
+								'default'         => EE_Registry::instance()->CFG->registration->copyAttendeeInfo(),
1197
+								'required'        => false,
1198
+								'display_html_label_text' => false,
1199
+							)
1200
+						),
1201
+					)
1202
+				),
1203
+			)
1204
+		);
1205
+	}
1206
+
1207
+	/**
1208
+	 * @param EE_Registration_Config $EE_Registration_Config
1209
+	 * @return EE_Registration_Config
1210
+	 * @throws EE_Error
1211
+	 * @throws InvalidArgumentException
1212
+	 * @throws ReflectionException
1213
+	 * @throws InvalidDataTypeException
1214
+	 * @throws InvalidInterfaceException
1215
+	 */
1216
+	public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1217
+	{
1218
+		$prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1219
+		try {
1220
+			$copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1221
+			// if not displaying a form, then check for form submission
1222
+			if ($copy_attendee_info_settings_form->was_submitted()) {
1223
+				// capture form data
1224
+				$copy_attendee_info_settings_form->receive_form_submission();
1225
+				// validate form data
1226
+				if ($copy_attendee_info_settings_form->is_valid()) {
1227
+					// grab validated data from form
1228
+					$valid_data = $copy_attendee_info_settings_form->valid_data();
1229
+					if (isset($valid_data['copy_attendee_info'])) {
1230
+						$EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1231
+					} else {
1232
+						EE_Error::add_error(
1233
+							esc_html__(
1234
+								'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1235
+								'event_espresso'
1236
+							),
1237
+							__FILE__,
1238
+							__FUNCTION__,
1239
+							__LINE__
1240
+						);
1241
+					}
1242
+				} else {
1243
+					if ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1244
+						EE_Error::add_error(
1245
+							$copy_attendee_info_settings_form->submission_error_message(),
1246
+							__FILE__,
1247
+							__FUNCTION__,
1248
+							__LINE__
1249
+						);
1250
+					}
1251
+				}
1252
+			}
1253
+		} catch (EE_Error $e) {
1254
+			$e->get_error();
1255
+		}
1256
+		return $EE_Registration_Config;
1257
+	}
1258
+
1259
+
1260
+	/**
1261
+	 * @return void
1262
+	 * @throws EE_Error
1263
+	 * @throws InvalidArgumentException
1264
+	 * @throws InvalidDataTypeException
1265
+	 * @throws InvalidInterfaceException
1266
+	 */
1267
+	public function email_validation_settings_form()
1268
+	{
1269
+		echo $this->_email_validation_settings_form()->get_html();
1270
+	}
1271
+
1272
+
1273
+	/**
1274
+	 * _email_validation_settings_form
1275
+	 *
1276
+	 * @access protected
1277
+	 * @return EE_Form_Section_Proper
1278
+	 * @throws \EE_Error
1279
+	 */
1280
+	protected function _email_validation_settings_form()
1281
+	{
1282
+		return new EE_Form_Section_Proper(
1283
+			array(
1284
+				'name'            => 'email_validation_settings',
1285
+				'html_id'         => 'email_validation_settings',
1286
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1287
+				'subsections'     => apply_filters(
1288
+					'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1289
+					array(
1290
+						'email_validation_hdr'   => new EE_Form_Section_HTML(
1291
+							EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1292
+						),
1293
+						'email_validation_level' => new EE_Select_Input(
1294
+							array(
1295
+								'basic'      => esc_html__('Basic', 'event_espresso'),
1296
+								'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1297
+								'i18n'       => esc_html__('International', 'event_espresso'),
1298
+								'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1299
+							),
1300
+							array(
1301
+								'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1302
+													 . EEH_Template::get_help_tab_link('email_validation_info'),
1303
+								'html_help_text'  => esc_html__(
1304
+									'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.',
1305
+									'event_espresso'
1306
+								),
1307
+								'default'         => isset(
1308
+									EE_Registry::instance()->CFG->registration->email_validation_level
1309
+								)
1310
+									? EE_Registry::instance()->CFG->registration->email_validation_level
1311
+									: 'wp_default',
1312
+								'required'        => false,
1313
+							)
1314
+						),
1315
+					)
1316
+				),
1317
+			)
1318
+		);
1319
+	}
1320
+
1321
+
1322
+	/**
1323
+	 * @param EE_Registration_Config $EE_Registration_Config
1324
+	 * @return EE_Registration_Config
1325
+	 * @throws EE_Error
1326
+	 * @throws InvalidArgumentException
1327
+	 * @throws ReflectionException
1328
+	 * @throws InvalidDataTypeException
1329
+	 * @throws InvalidInterfaceException
1330
+	 */
1331
+	public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1332
+	{
1333
+		$prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1334
+		try {
1335
+			$email_validation_settings_form = $this->_email_validation_settings_form();
1336
+			// if not displaying a form, then check for form submission
1337
+			if ($email_validation_settings_form->was_submitted()) {
1338
+				// capture form data
1339
+				$email_validation_settings_form->receive_form_submission();
1340
+				// validate form data
1341
+				if ($email_validation_settings_form->is_valid()) {
1342
+					// grab validated data from form
1343
+					$valid_data = $email_validation_settings_form->valid_data();
1344
+					if (isset($valid_data['email_validation_level'])) {
1345
+						$email_validation_level = $valid_data['email_validation_level'];
1346
+						// now if they want to use international email addresses
1347
+						if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1348
+							// in case we need to reset their email validation level,
1349
+							// make sure that the previous value wasn't already set to one of the i18n options.
1350
+							if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1351
+								// if so, then reset it back to "basic" since that is the only other option that,
1352
+								// despite offering poor validation, supports i18n email addresses
1353
+								$prev_email_validation_level = 'basic';
1354
+							}
1355
+							// confirm our i18n email validation will work on the server
1356
+							if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1357
+								// or reset email validation level to previous value
1358
+								$email_validation_level = $prev_email_validation_level;
1359
+							}
1360
+						}
1361
+						$EE_Registration_Config->email_validation_level = $email_validation_level;
1362
+					} else {
1363
+						EE_Error::add_error(
1364
+							esc_html__(
1365
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1366
+								'event_espresso'
1367
+							),
1368
+							__FILE__,
1369
+							__FUNCTION__,
1370
+							__LINE__
1371
+						);
1372
+					}
1373
+				} else {
1374
+					if ($email_validation_settings_form->submission_error_message() !== '') {
1375
+						EE_Error::add_error(
1376
+							$email_validation_settings_form->submission_error_message(),
1377
+							__FILE__,
1378
+							__FUNCTION__,
1379
+							__LINE__
1380
+						);
1381
+					}
1382
+				}
1383
+			}
1384
+		} catch (EE_Error $e) {
1385
+			$e->get_error();
1386
+		}
1387
+		return $EE_Registration_Config;
1388
+	}
1389
+
1390
+
1391
+	/**
1392
+	 * confirms that the server's PHP version has the PCRE module enabled,
1393
+	 * and that the PCRE version works with our i18n email validation
1394
+	 *
1395
+	 * @param EE_Registration_Config $EE_Registration_Config
1396
+	 * @param string                 $email_validation_level
1397
+	 * @return bool
1398
+	 */
1399
+	private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1400
+	{
1401
+		// first check that PCRE is enabled
1402
+		if (! defined('PREG_BAD_UTF8_ERROR')) {
1403
+			EE_Error::add_error(
1404
+				sprintf(
1405
+					esc_html__(
1406
+						'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.',
1407
+						'event_espresso'
1408
+					),
1409
+					'<br />'
1410
+				),
1411
+				__FILE__,
1412
+				__FUNCTION__,
1413
+				__LINE__
1414
+			);
1415
+			return false;
1416
+		} else {
1417
+			// PCRE support is enabled, but let's still
1418
+			// perform a test to see if the server will support it.
1419
+			// but first, save the updated validation level to the config,
1420
+			// so that the validation strategy picks it up.
1421
+			// this will get bumped back down if it doesn't work
1422
+			$EE_Registration_Config->email_validation_level = $email_validation_level;
1423
+			try {
1424
+				$email_validator = new EE_Email_Validation_Strategy();
1425
+				$i18n_email_address = apply_filters(
1426
+					'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1427
+					'jägerjü[email protected]'
1428
+				);
1429
+				$email_validator->validate($i18n_email_address);
1430
+			} catch (Exception $e) {
1431
+				EE_Error::add_error(
1432
+					sprintf(
1433
+						esc_html__(
1434
+							'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',
1435
+							'event_espresso'
1436
+						),
1437
+						'<br />',
1438
+						'<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1439
+					),
1440
+					__FILE__,
1441
+					__FUNCTION__,
1442
+					__LINE__
1443
+				);
1444
+				return false;
1445
+			}
1446
+		}
1447
+		return true;
1448
+	}
1449 1449
 }
Please login to merge, or discard this patch.