Completed
Branch add-cap-checks-to-routes (73eed8)
by
unknown
08:17 queued 10s
created
core/libraries/form_sections/form_handlers/FormHandler.php 1 patch
Indentation   +639 added lines, -639 removed lines patch added patch discarded remove patch
@@ -29,643 +29,643 @@
 block discarded – undo
29 29
  */
30 30
 abstract class FormHandler implements FormHandlerInterface
31 31
 {
32
-    /**
33
-     * will add opening and closing HTML form tags as well as a submit button
34
-     */
35
-    const ADD_FORM_TAGS_AND_SUBMIT = 'add_form_tags_and_submit';
36
-
37
-    /**
38
-     * will add opening and closing HTML form tags but NOT a submit button
39
-     */
40
-    const ADD_FORM_TAGS_ONLY = 'add_form_tags_only';
41
-
42
-    /**
43
-     * will NOT add opening and closing HTML form tags but will add a submit button
44
-     */
45
-    const ADD_FORM_SUBMIT_ONLY = 'add_form_submit_only';
46
-
47
-    /**
48
-     * will NOT add opening and closing HTML form tags NOR a submit button
49
-     */
50
-    const DO_NOT_SETUP_FORM = 'do_not_setup_form';
51
-
52
-    /**
53
-     * if set to false, then this form has no displayable content,
54
-     * and will only be used for processing data sent passed via GET or POST
55
-     * defaults to true ( ie: form has displayable content )
56
-     *
57
-     * @var boolean $displayable
58
-     */
59
-    private $displayable = true;
60
-
61
-    /**
62
-     * @var string $form_name
63
-     */
64
-    private $form_name;
65
-
66
-    /**
67
-     * @var string $admin_name
68
-     */
69
-    private $admin_name;
70
-
71
-    /**
72
-     * @var string $slug
73
-     */
74
-    private $slug;
75
-
76
-    /**
77
-     * @var string $submit_btn_text
78
-     */
79
-    private $submit_btn_text;
80
-
81
-    /**
82
-     * @var string $form_action
83
-     */
84
-    private $form_action;
85
-
86
-    /**
87
-     * form params in key value pairs
88
-     * can be added to form action URL or as hidden inputs
89
-     *
90
-     * @var array $form_args
91
-     */
92
-    private $form_args = array();
93
-
94
-    /**
95
-     * value of one of the string constant above
96
-     *
97
-     * @var string $form_config
98
-     */
99
-    private $form_config;
100
-
101
-    /**
102
-     * whether or not the form was determined to be invalid
103
-     *
104
-     * @var boolean $form_has_errors
105
-     */
106
-    private $form_has_errors;
107
-
108
-    /**
109
-     * the absolute top level form section being used on the page
110
-     *
111
-     * @var EE_Form_Section_Proper $form
112
-     */
113
-    private $form;
114
-
115
-    /**
116
-     * @var EE_Registry $registry
117
-     */
118
-    protected $registry;
119
-
120
-    // phpcs:disable PEAR.Functions.ValidDefaultValue.NotAtEnd
121
-    /**
122
-     * Form constructor.
123
-     *
124
-     * @param string      $form_name
125
-     * @param string      $admin_name
126
-     * @param string      $slug
127
-     * @param string      $form_action
128
-     * @param string      $form_config
129
-     * @param EE_Registry $registry
130
-     * @throws InvalidDataTypeException
131
-     * @throws DomainException
132
-     * @throws InvalidArgumentException
133
-     */
134
-    public function __construct(
135
-        $form_name,
136
-        $admin_name,
137
-        $slug,
138
-        $form_action = '',
139
-        $form_config = FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
140
-        EE_Registry $registry
141
-    ) {
142
-        $this->setFormName($form_name);
143
-        $this->setAdminName($admin_name);
144
-        $this->setSlug($slug);
145
-        $this->setFormAction($form_action);
146
-        $this->setFormConfig($form_config);
147
-        $this->setSubmitBtnText(esc_html__('Submit', 'event_espresso'));
148
-        $this->registry = $registry;
149
-    }
150
-
151
-
152
-    /**
153
-     * @return array
154
-     */
155
-    public static function getFormConfigConstants()
156
-    {
157
-        return array(
158
-            FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
159
-            FormHandler::ADD_FORM_TAGS_ONLY,
160
-            FormHandler::ADD_FORM_SUBMIT_ONLY,
161
-            FormHandler::DO_NOT_SETUP_FORM,
162
-        );
163
-    }
164
-
165
-
166
-    /**
167
-     * @param bool $for_display
168
-     * @return EE_Form_Section_Proper
169
-     * @throws EE_Error
170
-     * @throws LogicException
171
-     */
172
-    public function form($for_display = false)
173
-    {
174
-        if (! $this->formIsValid()) {
175
-            return null;
176
-        }
177
-        if ($for_display) {
178
-            $form_config = $this->formConfig();
179
-            if (
180
-                $form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
181
-                || $form_config === FormHandler::ADD_FORM_SUBMIT_ONLY
182
-            ) {
183
-                $this->appendSubmitButton();
184
-                $this->clearFormButtonFloats();
185
-            }
186
-        }
187
-        return $this->form;
188
-    }
189
-
190
-
191
-    /**
192
-     * @return boolean
193
-     * @throws LogicException
194
-     */
195
-    public function formIsValid()
196
-    {
197
-        if ($this->form instanceof EE_Form_Section_Proper) {
198
-            return true;
199
-        }
200
-        $form = apply_filters(
201
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__formIsValid__generated_form_object',
202
-            $this->generate(),
203
-            $this
204
-        );
205
-        if ($this->verifyForm($form)) {
206
-            $this->setForm($form);
207
-        }
208
-        return true;
209
-    }
210
-
211
-
212
-    /**
213
-     * @param EE_Form_Section_Proper|null $form
214
-     * @return bool
215
-     * @throws LogicException
216
-     */
217
-    public function verifyForm(EE_Form_Section_Proper $form = null)
218
-    {
219
-        $form = $form !== null ? $form : $this->form;
220
-        if ($form instanceof EE_Form_Section_Proper) {
221
-            return true;
222
-        }
223
-        throw new LogicException(
224
-            sprintf(
225
-                esc_html__('The "%1$s" form is invalid or missing. %2$s', 'event_espresso'),
226
-                $this->form_name,
227
-                var_export($form, true)
228
-            )
229
-        );
230
-    }
231
-
232
-
233
-    /**
234
-     * @param EE_Form_Section_Proper $form
235
-     */
236
-    public function setForm(EE_Form_Section_Proper $form)
237
-    {
238
-        $this->form = $form;
239
-    }
240
-
241
-
242
-    /**
243
-     * @return boolean
244
-     */
245
-    public function displayable()
246
-    {
247
-        return $this->displayable;
248
-    }
249
-
250
-
251
-    /**
252
-     * @param boolean $displayable
253
-     */
254
-    public function setDisplayable($displayable = false)
255
-    {
256
-        $this->displayable = filter_var($displayable, FILTER_VALIDATE_BOOLEAN);
257
-    }
258
-
259
-
260
-    /**
261
-     * a public name for the form that can be displayed on the frontend of a site
262
-     *
263
-     * @return string
264
-     */
265
-    public function formName()
266
-    {
267
-        return $this->form_name;
268
-    }
269
-
270
-
271
-    /**
272
-     * @param string $form_name
273
-     * @throws InvalidDataTypeException
274
-     */
275
-    public function setFormName($form_name)
276
-    {
277
-        if (! is_string($form_name)) {
278
-            throw new InvalidDataTypeException('$form_name', $form_name, 'string');
279
-        }
280
-        $this->form_name = $form_name;
281
-    }
282
-
283
-
284
-    /**
285
-     * a public name for the form that can be displayed, but only in the admin
286
-     *
287
-     * @return string
288
-     */
289
-    public function adminName()
290
-    {
291
-        return $this->admin_name;
292
-    }
293
-
294
-
295
-    /**
296
-     * @param string $admin_name
297
-     * @throws InvalidDataTypeException
298
-     */
299
-    public function setAdminName($admin_name)
300
-    {
301
-        if (! is_string($admin_name)) {
302
-            throw new InvalidDataTypeException('$admin_name', $admin_name, 'string');
303
-        }
304
-        $this->admin_name = $admin_name;
305
-    }
306
-
307
-
308
-    /**
309
-     * a URL friendly string that can be used for identifying the form
310
-     *
311
-     * @return string
312
-     */
313
-    public function slug()
314
-    {
315
-        return $this->slug;
316
-    }
317
-
318
-
319
-    /**
320
-     * @param string $slug
321
-     * @throws InvalidDataTypeException
322
-     */
323
-    public function setSlug($slug)
324
-    {
325
-        if (! is_string($slug)) {
326
-            throw new InvalidDataTypeException('$slug', $slug, 'string');
327
-        }
328
-        $this->slug = $slug;
329
-    }
330
-
331
-
332
-    /**
333
-     * @return string
334
-     */
335
-    public function submitBtnText()
336
-    {
337
-        return $this->submit_btn_text;
338
-    }
339
-
340
-
341
-    /**
342
-     * @param string $submit_btn_text
343
-     * @throws InvalidDataTypeException
344
-     * @throws InvalidArgumentException
345
-     */
346
-    public function setSubmitBtnText($submit_btn_text)
347
-    {
348
-        if (! is_string($submit_btn_text)) {
349
-            throw new InvalidDataTypeException('$submit_btn_text', $submit_btn_text, 'string');
350
-        }
351
-        if (empty($submit_btn_text)) {
352
-            throw new InvalidArgumentException(
353
-                esc_html__('Can not set Submit button text because an empty string was provided.', 'event_espresso')
354
-            );
355
-        }
356
-        $this->submit_btn_text = $submit_btn_text;
357
-    }
358
-
359
-
360
-    /**
361
-     * @return string
362
-     */
363
-    public function formAction()
364
-    {
365
-        return ! empty($this->form_args)
366
-            ? add_query_arg($this->form_args, $this->form_action)
367
-            : $this->form_action;
368
-    }
369
-
370
-
371
-    /**
372
-     * @param string $form_action
373
-     * @throws InvalidDataTypeException
374
-     */
375
-    public function setFormAction($form_action)
376
-    {
377
-        if (! is_string($form_action)) {
378
-            throw new InvalidDataTypeException('$form_action', $form_action, 'string');
379
-        }
380
-        $this->form_action = $form_action;
381
-    }
382
-
383
-
384
-    /**
385
-     * @param array $form_args
386
-     * @throws InvalidDataTypeException
387
-     * @throws InvalidArgumentException
388
-     */
389
-    public function addFormActionArgs($form_args = array())
390
-    {
391
-        if (is_object($form_args)) {
392
-            throw new InvalidDataTypeException(
393
-                '$form_args',
394
-                $form_args,
395
-                'anything other than an object was expected.'
396
-            );
397
-        }
398
-        if (empty($form_args)) {
399
-            throw new InvalidArgumentException(
400
-                esc_html__('The redirect arguments can not be an empty array.', 'event_espresso')
401
-            );
402
-        }
403
-        $this->form_args = array_merge($this->form_args, $form_args);
404
-    }
405
-
406
-
407
-    /**
408
-     * @return string
409
-     */
410
-    public function formConfig()
411
-    {
412
-        return $this->form_config;
413
-    }
414
-
415
-
416
-    /**
417
-     * @param string $form_config
418
-     * @throws DomainException
419
-     */
420
-    public function setFormConfig($form_config)
421
-    {
422
-        if (
423
-            ! in_array(
424
-                $form_config,
425
-                array(
426
-                FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
427
-                FormHandler::ADD_FORM_TAGS_ONLY,
428
-                FormHandler::ADD_FORM_SUBMIT_ONLY,
429
-                FormHandler::DO_NOT_SETUP_FORM,
430
-                ),
431
-                true
432
-            )
433
-        ) {
434
-            throw new DomainException(
435
-                sprintf(
436
-                    esc_html__(
437
-                        '"%1$s" is not a valid value for the form config. Please use one of the class constants on \EventEspresso\core\libraries\form_sections\form_handlers\Form',
438
-                        'event_espresso'
439
-                    ),
440
-                    $form_config
441
-                )
442
-            );
443
-        }
444
-        $this->form_config = $form_config;
445
-    }
446
-
447
-
448
-    /**
449
-     * called after the form is instantiated
450
-     * and used for performing any logic that needs to occur early
451
-     * before any of the other methods are called.
452
-     * returns true if everything is ok to proceed,
453
-     * and false if no further form logic should be implemented
454
-     *
455
-     * @return boolean
456
-     */
457
-    public function initialize()
458
-    {
459
-        $this->form_has_errors = EE_Error::has_error(true);
460
-        return true;
461
-    }
462
-
463
-
464
-    /**
465
-     * used for setting up css and js
466
-     *
467
-     * @return void
468
-     * @throws LogicException
469
-     * @throws EE_Error
470
-     */
471
-    public function enqueueStylesAndScripts()
472
-    {
473
-        $this->form()->enqueue_js();
474
-    }
475
-
476
-
477
-    /**
478
-     * creates and returns the actual form
479
-     *
480
-     * @return EE_Form_Section_Proper
481
-     */
482
-    abstract public function generate();
483
-
484
-
485
-    /**
486
-     * creates and returns an EE_Submit_Input labeled "Submit"
487
-     *
488
-     * @param string $text
489
-     * @return EE_Submit_Input
490
-     */
491
-    public function generateSubmitButton($text = '')
492
-    {
493
-        $text = ! empty($text) ? $text : $this->submitBtnText();
494
-        return new EE_Submit_Input(
495
-            array(
496
-                'html_name'             => 'ee-form-submit-' . $this->slug(),
497
-                'html_id'               => 'ee-form-submit-' . $this->slug(),
498
-                'html_class'            => 'ee-form-submit',
499
-                'html_label'            => ' ',
500
-                'other_html_attributes' => ' rel="' . $this->slug() . '"',
501
-                'default'               => $text,
502
-            )
503
-        );
504
-    }
505
-
506
-
507
-    /**
508
-     * calls generateSubmitButton() and appends it onto the form along with a float clearing div
509
-     *
510
-     * @param string $text
511
-     * @return void
512
-     * @throws EE_Error
513
-     */
514
-    public function appendSubmitButton($text = '')
515
-    {
516
-        if ($this->form->subsection_exists($this->slug() . '-submit-btn')) {
517
-            return;
518
-        }
519
-        $this->form->add_subsections(
520
-            array($this->slug() . '-submit-btn' => $this->generateSubmitButton($text)),
521
-            null,
522
-            false
523
-        );
524
-    }
525
-
526
-
527
-    /**
528
-     * creates and returns an EE_Submit_Input labeled "Cancel"
529
-     *
530
-     * @param string $text
531
-     * @return EE_Submit_Input
532
-     */
533
-    public function generateCancelButton($text = '')
534
-    {
535
-        $cancel_button = new EE_Submit_Input(
536
-            array(
537
-                'html_name'             => 'ee-form-submit-' . $this->slug(), // YES! Same name as submit !!!
538
-                'html_id'               => 'ee-cancel-form-' . $this->slug(),
539
-                'html_class'            => 'ee-cancel-form',
540
-                'html_label'            => ' ',
541
-                'other_html_attributes' => ' rel="' . $this->slug() . '"',
542
-                'default'               => ! empty($text) ? $text : esc_html__('Cancel', 'event_espresso'),
543
-            )
544
-        );
545
-        $cancel_button->set_button_css_attributes(false);
546
-        return $cancel_button;
547
-    }
548
-
549
-
550
-    /**
551
-     * appends a float clearing div onto end of form
552
-     *
553
-     * @return void
554
-     * @throws EE_Error
555
-     */
556
-    public function clearFormButtonFloats()
557
-    {
558
-        $this->form->add_subsections(
559
-            array(
560
-                'clear-submit-btn-float' => new EE_Form_Section_HTML(
561
-                    EEH_HTML::div('', '', 'clear-float') . EEH_HTML::divx()
562
-                ),
563
-            ),
564
-            null,
565
-            false
566
-        );
567
-    }
568
-
569
-
570
-    /**
571
-     * takes the generated form and displays it along with ony other non-form HTML that may be required
572
-     * returns a string of HTML that can be directly echoed in a template
573
-     *
574
-     * @return string
575
-     * @throws InvalidArgumentException
576
-     * @throws InvalidInterfaceException
577
-     * @throws InvalidDataTypeException
578
-     * @throws LogicException
579
-     * @throws EE_Error
580
-     */
581
-    public function display()
582
-    {
583
-        $form_html = apply_filters(
584
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__display__before_form',
585
-            ''
586
-        );
587
-        $form_config = $this->formConfig();
588
-        if (
589
-            $form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
590
-            || $form_config === FormHandler::ADD_FORM_TAGS_ONLY
591
-        ) {
592
-            $additional_props = $this->requiresMultipartEnctype()
593
-                ? 'enctype="multipart/form-data"'
594
-                : '';
595
-            $form_html .= $this->form()->form_open(
596
-                $this->formAction(),
597
-                'POST',
598
-                $additional_props
599
-            );
600
-        }
601
-        $form_html .= $this->form(true)->get_html();
602
-        if (
603
-            $form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
604
-            || $form_config === FormHandler::ADD_FORM_TAGS_ONLY
605
-        ) {
606
-            $form_html .= $this->form()->form_close();
607
-        }
608
-        $form_html .= apply_filters(
609
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__display__after_form',
610
-            ''
611
-        );
612
-        return $form_html;
613
-    }
614
-
615
-    /**
616
-     * Determines if this form needs "enctype='multipart/form-data'" or not.
617
-     * @since 4.9.80.p
618
-     * @return bool
619
-     * @throws EE_Error
620
-     */
621
-    public function requiresMultipartEnctype()
622
-    {
623
-        foreach ($this->form()->inputs_in_subsections() as $input) {
624
-            if ($input instanceof EE_File_Input) {
625
-                return true;
626
-            }
627
-        }
628
-        return false;
629
-    }
630
-
631
-
632
-    /**
633
-     * handles processing the form submission
634
-     * returns true or false depending on whether the form was processed successfully or not
635
-     *
636
-     * @param array $submitted_form_data
637
-     * @return array
638
-     * @throws InvalidArgumentException
639
-     * @throws InvalidInterfaceException
640
-     * @throws InvalidDataTypeException
641
-     * @throws EE_Error
642
-     * @throws LogicException
643
-     * @throws InvalidFormSubmissionException
644
-     */
645
-    public function process($submitted_form_data = array())
646
-    {
647
-        if (! $this->form()->was_submitted($submitted_form_data)) {
648
-            throw new InvalidFormSubmissionException($this->form_name);
649
-        }
650
-        $this->form(true)->receive_form_submission($submitted_form_data);
651
-        if (! $this->form()->is_valid()) {
652
-            throw new InvalidFormSubmissionException(
653
-                $this->form_name,
654
-                sprintf(
655
-                    esc_html__(
656
-                        'The "%1$s" form is invalid. Please correct the following errors and resubmit: %2$s %3$s',
657
-                        'event_espresso'
658
-                    ),
659
-                    $this->form_name,
660
-                    '<br />',
661
-                    implode('<br />', $this->form()->get_validation_errors_accumulated())
662
-                )
663
-            );
664
-        }
665
-        return (array) apply_filters(
666
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__process__valid_data',
667
-            $this->form()->valid_data(),
668
-            $this
669
-        );
670
-    }
32
+	/**
33
+	 * will add opening and closing HTML form tags as well as a submit button
34
+	 */
35
+	const ADD_FORM_TAGS_AND_SUBMIT = 'add_form_tags_and_submit';
36
+
37
+	/**
38
+	 * will add opening and closing HTML form tags but NOT a submit button
39
+	 */
40
+	const ADD_FORM_TAGS_ONLY = 'add_form_tags_only';
41
+
42
+	/**
43
+	 * will NOT add opening and closing HTML form tags but will add a submit button
44
+	 */
45
+	const ADD_FORM_SUBMIT_ONLY = 'add_form_submit_only';
46
+
47
+	/**
48
+	 * will NOT add opening and closing HTML form tags NOR a submit button
49
+	 */
50
+	const DO_NOT_SETUP_FORM = 'do_not_setup_form';
51
+
52
+	/**
53
+	 * if set to false, then this form has no displayable content,
54
+	 * and will only be used for processing data sent passed via GET or POST
55
+	 * defaults to true ( ie: form has displayable content )
56
+	 *
57
+	 * @var boolean $displayable
58
+	 */
59
+	private $displayable = true;
60
+
61
+	/**
62
+	 * @var string $form_name
63
+	 */
64
+	private $form_name;
65
+
66
+	/**
67
+	 * @var string $admin_name
68
+	 */
69
+	private $admin_name;
70
+
71
+	/**
72
+	 * @var string $slug
73
+	 */
74
+	private $slug;
75
+
76
+	/**
77
+	 * @var string $submit_btn_text
78
+	 */
79
+	private $submit_btn_text;
80
+
81
+	/**
82
+	 * @var string $form_action
83
+	 */
84
+	private $form_action;
85
+
86
+	/**
87
+	 * form params in key value pairs
88
+	 * can be added to form action URL or as hidden inputs
89
+	 *
90
+	 * @var array $form_args
91
+	 */
92
+	private $form_args = array();
93
+
94
+	/**
95
+	 * value of one of the string constant above
96
+	 *
97
+	 * @var string $form_config
98
+	 */
99
+	private $form_config;
100
+
101
+	/**
102
+	 * whether or not the form was determined to be invalid
103
+	 *
104
+	 * @var boolean $form_has_errors
105
+	 */
106
+	private $form_has_errors;
107
+
108
+	/**
109
+	 * the absolute top level form section being used on the page
110
+	 *
111
+	 * @var EE_Form_Section_Proper $form
112
+	 */
113
+	private $form;
114
+
115
+	/**
116
+	 * @var EE_Registry $registry
117
+	 */
118
+	protected $registry;
119
+
120
+	// phpcs:disable PEAR.Functions.ValidDefaultValue.NotAtEnd
121
+	/**
122
+	 * Form constructor.
123
+	 *
124
+	 * @param string      $form_name
125
+	 * @param string      $admin_name
126
+	 * @param string      $slug
127
+	 * @param string      $form_action
128
+	 * @param string      $form_config
129
+	 * @param EE_Registry $registry
130
+	 * @throws InvalidDataTypeException
131
+	 * @throws DomainException
132
+	 * @throws InvalidArgumentException
133
+	 */
134
+	public function __construct(
135
+		$form_name,
136
+		$admin_name,
137
+		$slug,
138
+		$form_action = '',
139
+		$form_config = FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
140
+		EE_Registry $registry
141
+	) {
142
+		$this->setFormName($form_name);
143
+		$this->setAdminName($admin_name);
144
+		$this->setSlug($slug);
145
+		$this->setFormAction($form_action);
146
+		$this->setFormConfig($form_config);
147
+		$this->setSubmitBtnText(esc_html__('Submit', 'event_espresso'));
148
+		$this->registry = $registry;
149
+	}
150
+
151
+
152
+	/**
153
+	 * @return array
154
+	 */
155
+	public static function getFormConfigConstants()
156
+	{
157
+		return array(
158
+			FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
159
+			FormHandler::ADD_FORM_TAGS_ONLY,
160
+			FormHandler::ADD_FORM_SUBMIT_ONLY,
161
+			FormHandler::DO_NOT_SETUP_FORM,
162
+		);
163
+	}
164
+
165
+
166
+	/**
167
+	 * @param bool $for_display
168
+	 * @return EE_Form_Section_Proper
169
+	 * @throws EE_Error
170
+	 * @throws LogicException
171
+	 */
172
+	public function form($for_display = false)
173
+	{
174
+		if (! $this->formIsValid()) {
175
+			return null;
176
+		}
177
+		if ($for_display) {
178
+			$form_config = $this->formConfig();
179
+			if (
180
+				$form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
181
+				|| $form_config === FormHandler::ADD_FORM_SUBMIT_ONLY
182
+			) {
183
+				$this->appendSubmitButton();
184
+				$this->clearFormButtonFloats();
185
+			}
186
+		}
187
+		return $this->form;
188
+	}
189
+
190
+
191
+	/**
192
+	 * @return boolean
193
+	 * @throws LogicException
194
+	 */
195
+	public function formIsValid()
196
+	{
197
+		if ($this->form instanceof EE_Form_Section_Proper) {
198
+			return true;
199
+		}
200
+		$form = apply_filters(
201
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__formIsValid__generated_form_object',
202
+			$this->generate(),
203
+			$this
204
+		);
205
+		if ($this->verifyForm($form)) {
206
+			$this->setForm($form);
207
+		}
208
+		return true;
209
+	}
210
+
211
+
212
+	/**
213
+	 * @param EE_Form_Section_Proper|null $form
214
+	 * @return bool
215
+	 * @throws LogicException
216
+	 */
217
+	public function verifyForm(EE_Form_Section_Proper $form = null)
218
+	{
219
+		$form = $form !== null ? $form : $this->form;
220
+		if ($form instanceof EE_Form_Section_Proper) {
221
+			return true;
222
+		}
223
+		throw new LogicException(
224
+			sprintf(
225
+				esc_html__('The "%1$s" form is invalid or missing. %2$s', 'event_espresso'),
226
+				$this->form_name,
227
+				var_export($form, true)
228
+			)
229
+		);
230
+	}
231
+
232
+
233
+	/**
234
+	 * @param EE_Form_Section_Proper $form
235
+	 */
236
+	public function setForm(EE_Form_Section_Proper $form)
237
+	{
238
+		$this->form = $form;
239
+	}
240
+
241
+
242
+	/**
243
+	 * @return boolean
244
+	 */
245
+	public function displayable()
246
+	{
247
+		return $this->displayable;
248
+	}
249
+
250
+
251
+	/**
252
+	 * @param boolean $displayable
253
+	 */
254
+	public function setDisplayable($displayable = false)
255
+	{
256
+		$this->displayable = filter_var($displayable, FILTER_VALIDATE_BOOLEAN);
257
+	}
258
+
259
+
260
+	/**
261
+	 * a public name for the form that can be displayed on the frontend of a site
262
+	 *
263
+	 * @return string
264
+	 */
265
+	public function formName()
266
+	{
267
+		return $this->form_name;
268
+	}
269
+
270
+
271
+	/**
272
+	 * @param string $form_name
273
+	 * @throws InvalidDataTypeException
274
+	 */
275
+	public function setFormName($form_name)
276
+	{
277
+		if (! is_string($form_name)) {
278
+			throw new InvalidDataTypeException('$form_name', $form_name, 'string');
279
+		}
280
+		$this->form_name = $form_name;
281
+	}
282
+
283
+
284
+	/**
285
+	 * a public name for the form that can be displayed, but only in the admin
286
+	 *
287
+	 * @return string
288
+	 */
289
+	public function adminName()
290
+	{
291
+		return $this->admin_name;
292
+	}
293
+
294
+
295
+	/**
296
+	 * @param string $admin_name
297
+	 * @throws InvalidDataTypeException
298
+	 */
299
+	public function setAdminName($admin_name)
300
+	{
301
+		if (! is_string($admin_name)) {
302
+			throw new InvalidDataTypeException('$admin_name', $admin_name, 'string');
303
+		}
304
+		$this->admin_name = $admin_name;
305
+	}
306
+
307
+
308
+	/**
309
+	 * a URL friendly string that can be used for identifying the form
310
+	 *
311
+	 * @return string
312
+	 */
313
+	public function slug()
314
+	{
315
+		return $this->slug;
316
+	}
317
+
318
+
319
+	/**
320
+	 * @param string $slug
321
+	 * @throws InvalidDataTypeException
322
+	 */
323
+	public function setSlug($slug)
324
+	{
325
+		if (! is_string($slug)) {
326
+			throw new InvalidDataTypeException('$slug', $slug, 'string');
327
+		}
328
+		$this->slug = $slug;
329
+	}
330
+
331
+
332
+	/**
333
+	 * @return string
334
+	 */
335
+	public function submitBtnText()
336
+	{
337
+		return $this->submit_btn_text;
338
+	}
339
+
340
+
341
+	/**
342
+	 * @param string $submit_btn_text
343
+	 * @throws InvalidDataTypeException
344
+	 * @throws InvalidArgumentException
345
+	 */
346
+	public function setSubmitBtnText($submit_btn_text)
347
+	{
348
+		if (! is_string($submit_btn_text)) {
349
+			throw new InvalidDataTypeException('$submit_btn_text', $submit_btn_text, 'string');
350
+		}
351
+		if (empty($submit_btn_text)) {
352
+			throw new InvalidArgumentException(
353
+				esc_html__('Can not set Submit button text because an empty string was provided.', 'event_espresso')
354
+			);
355
+		}
356
+		$this->submit_btn_text = $submit_btn_text;
357
+	}
358
+
359
+
360
+	/**
361
+	 * @return string
362
+	 */
363
+	public function formAction()
364
+	{
365
+		return ! empty($this->form_args)
366
+			? add_query_arg($this->form_args, $this->form_action)
367
+			: $this->form_action;
368
+	}
369
+
370
+
371
+	/**
372
+	 * @param string $form_action
373
+	 * @throws InvalidDataTypeException
374
+	 */
375
+	public function setFormAction($form_action)
376
+	{
377
+		if (! is_string($form_action)) {
378
+			throw new InvalidDataTypeException('$form_action', $form_action, 'string');
379
+		}
380
+		$this->form_action = $form_action;
381
+	}
382
+
383
+
384
+	/**
385
+	 * @param array $form_args
386
+	 * @throws InvalidDataTypeException
387
+	 * @throws InvalidArgumentException
388
+	 */
389
+	public function addFormActionArgs($form_args = array())
390
+	{
391
+		if (is_object($form_args)) {
392
+			throw new InvalidDataTypeException(
393
+				'$form_args',
394
+				$form_args,
395
+				'anything other than an object was expected.'
396
+			);
397
+		}
398
+		if (empty($form_args)) {
399
+			throw new InvalidArgumentException(
400
+				esc_html__('The redirect arguments can not be an empty array.', 'event_espresso')
401
+			);
402
+		}
403
+		$this->form_args = array_merge($this->form_args, $form_args);
404
+	}
405
+
406
+
407
+	/**
408
+	 * @return string
409
+	 */
410
+	public function formConfig()
411
+	{
412
+		return $this->form_config;
413
+	}
414
+
415
+
416
+	/**
417
+	 * @param string $form_config
418
+	 * @throws DomainException
419
+	 */
420
+	public function setFormConfig($form_config)
421
+	{
422
+		if (
423
+			! in_array(
424
+				$form_config,
425
+				array(
426
+				FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
427
+				FormHandler::ADD_FORM_TAGS_ONLY,
428
+				FormHandler::ADD_FORM_SUBMIT_ONLY,
429
+				FormHandler::DO_NOT_SETUP_FORM,
430
+				),
431
+				true
432
+			)
433
+		) {
434
+			throw new DomainException(
435
+				sprintf(
436
+					esc_html__(
437
+						'"%1$s" is not a valid value for the form config. Please use one of the class constants on \EventEspresso\core\libraries\form_sections\form_handlers\Form',
438
+						'event_espresso'
439
+					),
440
+					$form_config
441
+				)
442
+			);
443
+		}
444
+		$this->form_config = $form_config;
445
+	}
446
+
447
+
448
+	/**
449
+	 * called after the form is instantiated
450
+	 * and used for performing any logic that needs to occur early
451
+	 * before any of the other methods are called.
452
+	 * returns true if everything is ok to proceed,
453
+	 * and false if no further form logic should be implemented
454
+	 *
455
+	 * @return boolean
456
+	 */
457
+	public function initialize()
458
+	{
459
+		$this->form_has_errors = EE_Error::has_error(true);
460
+		return true;
461
+	}
462
+
463
+
464
+	/**
465
+	 * used for setting up css and js
466
+	 *
467
+	 * @return void
468
+	 * @throws LogicException
469
+	 * @throws EE_Error
470
+	 */
471
+	public function enqueueStylesAndScripts()
472
+	{
473
+		$this->form()->enqueue_js();
474
+	}
475
+
476
+
477
+	/**
478
+	 * creates and returns the actual form
479
+	 *
480
+	 * @return EE_Form_Section_Proper
481
+	 */
482
+	abstract public function generate();
483
+
484
+
485
+	/**
486
+	 * creates and returns an EE_Submit_Input labeled "Submit"
487
+	 *
488
+	 * @param string $text
489
+	 * @return EE_Submit_Input
490
+	 */
491
+	public function generateSubmitButton($text = '')
492
+	{
493
+		$text = ! empty($text) ? $text : $this->submitBtnText();
494
+		return new EE_Submit_Input(
495
+			array(
496
+				'html_name'             => 'ee-form-submit-' . $this->slug(),
497
+				'html_id'               => 'ee-form-submit-' . $this->slug(),
498
+				'html_class'            => 'ee-form-submit',
499
+				'html_label'            => '&nbsp;',
500
+				'other_html_attributes' => ' rel="' . $this->slug() . '"',
501
+				'default'               => $text,
502
+			)
503
+		);
504
+	}
505
+
506
+
507
+	/**
508
+	 * calls generateSubmitButton() and appends it onto the form along with a float clearing div
509
+	 *
510
+	 * @param string $text
511
+	 * @return void
512
+	 * @throws EE_Error
513
+	 */
514
+	public function appendSubmitButton($text = '')
515
+	{
516
+		if ($this->form->subsection_exists($this->slug() . '-submit-btn')) {
517
+			return;
518
+		}
519
+		$this->form->add_subsections(
520
+			array($this->slug() . '-submit-btn' => $this->generateSubmitButton($text)),
521
+			null,
522
+			false
523
+		);
524
+	}
525
+
526
+
527
+	/**
528
+	 * creates and returns an EE_Submit_Input labeled "Cancel"
529
+	 *
530
+	 * @param string $text
531
+	 * @return EE_Submit_Input
532
+	 */
533
+	public function generateCancelButton($text = '')
534
+	{
535
+		$cancel_button = new EE_Submit_Input(
536
+			array(
537
+				'html_name'             => 'ee-form-submit-' . $this->slug(), // YES! Same name as submit !!!
538
+				'html_id'               => 'ee-cancel-form-' . $this->slug(),
539
+				'html_class'            => 'ee-cancel-form',
540
+				'html_label'            => '&nbsp;',
541
+				'other_html_attributes' => ' rel="' . $this->slug() . '"',
542
+				'default'               => ! empty($text) ? $text : esc_html__('Cancel', 'event_espresso'),
543
+			)
544
+		);
545
+		$cancel_button->set_button_css_attributes(false);
546
+		return $cancel_button;
547
+	}
548
+
549
+
550
+	/**
551
+	 * appends a float clearing div onto end of form
552
+	 *
553
+	 * @return void
554
+	 * @throws EE_Error
555
+	 */
556
+	public function clearFormButtonFloats()
557
+	{
558
+		$this->form->add_subsections(
559
+			array(
560
+				'clear-submit-btn-float' => new EE_Form_Section_HTML(
561
+					EEH_HTML::div('', '', 'clear-float') . EEH_HTML::divx()
562
+				),
563
+			),
564
+			null,
565
+			false
566
+		);
567
+	}
568
+
569
+
570
+	/**
571
+	 * takes the generated form and displays it along with ony other non-form HTML that may be required
572
+	 * returns a string of HTML that can be directly echoed in a template
573
+	 *
574
+	 * @return string
575
+	 * @throws InvalidArgumentException
576
+	 * @throws InvalidInterfaceException
577
+	 * @throws InvalidDataTypeException
578
+	 * @throws LogicException
579
+	 * @throws EE_Error
580
+	 */
581
+	public function display()
582
+	{
583
+		$form_html = apply_filters(
584
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__display__before_form',
585
+			''
586
+		);
587
+		$form_config = $this->formConfig();
588
+		if (
589
+			$form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
590
+			|| $form_config === FormHandler::ADD_FORM_TAGS_ONLY
591
+		) {
592
+			$additional_props = $this->requiresMultipartEnctype()
593
+				? 'enctype="multipart/form-data"'
594
+				: '';
595
+			$form_html .= $this->form()->form_open(
596
+				$this->formAction(),
597
+				'POST',
598
+				$additional_props
599
+			);
600
+		}
601
+		$form_html .= $this->form(true)->get_html();
602
+		if (
603
+			$form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
604
+			|| $form_config === FormHandler::ADD_FORM_TAGS_ONLY
605
+		) {
606
+			$form_html .= $this->form()->form_close();
607
+		}
608
+		$form_html .= apply_filters(
609
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__display__after_form',
610
+			''
611
+		);
612
+		return $form_html;
613
+	}
614
+
615
+	/**
616
+	 * Determines if this form needs "enctype='multipart/form-data'" or not.
617
+	 * @since 4.9.80.p
618
+	 * @return bool
619
+	 * @throws EE_Error
620
+	 */
621
+	public function requiresMultipartEnctype()
622
+	{
623
+		foreach ($this->form()->inputs_in_subsections() as $input) {
624
+			if ($input instanceof EE_File_Input) {
625
+				return true;
626
+			}
627
+		}
628
+		return false;
629
+	}
630
+
631
+
632
+	/**
633
+	 * handles processing the form submission
634
+	 * returns true or false depending on whether the form was processed successfully or not
635
+	 *
636
+	 * @param array $submitted_form_data
637
+	 * @return array
638
+	 * @throws InvalidArgumentException
639
+	 * @throws InvalidInterfaceException
640
+	 * @throws InvalidDataTypeException
641
+	 * @throws EE_Error
642
+	 * @throws LogicException
643
+	 * @throws InvalidFormSubmissionException
644
+	 */
645
+	public function process($submitted_form_data = array())
646
+	{
647
+		if (! $this->form()->was_submitted($submitted_form_data)) {
648
+			throw new InvalidFormSubmissionException($this->form_name);
649
+		}
650
+		$this->form(true)->receive_form_submission($submitted_form_data);
651
+		if (! $this->form()->is_valid()) {
652
+			throw new InvalidFormSubmissionException(
653
+				$this->form_name,
654
+				sprintf(
655
+					esc_html__(
656
+						'The "%1$s" form is invalid. Please correct the following errors and resubmit: %2$s %3$s',
657
+						'event_espresso'
658
+					),
659
+					$this->form_name,
660
+					'<br />',
661
+					implode('<br />', $this->form()->get_validation_errors_accumulated())
662
+				)
663
+			);
664
+		}
665
+		return (array) apply_filters(
666
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__process__valid_data',
667
+			$this->form()->valid_data(),
668
+			$this
669
+		);
670
+	}
671 671
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/form_handlers/SequentialStepForm.php 1 patch
Indentation   +222 added lines, -222 removed lines patch added patch discarded remove patch
@@ -18,228 +18,228 @@
 block discarded – undo
18 18
  */
19 19
 abstract class SequentialStepForm extends FormHandler implements SequentialStepFormInterface
20 20
 {
21
-    const REDIRECT_TO_NEXT_STEP    = 'redirect_to_next_step';
22
-
23
-    const REDIRECT_TO_CURRENT_STEP = 'redirect_to_current_step';
24
-
25
-    const REDIRECT_TO_PREV_STEP    = 'redirect_to_prev_step';
26
-
27
-    const REDIRECT_TO_OTHER        = 'redirect_to_other';
28
-
29
-    /**
30
-     * numerical value used for sorting form steps
31
-     *
32
-     * @var int $order
33
-     */
34
-    private $order = 1;
35
-
36
-    /**
37
-     * a final URL with all form related parameters added
38
-     * that will be used to advance to the next step
39
-     *
40
-     * @var string $redirect_url
41
-     */
42
-    private $redirect_url = '';
43
-
44
-    /**
45
-     * URL params in key value pairs
46
-     *
47
-     * @var array $redirect_args
48
-     */
49
-    private $redirect_args = array();
50
-
51
-    /**
52
-     * Which step should be redirected to after form processing.
53
-     * Usually after successfully processing this value would be REDIRECT_TO_NEXT_STEP
54
-     * If a form is invalid and requires errors to be corrected,
55
-     * then this value would be REDIRECT_TO_CURRENT_STEP so that form can be resubmitted
56
-     * Some form handlers do not have a form that is displayable,
57
-     * and only perform data processing, but if an error occurs,
58
-     * then this value needs to be set to REDIRECT_TO_PREV_STEP
59
-     * since the current step has no displayable content.
60
-     * if the form is completely finished, and needs to redirect to somewhere
61
-     * completely different, then this value will be REDIRECT_TO_OTHER
62
-     *
63
-     * @var string $redirect_to
64
-     */
65
-    private $redirect_to = SequentialStepForm::REDIRECT_TO_CURRENT_STEP;
66
-
67
-
68
-
69
-    /**
70
-     * SequentialStepForm constructor
71
-     *
72
-     * @param int         $order
73
-     * @param string      $form_name
74
-     * @param string      $admin_name
75
-     * @param string      $slug
76
-     * @param string      $form_action
77
-     * @param string      $form_config
78
-     * @param EE_Registry|null $registry
79
-     * @throws InvalidArgumentException
80
-     * @throws InvalidDataTypeException
81
-     * @throws DomainException
82
-     */
83
-    public function __construct(
84
-        $order,
85
-        $form_name,
86
-        $admin_name,
87
-        $slug,
88
-        $form_action = '',
89
-        $form_config = 'add_form_tags_and_submit',
90
-        ?EE_Registry $registry = null
91
-    ) {
92
-        $this->setOrder($order);
93
-        parent::__construct($form_name, $admin_name, $slug, $form_action, $form_config, $registry);
94
-    }
95
-
96
-
97
-
98
-    /**
99
-     * @return int
100
-     */
101
-    public function order()
102
-    {
103
-        return $this->order;
104
-    }
105
-
106
-
107
-
108
-    /**
109
-     * @param int $order
110
-     * @throws InvalidArgumentException
111
-     */
112
-    public function setOrder($order)
113
-    {
114
-        $order = absint($order);
115
-        if (! $order > 0) {
116
-            throw new InvalidArgumentException(
117
-                esc_html__('The form order property must be a positive integer.', 'event_espresso')
118
-            );
119
-        }
120
-        $this->order = $order;
121
-    }
122
-
123
-
124
-
125
-    /**
126
-     * @return string
127
-     */
128
-    public function redirectUrl()
129
-    {
130
-        return ! empty($this->redirect_args)
131
-            ? add_query_arg($this->redirect_args, $this->redirect_url)
132
-            : $this->redirect_url;
133
-    }
134
-
135
-
136
-
137
-    /**
138
-     * @param string $redirect_url
139
-     * @throws InvalidDataTypeException
140
-     * @throws InvalidArgumentException
141
-     */
142
-    public function setRedirectUrl($redirect_url)
143
-    {
144
-        if (! is_string($redirect_url)) {
145
-            throw new InvalidDataTypeException('$redirect_url', $redirect_url, 'string');
146
-        }
147
-        if (empty($redirect_url)) {
148
-            throw new InvalidArgumentException(
149
-                esc_html__('The redirect URL can not be an empty string.', 'event_espresso')
150
-            );
151
-        }
152
-        $this->redirect_url = $redirect_url;
153
-    }
154
-
155
-
156
-
157
-    /**
158
-     * @param array $redirect_args
159
-     * @throws InvalidDataTypeException
160
-     * @throws InvalidArgumentException
161
-     */
162
-    public function addRedirectArgs($redirect_args = array())
163
-    {
164
-        if (is_object($redirect_args)) {
165
-            throw new InvalidDataTypeException(
166
-                '$redirect_args',
167
-                $redirect_args,
168
-                'anything other than an object was expected.'
169
-            );
170
-        }
171
-        if (empty($redirect_args)) {
172
-            throw new InvalidArgumentException(
173
-                esc_html__('The redirect argument can not be an empty array.', 'event_espresso')
174
-            );
175
-        }
176
-        $this->redirect_args = array_merge($this->redirect_args, (array) $redirect_args);
177
-    }
178
-
179
-
180
-
181
-    /**
182
-     * @param array $redirect_arg_keys_to_remove
183
-     * @throws InvalidDataTypeException
184
-     * @throws InvalidArgumentException
185
-     */
186
-    public function removeRedirectArgs($redirect_arg_keys_to_remove = array())
187
-    {
188
-        if (is_object($redirect_arg_keys_to_remove)) {
189
-            throw new InvalidDataTypeException(
190
-                '$redirect_arg_keys_to_remove',
191
-                $redirect_arg_keys_to_remove,
192
-                'anything other than an object was expected.'
193
-            );
194
-        }
195
-        if (empty($redirect_arg_keys_to_remove)) {
196
-            throw new InvalidArgumentException(
197
-                esc_html__('The $redirect_arg_keys_to_remove argument can not be an empty array.', 'event_espresso')
198
-            );
199
-        }
200
-        foreach ($redirect_arg_keys_to_remove as $redirect_arg_key) {
201
-            unset($this->redirect_args[ $redirect_arg_key ]);
202
-        }
203
-    }
204
-
205
-
206
-
207
-    /**
208
-     * @return string
209
-     */
210
-    public function redirectTo()
211
-    {
212
-        return $this->redirect_to;
213
-    }
214
-
215
-
216
-
217
-    /**
218
-     * @param string $redirect_to
219
-     * @throws InvalidDataTypeException
220
-     */
221
-    public function setRedirectTo($redirect_to)
222
-    {
223
-        if (
224
-            ! in_array(
225
-                $redirect_to,
226
-                array(
227
-                    SequentialStepForm::REDIRECT_TO_NEXT_STEP,
228
-                    SequentialStepForm::REDIRECT_TO_CURRENT_STEP,
229
-                    SequentialStepForm::REDIRECT_TO_PREV_STEP,
230
-                    SequentialStepForm::REDIRECT_TO_OTHER,
231
-                ),
232
-                true
233
-            )
234
-        ) {
235
-            throw new InvalidDataTypeException(
236
-                'setRedirectTo()',
237
-                $redirect_to,
238
-                'one of the SequentialStepForm class constants was expected.'
239
-            );
240
-        }
241
-        $this->redirect_to = $redirect_to;
242
-    }
21
+	const REDIRECT_TO_NEXT_STEP    = 'redirect_to_next_step';
22
+
23
+	const REDIRECT_TO_CURRENT_STEP = 'redirect_to_current_step';
24
+
25
+	const REDIRECT_TO_PREV_STEP    = 'redirect_to_prev_step';
26
+
27
+	const REDIRECT_TO_OTHER        = 'redirect_to_other';
28
+
29
+	/**
30
+	 * numerical value used for sorting form steps
31
+	 *
32
+	 * @var int $order
33
+	 */
34
+	private $order = 1;
35
+
36
+	/**
37
+	 * a final URL with all form related parameters added
38
+	 * that will be used to advance to the next step
39
+	 *
40
+	 * @var string $redirect_url
41
+	 */
42
+	private $redirect_url = '';
43
+
44
+	/**
45
+	 * URL params in key value pairs
46
+	 *
47
+	 * @var array $redirect_args
48
+	 */
49
+	private $redirect_args = array();
50
+
51
+	/**
52
+	 * Which step should be redirected to after form processing.
53
+	 * Usually after successfully processing this value would be REDIRECT_TO_NEXT_STEP
54
+	 * If a form is invalid and requires errors to be corrected,
55
+	 * then this value would be REDIRECT_TO_CURRENT_STEP so that form can be resubmitted
56
+	 * Some form handlers do not have a form that is displayable,
57
+	 * and only perform data processing, but if an error occurs,
58
+	 * then this value needs to be set to REDIRECT_TO_PREV_STEP
59
+	 * since the current step has no displayable content.
60
+	 * if the form is completely finished, and needs to redirect to somewhere
61
+	 * completely different, then this value will be REDIRECT_TO_OTHER
62
+	 *
63
+	 * @var string $redirect_to
64
+	 */
65
+	private $redirect_to = SequentialStepForm::REDIRECT_TO_CURRENT_STEP;
66
+
67
+
68
+
69
+	/**
70
+	 * SequentialStepForm constructor
71
+	 *
72
+	 * @param int         $order
73
+	 * @param string      $form_name
74
+	 * @param string      $admin_name
75
+	 * @param string      $slug
76
+	 * @param string      $form_action
77
+	 * @param string      $form_config
78
+	 * @param EE_Registry|null $registry
79
+	 * @throws InvalidArgumentException
80
+	 * @throws InvalidDataTypeException
81
+	 * @throws DomainException
82
+	 */
83
+	public function __construct(
84
+		$order,
85
+		$form_name,
86
+		$admin_name,
87
+		$slug,
88
+		$form_action = '',
89
+		$form_config = 'add_form_tags_and_submit',
90
+		?EE_Registry $registry = null
91
+	) {
92
+		$this->setOrder($order);
93
+		parent::__construct($form_name, $admin_name, $slug, $form_action, $form_config, $registry);
94
+	}
95
+
96
+
97
+
98
+	/**
99
+	 * @return int
100
+	 */
101
+	public function order()
102
+	{
103
+		return $this->order;
104
+	}
105
+
106
+
107
+
108
+	/**
109
+	 * @param int $order
110
+	 * @throws InvalidArgumentException
111
+	 */
112
+	public function setOrder($order)
113
+	{
114
+		$order = absint($order);
115
+		if (! $order > 0) {
116
+			throw new InvalidArgumentException(
117
+				esc_html__('The form order property must be a positive integer.', 'event_espresso')
118
+			);
119
+		}
120
+		$this->order = $order;
121
+	}
122
+
123
+
124
+
125
+	/**
126
+	 * @return string
127
+	 */
128
+	public function redirectUrl()
129
+	{
130
+		return ! empty($this->redirect_args)
131
+			? add_query_arg($this->redirect_args, $this->redirect_url)
132
+			: $this->redirect_url;
133
+	}
134
+
135
+
136
+
137
+	/**
138
+	 * @param string $redirect_url
139
+	 * @throws InvalidDataTypeException
140
+	 * @throws InvalidArgumentException
141
+	 */
142
+	public function setRedirectUrl($redirect_url)
143
+	{
144
+		if (! is_string($redirect_url)) {
145
+			throw new InvalidDataTypeException('$redirect_url', $redirect_url, 'string');
146
+		}
147
+		if (empty($redirect_url)) {
148
+			throw new InvalidArgumentException(
149
+				esc_html__('The redirect URL can not be an empty string.', 'event_espresso')
150
+			);
151
+		}
152
+		$this->redirect_url = $redirect_url;
153
+	}
154
+
155
+
156
+
157
+	/**
158
+	 * @param array $redirect_args
159
+	 * @throws InvalidDataTypeException
160
+	 * @throws InvalidArgumentException
161
+	 */
162
+	public function addRedirectArgs($redirect_args = array())
163
+	{
164
+		if (is_object($redirect_args)) {
165
+			throw new InvalidDataTypeException(
166
+				'$redirect_args',
167
+				$redirect_args,
168
+				'anything other than an object was expected.'
169
+			);
170
+		}
171
+		if (empty($redirect_args)) {
172
+			throw new InvalidArgumentException(
173
+				esc_html__('The redirect argument can not be an empty array.', 'event_espresso')
174
+			);
175
+		}
176
+		$this->redirect_args = array_merge($this->redirect_args, (array) $redirect_args);
177
+	}
178
+
179
+
180
+
181
+	/**
182
+	 * @param array $redirect_arg_keys_to_remove
183
+	 * @throws InvalidDataTypeException
184
+	 * @throws InvalidArgumentException
185
+	 */
186
+	public function removeRedirectArgs($redirect_arg_keys_to_remove = array())
187
+	{
188
+		if (is_object($redirect_arg_keys_to_remove)) {
189
+			throw new InvalidDataTypeException(
190
+				'$redirect_arg_keys_to_remove',
191
+				$redirect_arg_keys_to_remove,
192
+				'anything other than an object was expected.'
193
+			);
194
+		}
195
+		if (empty($redirect_arg_keys_to_remove)) {
196
+			throw new InvalidArgumentException(
197
+				esc_html__('The $redirect_arg_keys_to_remove argument can not be an empty array.', 'event_espresso')
198
+			);
199
+		}
200
+		foreach ($redirect_arg_keys_to_remove as $redirect_arg_key) {
201
+			unset($this->redirect_args[ $redirect_arg_key ]);
202
+		}
203
+	}
204
+
205
+
206
+
207
+	/**
208
+	 * @return string
209
+	 */
210
+	public function redirectTo()
211
+	{
212
+		return $this->redirect_to;
213
+	}
214
+
215
+
216
+
217
+	/**
218
+	 * @param string $redirect_to
219
+	 * @throws InvalidDataTypeException
220
+	 */
221
+	public function setRedirectTo($redirect_to)
222
+	{
223
+		if (
224
+			! in_array(
225
+				$redirect_to,
226
+				array(
227
+					SequentialStepForm::REDIRECT_TO_NEXT_STEP,
228
+					SequentialStepForm::REDIRECT_TO_CURRENT_STEP,
229
+					SequentialStepForm::REDIRECT_TO_PREV_STEP,
230
+					SequentialStepForm::REDIRECT_TO_OTHER,
231
+				),
232
+				true
233
+			)
234
+		) {
235
+			throw new InvalidDataTypeException(
236
+				'setRedirectTo()',
237
+				$redirect_to,
238
+				'one of the SequentialStepForm class constants was expected.'
239
+			);
240
+		}
241
+		$this->redirect_to = $redirect_to;
242
+	}
243 243
 }
244 244
 // End of file SequentialStepForm.php
245 245
 // Location: /SequentialStepForm.php
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Form_Input_Base.input.php 1 patch
Indentation   +1255 added lines, -1255 removed lines patch added patch discarded remove patch
@@ -14,1259 +14,1259 @@
 block discarded – undo
14 14
  */
15 15
 abstract class EE_Form_Input_Base extends EE_Form_Section_Validatable
16 16
 {
17
-    /**
18
-     * the input's name attribute
19
-     *
20
-     * @var string
21
-     */
22
-    protected $_html_name;
23
-
24
-    /**
25
-     * id for the html label tag
26
-     *
27
-     * @var string
28
-     */
29
-    protected $_html_label_id;
30
-
31
-    /**
32
-     * class for teh html label tag
33
-     *
34
-     * @var string
35
-     */
36
-    protected $_html_label_class;
37
-
38
-    /**
39
-     * style for teh html label tag
40
-     *
41
-     * @var string
42
-     */
43
-    protected $_html_label_style;
44
-
45
-    /**
46
-     * text to be placed in the html label
47
-     *
48
-     * @var string
49
-     */
50
-    protected $_html_label_text;
51
-
52
-    /**
53
-     * the full html label. If used, all other html_label_* properties are invalid
54
-     *
55
-     * @var string
56
-     */
57
-    protected $_html_label;
58
-
59
-    /**
60
-     * HTML to use for help text (normally placed below form input), in a span which normally
61
-     * has a class of 'description'
62
-     *
63
-     * @var string
64
-     */
65
-    protected $_html_help_text;
66
-
67
-    /**
68
-     * CSS classes for displaying the help span
69
-     *
70
-     * @var string
71
-     */
72
-    protected $_html_help_class = 'description';
73
-
74
-    /**
75
-     * CSS to put in the style attribute on the help span
76
-     *
77
-     * @var string
78
-     */
79
-    protected $_html_help_style;
80
-
81
-    /**
82
-     * Stores whether or not this input's response is required.
83
-     * Because certain styling elements may also want to know that this
84
-     * input is required etc.
85
-     *
86
-     * @var boolean
87
-     */
88
-    protected $_required;
89
-
90
-    /**
91
-     * css class added to required inputs
92
-     *
93
-     * @var string
94
-     */
95
-    protected $_required_css_class = 'ee-required';
96
-
97
-    /**
98
-     * css styles applied to button type inputs
99
-     *
100
-     * @var string
101
-     */
102
-    protected $_button_css_attributes;
103
-
104
-    /**
105
-     * The raw post data submitted for this
106
-     * Generally unsafe for usage in client code
107
-     *
108
-     * @var mixed string or array
109
-     */
110
-    protected $_raw_value;
111
-
112
-    /**
113
-     * Value normalized according to the input's normalization strategy.
114
-     * The normalization strategy dictates whether this is a string, int, float,
115
-     * boolean, or array of any of those.
116
-     *
117
-     * @var mixed
118
-     */
119
-    protected $_normalized_value;
120
-
121
-
122
-    /**
123
-     * Normalized default value either initially set on the input, or provided by calling
124
-     * set_default().
125
-     * @var mixed
126
-     */
127
-    protected $_default;
128
-
129
-    /**
130
-     * Strategy used for displaying this field.
131
-     * Child classes must use _get_display_strategy to access it.
132
-     *
133
-     * @var EE_Display_Strategy_Base
134
-     */
135
-    private $_display_strategy;
136
-
137
-    /**
138
-     * Gets all the validation strategies used on this field
139
-     *
140
-     * @var EE_Validation_Strategy_Base[]
141
-     */
142
-    private $_validation_strategies = array();
143
-
144
-    /**
145
-     * The normalization strategy for this field
146
-     *
147
-     * @var EE_Normalization_Strategy_Base
148
-     */
149
-    private $_normalization_strategy;
150
-
151
-    /**
152
-     * Strategy for removing sensitive data after we're done with the form input
153
-     *
154
-     * @var EE_Sensitive_Data_Removal_Base
155
-     */
156
-    protected $_sensitive_data_removal_strategy;
157
-
158
-    /**
159
-     * Whether this input has been disabled or not.
160
-     * If it's disabled while rendering, an extra hidden input is added that indicates it has been knowingly disabled.
161
-     * (Client-side code that wants to dynamically disable it must also add this hidden input).
162
-     * When the form is submitted, if the input is disabled in the PHP form section, then input is ignored.
163
-     * If the input is missing from the request data but the hidden input indicating the input is disabled, then the input is again ignored.
164
-     *
165
-     * @var boolean
166
-     */
167
-    protected $disabled = false;
168
-
169
-
170
-
171
-    /**
172
-     * @param array                         $input_args       {
173
-     * @type string                         $html_name        the html name for the input
174
-     * @type string                         $html_label_id    the id attribute to give to the html label tag
175
-     * @type string                         $html_label_class the class attribute to give to the html label tag
176
-     * @type string                         $html_label_style the style attribute to give ot teh label tag
177
-     * @type string                         $html_label_text  the text to put in the label tag
178
-     * @type string                         $html_label       the full html label. If used,
179
-     *                                                        all other html_label_* args are invalid
180
-     * @type string                         $html_help_text   text to put in help element
181
-     * @type string                         $html_help_style  style attribute to give to teh help element
182
-     * @type string                         $html_help_class  class attribute to give to the help element
183
-     * @type string                         $default          default value NORMALIZED (eg, if providing the default
184
-     *       for a Yes_No_Input, you should provide TRUE or FALSE, not '1' or '0')
185
-     * @type EE_Display_Strategy_Base       $display          strategy
186
-     * @type EE_Normalization_Strategy_Base $normalization_strategy
187
-     * @type EE_Validation_Strategy_Base[]  $validation_strategies
188
-     * @type boolean                        $ignore_input special argument which can be used to avoid adding any validation strategies,
189
-     *                                                    and sets the normalization strategy to the Null normalization. This is good
190
-     *                                                    when you want the input to be totally ignored server-side (like when using
191
-     *                                                    React.js form inputs)
192
-     *                                                        }
193
-     */
194
-    public function __construct($input_args = array())
195
-    {
196
-        $input_args = (array) apply_filters('FHEE__EE_Form_Input_Base___construct__input_args', $input_args, $this);
197
-        // the following properties must be cast as arrays
198
-        if (isset($input_args['validation_strategies'])) {
199
-            foreach ((array) $input_args['validation_strategies'] as $validation_strategy) {
200
-                if ($validation_strategy instanceof EE_Validation_Strategy_Base && empty($input_args['ignore_input'])) {
201
-                    $this->_validation_strategies[ get_class($validation_strategy) ] = $validation_strategy;
202
-                }
203
-            }
204
-            unset($input_args['validation_strategies']);
205
-        }
206
-        if (isset($input_args['ignore_input'])) {
207
-            $this->_validation_strategies = array();
208
-        }
209
-        // loop thru incoming options
210
-        foreach ($input_args as $key => $value) {
211
-            // add underscore to $key to match property names
212
-            $_key = '_' . $key;
213
-            if (property_exists($this, $_key)) {
214
-                $this->{$_key} = $value;
215
-            }
216
-        }
217
-        // ensure that "required" is set correctly
218
-        $this->set_required(
219
-            $this->_required,
220
-            $input_args['required_validation_error_message'] ?? null
221
-        );
222
-        // $this->_html_name_specified = isset( $input_args['html_name'] ) ? TRUE : FALSE;
223
-        $this->_display_strategy->_construct_finalize($this);
224
-        foreach ($this->_validation_strategies as $validation_strategy) {
225
-            $validation_strategy->_construct_finalize($this);
226
-        }
227
-        if (isset($input_args['ignore_input'])) {
228
-            $this->_normalization_strategy = new EE_Null_Normalization();
229
-        }
230
-        if (! $this->_normalization_strategy) {
231
-                $this->_normalization_strategy = new EE_Text_Normalization();
232
-        }
233
-        $this->_normalization_strategy->_construct_finalize($this);
234
-        // at least we can use the normalization strategy to populate the default
235
-        if (isset($input_args['default'])) {
236
-            $this->set_default($input_args['default']);
237
-            unset($input_args['default']);
238
-        }
239
-        if (! $this->_sensitive_data_removal_strategy) {
240
-            $this->_sensitive_data_removal_strategy = new EE_No_Sensitive_Data_Removal();
241
-        }
242
-        $this->_sensitive_data_removal_strategy->_construct_finalize($this);
243
-        parent::__construct($input_args);
244
-    }
245
-
246
-
247
-
248
-    /**
249
-     * Sets the html_name to its default value, if none was specified in teh constructor.
250
-     * Calculation involves using the name and the parent's html_name
251
-     *
252
-     * @throws EE_Error
253
-     */
254
-    protected function _set_default_html_name_if_empty()
255
-    {
256
-        if (! $this->_html_name) {
257
-            $this->_html_name = $this->name();
258
-            if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
259
-                $this->_html_name = $this->_parent_section->html_name_prefix() . "[{$this->name()}]";
260
-            }
261
-        }
262
-    }
263
-
264
-
265
-
266
-    /**
267
-     * @param $parent_form_section
268
-     * @param $name
269
-     * @throws EE_Error
270
-     */
271
-    public function _construct_finalize($parent_form_section, $name)
272
-    {
273
-        parent::_construct_finalize($parent_form_section, $name);
274
-        if ($this->_html_label === null && $this->_html_label_text === null) {
275
-            $this->_html_label_text = ucwords(str_replace("_", " ", $name));
276
-        }
277
-        do_action('AHEE__EE_Form_Input_Base___construct_finalize__end', $this, $parent_form_section, $name);
278
-    }
279
-
280
-
281
-
282
-    /**
283
-     * Returns the strategy for displaying this form input. If none is set, throws an exception.
284
-     *
285
-     * @return EE_Display_Strategy_Base
286
-     * @throws EE_Error
287
-     */
288
-    protected function _get_display_strategy()
289
-    {
290
-        $this->ensure_construct_finalized_called();
291
-        if (! $this->_display_strategy || ! $this->_display_strategy instanceof EE_Display_Strategy_Base) {
292
-            throw new EE_Error(
293
-                sprintf(
294
-                    esc_html__(
295
-                        "Cannot get display strategy for form input with name %s and id %s, because it has not been set in the constructor",
296
-                        "event_espresso"
297
-                    ),
298
-                    $this->html_name(),
299
-                    $this->html_id()
300
-                )
301
-            );
302
-        } else {
303
-            return $this->_display_strategy;
304
-        }
305
-    }
306
-
307
-
308
-
309
-    /**
310
-     * Sets the display strategy.
311
-     *
312
-     * @param EE_Display_Strategy_Base $strategy
313
-     */
314
-    protected function _set_display_strategy(EE_Display_Strategy_Base $strategy)
315
-    {
316
-        $this->_display_strategy = $strategy;
317
-    }
318
-
319
-
320
-
321
-    /**
322
-     * Sets the sanitization strategy
323
-     *
324
-     * @param EE_Normalization_Strategy_Base $strategy
325
-     */
326
-    protected function _set_normalization_strategy(EE_Normalization_Strategy_Base $strategy)
327
-    {
328
-        $this->_normalization_strategy = $strategy;
329
-    }
330
-
331
-
332
-
333
-    /**
334
-     * Gets sensitive_data_removal_strategy
335
-     *
336
-     * @return EE_Sensitive_Data_Removal_Base
337
-     */
338
-    public function get_sensitive_data_removal_strategy()
339
-    {
340
-        return $this->_sensitive_data_removal_strategy;
341
-    }
342
-
343
-
344
-
345
-    /**
346
-     * Sets sensitive_data_removal_strategy
347
-     *
348
-     * @param EE_Sensitive_Data_Removal_Base $sensitive_data_removal_strategy
349
-     * @return void
350
-     */
351
-    public function set_sensitive_data_removal_strategy($sensitive_data_removal_strategy)
352
-    {
353
-        $this->_sensitive_data_removal_strategy = $sensitive_data_removal_strategy;
354
-    }
355
-
356
-
357
-
358
-    /**
359
-     * Gets the display strategy for this input
360
-     *
361
-     * @return EE_Display_Strategy_Base
362
-     */
363
-    public function get_display_strategy()
364
-    {
365
-        return $this->_display_strategy;
366
-    }
367
-
368
-
369
-
370
-    /**
371
-     * Overwrites the display strategy
372
-     *
373
-     * @param EE_Display_Strategy_Base $display_strategy
374
-     */
375
-    public function set_display_strategy($display_strategy)
376
-    {
377
-        $this->_display_strategy = $display_strategy;
378
-        $this->_display_strategy->_construct_finalize($this);
379
-    }
380
-
381
-
382
-
383
-    /**
384
-     * Gets the normalization strategy set on this input
385
-     *
386
-     * @return EE_Normalization_Strategy_Base
387
-     */
388
-    public function get_normalization_strategy()
389
-    {
390
-        return $this->_normalization_strategy;
391
-    }
392
-
393
-
394
-
395
-    /**
396
-     * Overwrites the normalization strategy
397
-     *
398
-     * @param EE_Normalization_Strategy_Base $normalization_strategy
399
-     */
400
-    public function set_normalization_strategy($normalization_strategy)
401
-    {
402
-        $this->_normalization_strategy = $normalization_strategy;
403
-        $this->_normalization_strategy->_construct_finalize($this);
404
-    }
405
-
406
-
407
-
408
-    /**
409
-     * Returns all teh validation strategies which apply to this field, numerically indexed
410
-     *
411
-     * @return EE_Validation_Strategy_Base[]
412
-     */
413
-    public function get_validation_strategies()
414
-    {
415
-        return $this->_validation_strategies;
416
-    }
417
-
418
-
419
-
420
-    /**
421
-     * Adds this strategy to the field so it will be used in both JS validation and server-side validation
422
-     *
423
-     * @param EE_Validation_Strategy_Base $validation_strategy
424
-     * @return void
425
-     */
426
-    protected function _add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
427
-    {
428
-        $validation_strategy->_construct_finalize($this);
429
-        $this->_validation_strategies[] = $validation_strategy;
430
-    }
431
-
432
-
433
-
434
-    /**
435
-     * Adds a new validation strategy onto the form input
436
-     *
437
-     * @param EE_Validation_Strategy_Base $validation_strategy
438
-     * @return void
439
-     */
440
-    public function add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
441
-    {
442
-        $this->_add_validation_strategy($validation_strategy);
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     * The classname of the validation strategy to remove
449
-     *
450
-     * @param string $validation_strategy_classname
451
-     */
452
-    public function remove_validation_strategy($validation_strategy_classname)
453
-    {
454
-        foreach ($this->_validation_strategies as $key => $validation_strategy) {
455
-            if (
456
-                $validation_strategy instanceof $validation_strategy_classname
457
-                || is_subclass_of($validation_strategy, $validation_strategy_classname)
458
-            ) {
459
-                unset($this->_validation_strategies[ $key ]);
460
-            }
461
-        }
462
-    }
463
-
464
-
465
-
466
-    /**
467
-     * returns true if input employs any of the validation strategy defined by the supplied array of classnames
468
-     *
469
-     * @param array $validation_strategy_classnames
470
-     * @return bool
471
-     */
472
-    public function has_validation_strategy($validation_strategy_classnames)
473
-    {
474
-        $validation_strategy_classnames = is_array($validation_strategy_classnames)
475
-            ? $validation_strategy_classnames
476
-            : array($validation_strategy_classnames);
477
-        foreach ($this->_validation_strategies as $key => $validation_strategy) {
478
-            if (in_array($key, $validation_strategy_classnames)) {
479
-                return true;
480
-            }
481
-        }
482
-        return false;
483
-    }
484
-
485
-
486
-
487
-    /**
488
-     * Gets the HTML
489
-     *
490
-     * @return string
491
-     */
492
-    public function get_html()
493
-    {
494
-        return $this->_parent_section->get_html_for_input($this);
495
-    }
496
-
497
-
498
-
499
-    /**
500
-     * Gets the HTML for the input itself (no label or errors) according to the
501
-     * input's display strategy
502
-     * Makes sure the JS and CSS are enqueued for it
503
-     *
504
-     * @return string
505
-     * @throws EE_Error
506
-     */
507
-    public function get_html_for_input()
508
-    {
509
-        return $this->_form_html_filter
510
-            ? $this->_form_html_filter->filterHtml(
511
-                $this->_get_display_strategy()->display(),
512
-                $this
513
-            )
514
-            : $this->_get_display_strategy()->display();
515
-    }
516
-
517
-
518
-
519
-    /**
520
-     * @return string
521
-     */
522
-    public function html_other_attributes()
523
-    {
524
-        EE_Error::doing_it_wrong(
525
-            __METHOD__,
526
-            sprintf(
527
-                esc_html__(
528
-                    'This method is no longer in use. You should replace it by %s',
529
-                    'event_espresso'
530
-                ),
531
-                'EE_Form_Section_Base::other_html_attributes()'
532
-            ),
533
-            '4.10.2.p'
534
-        );
535
-
536
-        return $this->other_html_attributes();
537
-    }
538
-
539
-
540
-
541
-    /**
542
-     * @param string $html_other_attributes
543
-     */
544
-    public function set_html_other_attributes($html_other_attributes)
545
-    {
546
-        EE_Error::doing_it_wrong(
547
-            __METHOD__,
548
-            sprintf(
549
-                esc_html__(
550
-                    'This method is no longer in use. You should replace it by %s',
551
-                    'event_espresso'
552
-                ),
553
-                'EE_Form_Section_Base::set_other_html_attributes()'
554
-            ),
555
-            '4.10.2.p'
556
-        );
557
-
558
-        $this->set_other_html_attributes($html_other_attributes);
559
-    }
560
-
561
-
562
-
563
-    /**
564
-     * Gets the HTML for displaying the label for this form input
565
-     * according to the form section's layout strategy
566
-     *
567
-     * @return string
568
-     */
569
-    public function get_html_for_label()
570
-    {
571
-        return $this->_parent_section->get_layout_strategy()->display_label($this);
572
-    }
573
-
574
-
575
-
576
-    /**
577
-     * Gets the HTML for displaying the errors section for this form input
578
-     * according to the form section's layout strategy
579
-     *
580
-     * @return string
581
-     */
582
-    public function get_html_for_errors()
583
-    {
584
-        return $this->_parent_section->get_layout_strategy()->display_errors($this);
585
-    }
586
-
587
-
588
-
589
-    /**
590
-     * Gets the HTML for displaying the help text for this form input
591
-     * according to the form section's layout strategy
592
-     *
593
-     * @return string
594
-     */
595
-    public function get_html_for_help()
596
-    {
597
-        return $this->_parent_section->get_layout_strategy()->display_help_text($this);
598
-    }
599
-
600
-
601
-
602
-    /**
603
-     * Validates the input's sanitized value (assumes _sanitize() has already been called)
604
-     * and returns whether or not the form input's submitted value is value
605
-     *
606
-     * @return boolean
607
-     */
608
-    protected function _validate()
609
-    {
610
-        if ($this->isDisabled()) {
611
-            return true;
612
-        }
613
-        foreach ($this->_validation_strategies as $validation_strategy) {
614
-            if ($validation_strategy instanceof EE_Validation_Strategy_Base) {
615
-                try {
616
-                    $validation_strategy->validate($this->normalized_value());
617
-                } catch (EE_Validation_Error $e) {
618
-                    $this->add_validation_error($e);
619
-                }
620
-            }
621
-        }
622
-        if ($this->get_validation_errors()) {
623
-            return false;
624
-        } else {
625
-            return true;
626
-        }
627
-    }
628
-
629
-
630
-
631
-    /**
632
-     * Performs basic sanitization on this value. But what sanitization can be performed anyways?
633
-     * This value MIGHT be allowed to have tags, so we can't really remove them.
634
-     *
635
-     * @param string $value
636
-     * @return null|string
637
-     */
638
-    protected function _sanitize($value)
639
-    {
640
-        return $value !== null ? stripslashes(html_entity_decode(trim($value))) : null;
641
-    }
642
-
643
-
644
-
645
-    /**
646
-     * Picks out the form value that relates to this form input,
647
-     * and stores it as the sanitized value on the form input, and sets the normalized value.
648
-     * Returns whether or not any validation errors occurred
649
-     *
650
-     * @param array $req_data
651
-     * @return boolean whether or not there was an error
652
-     * @throws EE_Error
653
-     */
654
-    protected function _normalize($req_data)
655
-    {
656
-        // any existing validation errors don't apply so clear them
657
-        $this->_validation_errors = array();
658
-        // if the input is disabled, ignore whatever input was sent in
659
-        if ($this->isDisabled()) {
660
-            $this->_set_raw_value(null);
661
-            $this->_set_normalized_value($this->get_default());
662
-            return false;
663
-        }
664
-        try {
665
-            $raw_input = $this->find_form_data_for_this_section($req_data);
666
-            // super simple sanitization for now
667
-            if (is_array($raw_input)) {
668
-                $raw_value = array();
669
-                foreach ($raw_input as $key => $value) {
670
-                    $raw_value[ $key ] = $this->_sanitize($value);
671
-                }
672
-                $this->_set_raw_value($raw_value);
673
-            } else {
674
-                $this->_set_raw_value($this->_sanitize($raw_input));
675
-            }
676
-            // we want to mostly leave the input alone in case we need to re-display it to the user
677
-            $this->_set_normalized_value($this->_normalization_strategy->normalize($this->raw_value()));
678
-            return false;
679
-        } catch (EE_Validation_Error $e) {
680
-            $this->add_validation_error($e);
681
-            return true;
682
-        }
683
-    }
684
-
685
-
686
-    /**
687
-     * @return string
688
-     * @throws EE_Error
689
-     */
690
-    public function html_name()
691
-    {
692
-        $this->_set_default_html_name_if_empty();
693
-        return $this->_html_name;
694
-    }
695
-
696
-
697
-    /**
698
-     * @return string
699
-     * @throws EE_Error
700
-     */
701
-    public function html_label_id()
702
-    {
703
-        return ! empty($this->_html_label_id) ? $this->_html_label_id : $this->html_id() . '-lbl';
704
-    }
705
-
706
-
707
-
708
-    /**
709
-     * @return string
710
-     */
711
-    public function html_label_class()
712
-    {
713
-        return $this->_html_label_class;
714
-    }
715
-
716
-
717
-
718
-    /**
719
-     * @return string
720
-     */
721
-    public function html_label_style()
722
-    {
723
-        return $this->_html_label_style;
724
-    }
725
-
726
-
727
-
728
-    /**
729
-     * @return string
730
-     */
731
-    public function html_label_text()
732
-    {
733
-        return $this->_html_label_text;
734
-    }
735
-
736
-
737
-
738
-    /**
739
-     * @return string
740
-     */
741
-    public function html_help_text()
742
-    {
743
-        return $this->_html_help_text;
744
-    }
745
-
746
-
747
-
748
-    /**
749
-     * @return string
750
-     */
751
-    public function html_help_class()
752
-    {
753
-        return $this->_html_help_class;
754
-    }
755
-
756
-
757
-
758
-    /**
759
-     * @return string
760
-     */
761
-    public function html_help_style()
762
-    {
763
-        return $this->_html_style;
764
-    }
765
-
766
-
767
-
768
-    /**
769
-     * returns the raw, UNSAFE, input, almost exactly as the user submitted it.
770
-     * Please note that almost all client code should instead use the normalized_value;
771
-     * or possibly raw_value_in_form (which prepares the string for displaying in an HTML attribute on a tag,
772
-     * mostly by escaping quotes)
773
-     * Note, we do not store the exact original value sent in the user's request because
774
-     * it may have malicious content, and we MIGHT want to store the form input in a transient or something...
775
-     * in which case, we would have stored the malicious content to our database.
776
-     *
777
-     * @return string
778
-     */
779
-    public function raw_value()
780
-    {
781
-        return $this->_raw_value;
782
-    }
783
-
784
-
785
-
786
-    /**
787
-     * Returns a string safe to usage in form inputs when displaying, because
788
-     * it escapes all html entities
789
-     *
790
-     * @return string
791
-     */
792
-    public function raw_value_in_form()
793
-    {
794
-        return htmlentities($this->raw_value(), ENT_QUOTES, 'UTF-8');
795
-    }
796
-
797
-
798
-
799
-    /**
800
-     * returns the value after it's been sanitized, and then converted into it's proper type
801
-     * in PHP. Eg, a string, an int, an array,
802
-     *
803
-     * @return mixed
804
-     */
805
-    public function normalized_value()
806
-    {
807
-        return $this->_normalized_value;
808
-    }
809
-
810
-
811
-
812
-    /**
813
-     * Returns the normalized value is a presentable way. By default this is just
814
-     * the normalized value by itself, but it can be overridden for when that's not
815
-     * the best thing to display
816
-     *
817
-     * @return string
818
-     */
819
-    public function pretty_value()
820
-    {
821
-        return $this->_normalized_value;
822
-    }
823
-
824
-
825
-
826
-    /**
827
-     * When generating the JS for the jquery validation rules like<br>
828
-     * <code>$( "#myform" ).validate({
829
-     * rules: {
830
-     * password: "required",
831
-     * password_again: {
832
-     * equalTo: "#password"
833
-     * }
834
-     * }
835
-     * });</code>
836
-     * if this field had the name 'password_again', it should return
837
-     * <br><code>password_again: {
838
-     * equalTo: "#password"
839
-     * }</code>
840
-     *
841
-     * @return array
842
-     */
843
-    public function get_jquery_validation_rules()
844
-    {
845
-        $jquery_validation_js = array();
846
-        $jquery_validation_rules = array();
847
-        foreach ($this->get_validation_strategies() as $validation_strategy) {
848
-            $jquery_validation_rules = array_replace_recursive(
849
-                $jquery_validation_rules,
850
-                $validation_strategy->get_jquery_validation_rule_array()
851
-            );
852
-        }
853
-        if (! empty($jquery_validation_rules)) {
854
-            foreach ($this->get_display_strategy()->get_html_input_ids(true) as $html_id_with_pound_sign) {
855
-                $jquery_validation_js[ $html_id_with_pound_sign ] = $jquery_validation_rules;
856
-            }
857
-        }
858
-        return $jquery_validation_js;
859
-    }
860
-
861
-
862
-
863
-    /**
864
-     * Sets the input's default value for use in displaying in the form. Note: value should be
865
-     * normalized (Eg, if providing a default of ra Yes_NO_Input you would provide TRUE or FALSE, not '1' or '0')
866
-     *
867
-     * @param mixed $value
868
-     * @return void
869
-     */
870
-    public function set_default($value)
871
-    {
872
-        $this->_default = $value;
873
-        $this->_set_normalized_value($value);
874
-        $this->_set_raw_value($value);
875
-    }
876
-
877
-
878
-
879
-    /**
880
-     * Sets the normalized value on this input
881
-     *
882
-     * @param mixed $value
883
-     */
884
-    protected function _set_normalized_value($value)
885
-    {
886
-        $this->_normalized_value = $value;
887
-    }
888
-
889
-
890
-
891
-    /**
892
-     * Sets the raw value on this input (ie, exactly as the user submitted it)
893
-     *
894
-     * @param mixed $value
895
-     */
896
-    protected function _set_raw_value($value)
897
-    {
898
-        $this->_raw_value = $this->_normalization_strategy->unnormalize($value);
899
-    }
900
-
901
-
902
-
903
-    /**
904
-     * Sets the HTML label text after it has already been defined
905
-     *
906
-     * @param string $label
907
-     * @return void
908
-     */
909
-    public function set_html_label_text($label)
910
-    {
911
-        $this->_html_label_text = $label;
912
-    }
913
-
914
-
915
-
916
-    /**
917
-     * Sets whether or not this field is required, and adjusts the validation strategy.
918
-     * If you want to use the EE_Conditionally_Required_Validation_Strategy,
919
-     * please add it as a validation strategy using add_validation_strategy as normal
920
-     *
921
-     * @param boolean $required boolean
922
-     * @param null    $required_text
923
-     */
924
-    public function set_required($required = true, $required_text = null)
925
-    {
926
-        $required = filter_var($required, FILTER_VALIDATE_BOOLEAN);
927
-        // whether $required is a string or a boolean, we want to add a required validation strategy
928
-        if ($required) {
929
-            $this->_add_validation_strategy(new EE_Required_Validation_Strategy($required_text));
930
-        } else {
931
-            $this->remove_validation_strategy('EE_Required_Validation_Strategy');
932
-        }
933
-        $this->_required = $required;
934
-    }
935
-
936
-
937
-
938
-    /**
939
-     * Returns whether or not this field is required
940
-     *
941
-     * @return boolean
942
-     */
943
-    public function required()
944
-    {
945
-        return $this->_required;
946
-    }
947
-
948
-
949
-
950
-    /**
951
-     * @param string $required_css_class
952
-     */
953
-    public function set_required_css_class($required_css_class)
954
-    {
955
-        $this->_required_css_class = $required_css_class;
956
-    }
957
-
958
-
959
-
960
-    /**
961
-     * @return string
962
-     */
963
-    public function required_css_class()
964
-    {
965
-        return $this->_required_css_class;
966
-    }
967
-
968
-
969
-
970
-    /**
971
-     * @param bool $add_required
972
-     * @return string
973
-     */
974
-    public function html_class($add_required = false)
975
-    {
976
-        return $add_required && $this->required()
977
-            ? $this->required_css_class() . ' ' . $this->_html_class
978
-            : $this->_html_class;
979
-    }
980
-
981
-
982
-    /**
983
-     * Sets the help text, in case
984
-     *
985
-     * @param string $text
986
-     */
987
-    public function set_html_help_text($text)
988
-    {
989
-        $this->_html_help_text = $text;
990
-    }
991
-
992
-
993
-
994
-    /**
995
-     * Uses the sensitive data removal strategy to remove the sensitive data from this
996
-     * input. If there is any kind of sensitive data removal on this input, we clear
997
-     * out the raw value completely
998
-     *
999
-     * @return void
1000
-     */
1001
-    public function clean_sensitive_data()
1002
-    {
1003
-        // if we do ANY kind of sensitive data removal on this, then just clear out the raw value
1004
-        // if we need more logic than this we'll make a strategy for it
1005
-        if (
1006
-            $this->_sensitive_data_removal_strategy
1007
-            && ! $this->_sensitive_data_removal_strategy instanceof EE_No_Sensitive_Data_Removal
1008
-        ) {
1009
-            $this->_set_raw_value(null);
1010
-        }
1011
-        // and clean the normalized value according to the appropriate strategy
1012
-        $this->_set_normalized_value(
1013
-            $this->get_sensitive_data_removal_strategy()->remove_sensitive_data(
1014
-                $this->_normalized_value
1015
-            )
1016
-        );
1017
-    }
1018
-
1019
-
1020
-
1021
-    /**
1022
-     * @param bool   $primary
1023
-     * @param string $button_size
1024
-     * @param string $other_attributes
1025
-     */
1026
-    public function set_button_css_attributes($primary = true, $button_size = '', $other_attributes = '')
1027
-    {
1028
-        $button_css_attributes = 'button';
1029
-        $button_css_attributes .= $primary === true ? ' button--primary' : ' button--secondary';
1030
-        switch ($button_size) {
1031
-            case 'xs':
1032
-            case 'extra-small':
1033
-                $button_css_attributes .= ' button-xs';
1034
-                break;
1035
-            case 'sm':
1036
-            case 'small':
1037
-                $button_css_attributes .= ' button-sm';
1038
-                break;
1039
-            case 'lg':
1040
-            case 'large':
1041
-                $button_css_attributes .= ' button-lg';
1042
-                break;
1043
-            case 'block':
1044
-                $button_css_attributes .= ' button-block';
1045
-                break;
1046
-            case 'md':
1047
-            case 'medium':
1048
-            default:
1049
-                $button_css_attributes .= '';
1050
-        }
1051
-        $this->_button_css_attributes .= ! empty($other_attributes)
1052
-            ? $button_css_attributes . ' ' . $other_attributes
1053
-            : $button_css_attributes;
1054
-    }
1055
-
1056
-
1057
-
1058
-    /**
1059
-     * @return string
1060
-     */
1061
-    public function button_css_attributes()
1062
-    {
1063
-        if (empty($this->_button_css_attributes)) {
1064
-            $this->set_button_css_attributes();
1065
-        }
1066
-        return $this->_button_css_attributes;
1067
-    }
1068
-
1069
-
1070
-
1071
-    /**
1072
-     * find_form_data_for_this_section
1073
-     * using this section's name and its parents, finds the value of the form data that corresponds to it.
1074
-     * For example, if this form section's HTML name is my_form[subform][form_input_1],
1075
-     * then it's value should be in request at request['my_form']['subform']['form_input_1'].
1076
-     * (If that doesn't exist, we also check for this subsection's name
1077
-     * at the TOP LEVEL of the request data. Eg request['form_input_1'].)
1078
-     * This function finds its value in the form.
1079
-     *
1080
-     * @param array $req_data
1081
-     * @return mixed whatever the raw value of this form section is in the request data
1082
-     * @throws EE_Error
1083
-     */
1084
-    public function find_form_data_for_this_section($req_data)
1085
-    {
1086
-        $name_parts = $this->getInputNameParts();
1087
-        // now get the value for the input
1088
-        $value = $this->findRequestForSectionUsingNameParts($name_parts, $req_data);
1089
-        // check if this thing's name is at the TOP level of the request data
1090
-        if ($value === null && isset($req_data[ $this->name() ])) {
1091
-            $value = $req_data[ $this->name() ];
1092
-        }
1093
-        return $value;
1094
-    }
1095
-
1096
-
1097
-    /**
1098
-     * If this input's name is something like "foo[bar][baz]"
1099
-     * returns an array like `array('foo','bar',baz')`
1100
-     *
1101
-     * @return array
1102
-     * @throws EE_Error
1103
-     */
1104
-    protected function getInputNameParts()
1105
-    {
1106
-        // break up the html name by "[]"
1107
-        if (strpos($this->html_name(), '[') !== false) {
1108
-            $before_any_brackets = substr($this->html_name(), 0, strpos($this->html_name(), '['));
1109
-        } else {
1110
-            $before_any_brackets = $this->html_name();
1111
-        }
1112
-        // grab all of the segments
1113
-        preg_match_all('~\[([^]]*)\]~', $this->html_name(), $matches);
1114
-        if (isset($matches[1]) && is_array($matches[1])) {
1115
-            $name_parts = $matches[1];
1116
-            array_unshift($name_parts, $before_any_brackets);
1117
-        } else {
1118
-            $name_parts = array($before_any_brackets);
1119
-        }
1120
-        return $name_parts;
1121
-    }
1122
-
1123
-
1124
-
1125
-    /**
1126
-     * @param array $html_name_parts
1127
-     * @param array $req_data
1128
-     * @return array | NULL
1129
-     */
1130
-    public function findRequestForSectionUsingNameParts($html_name_parts, $req_data)
1131
-    {
1132
-        $first_part_to_consider = array_shift($html_name_parts);
1133
-        if (isset($req_data[ $first_part_to_consider ])) {
1134
-            if (empty($html_name_parts)) {
1135
-                return $req_data[ $first_part_to_consider ];
1136
-            } else {
1137
-                return $this->findRequestForSectionUsingNameParts(
1138
-                    $html_name_parts,
1139
-                    $req_data[ $first_part_to_consider ]
1140
-                );
1141
-            }
1142
-        } else {
1143
-            return null;
1144
-        }
1145
-    }
1146
-
1147
-
1148
-
1149
-    /**
1150
-     * Checks if this form input's data is in the request data
1151
-     *
1152
-     * @param array $req_data
1153
-     * @return boolean
1154
-     * @throws EE_Error
1155
-     */
1156
-    public function form_data_present_in($req_data = null)
1157
-    {
1158
-        if ($req_data === null) {
1159
-            /** @var RequestInterface $request */
1160
-            $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
1161
-            $req_data = $request->postParams();
1162
-        }
1163
-        $checked_value = $this->find_form_data_for_this_section($req_data);
1164
-        if ($checked_value !== null) {
1165
-            return true;
1166
-        } else {
1167
-            return false;
1168
-        }
1169
-    }
1170
-
1171
-
1172
-
1173
-    /**
1174
-     * Overrides parent to add js data from validation and display strategies
1175
-     *
1176
-     * @param array $form_other_js_data
1177
-     * @return array
1178
-     */
1179
-    public function get_other_js_data($form_other_js_data = array())
1180
-    {
1181
-        return $this->get_other_js_data_from_strategies($form_other_js_data);
1182
-    }
1183
-
1184
-
1185
-
1186
-    /**
1187
-     * Gets other JS data for localization from this input's strategies, like
1188
-     * the validation strategies and the display strategy
1189
-     *
1190
-     * @param array $form_other_js_data
1191
-     * @return array
1192
-     */
1193
-    public function get_other_js_data_from_strategies($form_other_js_data = array())
1194
-    {
1195
-        $form_other_js_data = $this->get_display_strategy()->get_other_js_data($form_other_js_data);
1196
-        foreach ($this->get_validation_strategies() as $validation_strategy) {
1197
-            $form_other_js_data = $validation_strategy->get_other_js_data($form_other_js_data);
1198
-        }
1199
-        return $form_other_js_data;
1200
-    }
1201
-
1202
-
1203
-
1204
-    /**
1205
-     * Override parent because we want to give our strategies an opportunity to enqueue some js and css
1206
-     *
1207
-     * @return void
1208
-     */
1209
-    public function enqueue_js()
1210
-    {
1211
-        // ask our display strategy and validation strategies if they have js to enqueue
1212
-        $this->enqueue_js_from_strategies();
1213
-    }
1214
-
1215
-
1216
-
1217
-    /**
1218
-     * Tells strategies when its ok to enqueue their js and css
1219
-     *
1220
-     * @return void
1221
-     */
1222
-    public function enqueue_js_from_strategies()
1223
-    {
1224
-        $this->get_display_strategy()->enqueue_js();
1225
-        foreach ($this->get_validation_strategies() as $validation_strategy) {
1226
-            $validation_strategy->enqueue_js();
1227
-        }
1228
-    }
1229
-
1230
-
1231
-
1232
-    /**
1233
-     * Gets the default value set on the input (not the current value, which may have been
1234
-     * changed because of a form submission). If no default was set, this us null.
1235
-     * @return mixed
1236
-     */
1237
-    public function get_default()
1238
-    {
1239
-        return $this->_default;
1240
-    }
1241
-
1242
-
1243
-
1244
-    /**
1245
-     * Makes this input disabled. That means it will have the HTML attribute 'disabled="disabled"',
1246
-     * and server-side if any input was received it will be ignored
1247
-     */
1248
-    public function disable($disable = true)
1249
-    {
1250
-        $disabled_attribute = ' disabled="disabled"';
1251
-        $this->disabled = filter_var($disable, FILTER_VALIDATE_BOOLEAN);
1252
-        if ($this->disabled) {
1253
-            if (strpos($this->_other_html_attributes, $disabled_attribute) === false) {
1254
-                $this->_other_html_attributes .= $disabled_attribute;
1255
-            }
1256
-            $this->_set_normalized_value($this->get_default());
1257
-        } else {
1258
-            $this->_other_html_attributes = str_replace($disabled_attribute, '', $this->_other_html_attributes);
1259
-        }
1260
-    }
1261
-
1262
-
1263
-
1264
-    /**
1265
-     * Returns whether or not this input is currently disabled.
1266
-     * @return bool
1267
-     */
1268
-    public function isDisabled()
1269
-    {
1270
-        return $this->disabled;
1271
-    }
17
+	/**
18
+	 * the input's name attribute
19
+	 *
20
+	 * @var string
21
+	 */
22
+	protected $_html_name;
23
+
24
+	/**
25
+	 * id for the html label tag
26
+	 *
27
+	 * @var string
28
+	 */
29
+	protected $_html_label_id;
30
+
31
+	/**
32
+	 * class for teh html label tag
33
+	 *
34
+	 * @var string
35
+	 */
36
+	protected $_html_label_class;
37
+
38
+	/**
39
+	 * style for teh html label tag
40
+	 *
41
+	 * @var string
42
+	 */
43
+	protected $_html_label_style;
44
+
45
+	/**
46
+	 * text to be placed in the html label
47
+	 *
48
+	 * @var string
49
+	 */
50
+	protected $_html_label_text;
51
+
52
+	/**
53
+	 * the full html label. If used, all other html_label_* properties are invalid
54
+	 *
55
+	 * @var string
56
+	 */
57
+	protected $_html_label;
58
+
59
+	/**
60
+	 * HTML to use for help text (normally placed below form input), in a span which normally
61
+	 * has a class of 'description'
62
+	 *
63
+	 * @var string
64
+	 */
65
+	protected $_html_help_text;
66
+
67
+	/**
68
+	 * CSS classes for displaying the help span
69
+	 *
70
+	 * @var string
71
+	 */
72
+	protected $_html_help_class = 'description';
73
+
74
+	/**
75
+	 * CSS to put in the style attribute on the help span
76
+	 *
77
+	 * @var string
78
+	 */
79
+	protected $_html_help_style;
80
+
81
+	/**
82
+	 * Stores whether or not this input's response is required.
83
+	 * Because certain styling elements may also want to know that this
84
+	 * input is required etc.
85
+	 *
86
+	 * @var boolean
87
+	 */
88
+	protected $_required;
89
+
90
+	/**
91
+	 * css class added to required inputs
92
+	 *
93
+	 * @var string
94
+	 */
95
+	protected $_required_css_class = 'ee-required';
96
+
97
+	/**
98
+	 * css styles applied to button type inputs
99
+	 *
100
+	 * @var string
101
+	 */
102
+	protected $_button_css_attributes;
103
+
104
+	/**
105
+	 * The raw post data submitted for this
106
+	 * Generally unsafe for usage in client code
107
+	 *
108
+	 * @var mixed string or array
109
+	 */
110
+	protected $_raw_value;
111
+
112
+	/**
113
+	 * Value normalized according to the input's normalization strategy.
114
+	 * The normalization strategy dictates whether this is a string, int, float,
115
+	 * boolean, or array of any of those.
116
+	 *
117
+	 * @var mixed
118
+	 */
119
+	protected $_normalized_value;
120
+
121
+
122
+	/**
123
+	 * Normalized default value either initially set on the input, or provided by calling
124
+	 * set_default().
125
+	 * @var mixed
126
+	 */
127
+	protected $_default;
128
+
129
+	/**
130
+	 * Strategy used for displaying this field.
131
+	 * Child classes must use _get_display_strategy to access it.
132
+	 *
133
+	 * @var EE_Display_Strategy_Base
134
+	 */
135
+	private $_display_strategy;
136
+
137
+	/**
138
+	 * Gets all the validation strategies used on this field
139
+	 *
140
+	 * @var EE_Validation_Strategy_Base[]
141
+	 */
142
+	private $_validation_strategies = array();
143
+
144
+	/**
145
+	 * The normalization strategy for this field
146
+	 *
147
+	 * @var EE_Normalization_Strategy_Base
148
+	 */
149
+	private $_normalization_strategy;
150
+
151
+	/**
152
+	 * Strategy for removing sensitive data after we're done with the form input
153
+	 *
154
+	 * @var EE_Sensitive_Data_Removal_Base
155
+	 */
156
+	protected $_sensitive_data_removal_strategy;
157
+
158
+	/**
159
+	 * Whether this input has been disabled or not.
160
+	 * If it's disabled while rendering, an extra hidden input is added that indicates it has been knowingly disabled.
161
+	 * (Client-side code that wants to dynamically disable it must also add this hidden input).
162
+	 * When the form is submitted, if the input is disabled in the PHP form section, then input is ignored.
163
+	 * If the input is missing from the request data but the hidden input indicating the input is disabled, then the input is again ignored.
164
+	 *
165
+	 * @var boolean
166
+	 */
167
+	protected $disabled = false;
168
+
169
+
170
+
171
+	/**
172
+	 * @param array                         $input_args       {
173
+	 * @type string                         $html_name        the html name for the input
174
+	 * @type string                         $html_label_id    the id attribute to give to the html label tag
175
+	 * @type string                         $html_label_class the class attribute to give to the html label tag
176
+	 * @type string                         $html_label_style the style attribute to give ot teh label tag
177
+	 * @type string                         $html_label_text  the text to put in the label tag
178
+	 * @type string                         $html_label       the full html label. If used,
179
+	 *                                                        all other html_label_* args are invalid
180
+	 * @type string                         $html_help_text   text to put in help element
181
+	 * @type string                         $html_help_style  style attribute to give to teh help element
182
+	 * @type string                         $html_help_class  class attribute to give to the help element
183
+	 * @type string                         $default          default value NORMALIZED (eg, if providing the default
184
+	 *       for a Yes_No_Input, you should provide TRUE or FALSE, not '1' or '0')
185
+	 * @type EE_Display_Strategy_Base       $display          strategy
186
+	 * @type EE_Normalization_Strategy_Base $normalization_strategy
187
+	 * @type EE_Validation_Strategy_Base[]  $validation_strategies
188
+	 * @type boolean                        $ignore_input special argument which can be used to avoid adding any validation strategies,
189
+	 *                                                    and sets the normalization strategy to the Null normalization. This is good
190
+	 *                                                    when you want the input to be totally ignored server-side (like when using
191
+	 *                                                    React.js form inputs)
192
+	 *                                                        }
193
+	 */
194
+	public function __construct($input_args = array())
195
+	{
196
+		$input_args = (array) apply_filters('FHEE__EE_Form_Input_Base___construct__input_args', $input_args, $this);
197
+		// the following properties must be cast as arrays
198
+		if (isset($input_args['validation_strategies'])) {
199
+			foreach ((array) $input_args['validation_strategies'] as $validation_strategy) {
200
+				if ($validation_strategy instanceof EE_Validation_Strategy_Base && empty($input_args['ignore_input'])) {
201
+					$this->_validation_strategies[ get_class($validation_strategy) ] = $validation_strategy;
202
+				}
203
+			}
204
+			unset($input_args['validation_strategies']);
205
+		}
206
+		if (isset($input_args['ignore_input'])) {
207
+			$this->_validation_strategies = array();
208
+		}
209
+		// loop thru incoming options
210
+		foreach ($input_args as $key => $value) {
211
+			// add underscore to $key to match property names
212
+			$_key = '_' . $key;
213
+			if (property_exists($this, $_key)) {
214
+				$this->{$_key} = $value;
215
+			}
216
+		}
217
+		// ensure that "required" is set correctly
218
+		$this->set_required(
219
+			$this->_required,
220
+			$input_args['required_validation_error_message'] ?? null
221
+		);
222
+		// $this->_html_name_specified = isset( $input_args['html_name'] ) ? TRUE : FALSE;
223
+		$this->_display_strategy->_construct_finalize($this);
224
+		foreach ($this->_validation_strategies as $validation_strategy) {
225
+			$validation_strategy->_construct_finalize($this);
226
+		}
227
+		if (isset($input_args['ignore_input'])) {
228
+			$this->_normalization_strategy = new EE_Null_Normalization();
229
+		}
230
+		if (! $this->_normalization_strategy) {
231
+				$this->_normalization_strategy = new EE_Text_Normalization();
232
+		}
233
+		$this->_normalization_strategy->_construct_finalize($this);
234
+		// at least we can use the normalization strategy to populate the default
235
+		if (isset($input_args['default'])) {
236
+			$this->set_default($input_args['default']);
237
+			unset($input_args['default']);
238
+		}
239
+		if (! $this->_sensitive_data_removal_strategy) {
240
+			$this->_sensitive_data_removal_strategy = new EE_No_Sensitive_Data_Removal();
241
+		}
242
+		$this->_sensitive_data_removal_strategy->_construct_finalize($this);
243
+		parent::__construct($input_args);
244
+	}
245
+
246
+
247
+
248
+	/**
249
+	 * Sets the html_name to its default value, if none was specified in teh constructor.
250
+	 * Calculation involves using the name and the parent's html_name
251
+	 *
252
+	 * @throws EE_Error
253
+	 */
254
+	protected function _set_default_html_name_if_empty()
255
+	{
256
+		if (! $this->_html_name) {
257
+			$this->_html_name = $this->name();
258
+			if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
259
+				$this->_html_name = $this->_parent_section->html_name_prefix() . "[{$this->name()}]";
260
+			}
261
+		}
262
+	}
263
+
264
+
265
+
266
+	/**
267
+	 * @param $parent_form_section
268
+	 * @param $name
269
+	 * @throws EE_Error
270
+	 */
271
+	public function _construct_finalize($parent_form_section, $name)
272
+	{
273
+		parent::_construct_finalize($parent_form_section, $name);
274
+		if ($this->_html_label === null && $this->_html_label_text === null) {
275
+			$this->_html_label_text = ucwords(str_replace("_", " ", $name));
276
+		}
277
+		do_action('AHEE__EE_Form_Input_Base___construct_finalize__end', $this, $parent_form_section, $name);
278
+	}
279
+
280
+
281
+
282
+	/**
283
+	 * Returns the strategy for displaying this form input. If none is set, throws an exception.
284
+	 *
285
+	 * @return EE_Display_Strategy_Base
286
+	 * @throws EE_Error
287
+	 */
288
+	protected function _get_display_strategy()
289
+	{
290
+		$this->ensure_construct_finalized_called();
291
+		if (! $this->_display_strategy || ! $this->_display_strategy instanceof EE_Display_Strategy_Base) {
292
+			throw new EE_Error(
293
+				sprintf(
294
+					esc_html__(
295
+						"Cannot get display strategy for form input with name %s and id %s, because it has not been set in the constructor",
296
+						"event_espresso"
297
+					),
298
+					$this->html_name(),
299
+					$this->html_id()
300
+				)
301
+			);
302
+		} else {
303
+			return $this->_display_strategy;
304
+		}
305
+	}
306
+
307
+
308
+
309
+	/**
310
+	 * Sets the display strategy.
311
+	 *
312
+	 * @param EE_Display_Strategy_Base $strategy
313
+	 */
314
+	protected function _set_display_strategy(EE_Display_Strategy_Base $strategy)
315
+	{
316
+		$this->_display_strategy = $strategy;
317
+	}
318
+
319
+
320
+
321
+	/**
322
+	 * Sets the sanitization strategy
323
+	 *
324
+	 * @param EE_Normalization_Strategy_Base $strategy
325
+	 */
326
+	protected function _set_normalization_strategy(EE_Normalization_Strategy_Base $strategy)
327
+	{
328
+		$this->_normalization_strategy = $strategy;
329
+	}
330
+
331
+
332
+
333
+	/**
334
+	 * Gets sensitive_data_removal_strategy
335
+	 *
336
+	 * @return EE_Sensitive_Data_Removal_Base
337
+	 */
338
+	public function get_sensitive_data_removal_strategy()
339
+	{
340
+		return $this->_sensitive_data_removal_strategy;
341
+	}
342
+
343
+
344
+
345
+	/**
346
+	 * Sets sensitive_data_removal_strategy
347
+	 *
348
+	 * @param EE_Sensitive_Data_Removal_Base $sensitive_data_removal_strategy
349
+	 * @return void
350
+	 */
351
+	public function set_sensitive_data_removal_strategy($sensitive_data_removal_strategy)
352
+	{
353
+		$this->_sensitive_data_removal_strategy = $sensitive_data_removal_strategy;
354
+	}
355
+
356
+
357
+
358
+	/**
359
+	 * Gets the display strategy for this input
360
+	 *
361
+	 * @return EE_Display_Strategy_Base
362
+	 */
363
+	public function get_display_strategy()
364
+	{
365
+		return $this->_display_strategy;
366
+	}
367
+
368
+
369
+
370
+	/**
371
+	 * Overwrites the display strategy
372
+	 *
373
+	 * @param EE_Display_Strategy_Base $display_strategy
374
+	 */
375
+	public function set_display_strategy($display_strategy)
376
+	{
377
+		$this->_display_strategy = $display_strategy;
378
+		$this->_display_strategy->_construct_finalize($this);
379
+	}
380
+
381
+
382
+
383
+	/**
384
+	 * Gets the normalization strategy set on this input
385
+	 *
386
+	 * @return EE_Normalization_Strategy_Base
387
+	 */
388
+	public function get_normalization_strategy()
389
+	{
390
+		return $this->_normalization_strategy;
391
+	}
392
+
393
+
394
+
395
+	/**
396
+	 * Overwrites the normalization strategy
397
+	 *
398
+	 * @param EE_Normalization_Strategy_Base $normalization_strategy
399
+	 */
400
+	public function set_normalization_strategy($normalization_strategy)
401
+	{
402
+		$this->_normalization_strategy = $normalization_strategy;
403
+		$this->_normalization_strategy->_construct_finalize($this);
404
+	}
405
+
406
+
407
+
408
+	/**
409
+	 * Returns all teh validation strategies which apply to this field, numerically indexed
410
+	 *
411
+	 * @return EE_Validation_Strategy_Base[]
412
+	 */
413
+	public function get_validation_strategies()
414
+	{
415
+		return $this->_validation_strategies;
416
+	}
417
+
418
+
419
+
420
+	/**
421
+	 * Adds this strategy to the field so it will be used in both JS validation and server-side validation
422
+	 *
423
+	 * @param EE_Validation_Strategy_Base $validation_strategy
424
+	 * @return void
425
+	 */
426
+	protected function _add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
427
+	{
428
+		$validation_strategy->_construct_finalize($this);
429
+		$this->_validation_strategies[] = $validation_strategy;
430
+	}
431
+
432
+
433
+
434
+	/**
435
+	 * Adds a new validation strategy onto the form input
436
+	 *
437
+	 * @param EE_Validation_Strategy_Base $validation_strategy
438
+	 * @return void
439
+	 */
440
+	public function add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
441
+	{
442
+		$this->_add_validation_strategy($validation_strategy);
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 * The classname of the validation strategy to remove
449
+	 *
450
+	 * @param string $validation_strategy_classname
451
+	 */
452
+	public function remove_validation_strategy($validation_strategy_classname)
453
+	{
454
+		foreach ($this->_validation_strategies as $key => $validation_strategy) {
455
+			if (
456
+				$validation_strategy instanceof $validation_strategy_classname
457
+				|| is_subclass_of($validation_strategy, $validation_strategy_classname)
458
+			) {
459
+				unset($this->_validation_strategies[ $key ]);
460
+			}
461
+		}
462
+	}
463
+
464
+
465
+
466
+	/**
467
+	 * returns true if input employs any of the validation strategy defined by the supplied array of classnames
468
+	 *
469
+	 * @param array $validation_strategy_classnames
470
+	 * @return bool
471
+	 */
472
+	public function has_validation_strategy($validation_strategy_classnames)
473
+	{
474
+		$validation_strategy_classnames = is_array($validation_strategy_classnames)
475
+			? $validation_strategy_classnames
476
+			: array($validation_strategy_classnames);
477
+		foreach ($this->_validation_strategies as $key => $validation_strategy) {
478
+			if (in_array($key, $validation_strategy_classnames)) {
479
+				return true;
480
+			}
481
+		}
482
+		return false;
483
+	}
484
+
485
+
486
+
487
+	/**
488
+	 * Gets the HTML
489
+	 *
490
+	 * @return string
491
+	 */
492
+	public function get_html()
493
+	{
494
+		return $this->_parent_section->get_html_for_input($this);
495
+	}
496
+
497
+
498
+
499
+	/**
500
+	 * Gets the HTML for the input itself (no label or errors) according to the
501
+	 * input's display strategy
502
+	 * Makes sure the JS and CSS are enqueued for it
503
+	 *
504
+	 * @return string
505
+	 * @throws EE_Error
506
+	 */
507
+	public function get_html_for_input()
508
+	{
509
+		return $this->_form_html_filter
510
+			? $this->_form_html_filter->filterHtml(
511
+				$this->_get_display_strategy()->display(),
512
+				$this
513
+			)
514
+			: $this->_get_display_strategy()->display();
515
+	}
516
+
517
+
518
+
519
+	/**
520
+	 * @return string
521
+	 */
522
+	public function html_other_attributes()
523
+	{
524
+		EE_Error::doing_it_wrong(
525
+			__METHOD__,
526
+			sprintf(
527
+				esc_html__(
528
+					'This method is no longer in use. You should replace it by %s',
529
+					'event_espresso'
530
+				),
531
+				'EE_Form_Section_Base::other_html_attributes()'
532
+			),
533
+			'4.10.2.p'
534
+		);
535
+
536
+		return $this->other_html_attributes();
537
+	}
538
+
539
+
540
+
541
+	/**
542
+	 * @param string $html_other_attributes
543
+	 */
544
+	public function set_html_other_attributes($html_other_attributes)
545
+	{
546
+		EE_Error::doing_it_wrong(
547
+			__METHOD__,
548
+			sprintf(
549
+				esc_html__(
550
+					'This method is no longer in use. You should replace it by %s',
551
+					'event_espresso'
552
+				),
553
+				'EE_Form_Section_Base::set_other_html_attributes()'
554
+			),
555
+			'4.10.2.p'
556
+		);
557
+
558
+		$this->set_other_html_attributes($html_other_attributes);
559
+	}
560
+
561
+
562
+
563
+	/**
564
+	 * Gets the HTML for displaying the label for this form input
565
+	 * according to the form section's layout strategy
566
+	 *
567
+	 * @return string
568
+	 */
569
+	public function get_html_for_label()
570
+	{
571
+		return $this->_parent_section->get_layout_strategy()->display_label($this);
572
+	}
573
+
574
+
575
+
576
+	/**
577
+	 * Gets the HTML for displaying the errors section for this form input
578
+	 * according to the form section's layout strategy
579
+	 *
580
+	 * @return string
581
+	 */
582
+	public function get_html_for_errors()
583
+	{
584
+		return $this->_parent_section->get_layout_strategy()->display_errors($this);
585
+	}
586
+
587
+
588
+
589
+	/**
590
+	 * Gets the HTML for displaying the help text for this form input
591
+	 * according to the form section's layout strategy
592
+	 *
593
+	 * @return string
594
+	 */
595
+	public function get_html_for_help()
596
+	{
597
+		return $this->_parent_section->get_layout_strategy()->display_help_text($this);
598
+	}
599
+
600
+
601
+
602
+	/**
603
+	 * Validates the input's sanitized value (assumes _sanitize() has already been called)
604
+	 * and returns whether or not the form input's submitted value is value
605
+	 *
606
+	 * @return boolean
607
+	 */
608
+	protected function _validate()
609
+	{
610
+		if ($this->isDisabled()) {
611
+			return true;
612
+		}
613
+		foreach ($this->_validation_strategies as $validation_strategy) {
614
+			if ($validation_strategy instanceof EE_Validation_Strategy_Base) {
615
+				try {
616
+					$validation_strategy->validate($this->normalized_value());
617
+				} catch (EE_Validation_Error $e) {
618
+					$this->add_validation_error($e);
619
+				}
620
+			}
621
+		}
622
+		if ($this->get_validation_errors()) {
623
+			return false;
624
+		} else {
625
+			return true;
626
+		}
627
+	}
628
+
629
+
630
+
631
+	/**
632
+	 * Performs basic sanitization on this value. But what sanitization can be performed anyways?
633
+	 * This value MIGHT be allowed to have tags, so we can't really remove them.
634
+	 *
635
+	 * @param string $value
636
+	 * @return null|string
637
+	 */
638
+	protected function _sanitize($value)
639
+	{
640
+		return $value !== null ? stripslashes(html_entity_decode(trim($value))) : null;
641
+	}
642
+
643
+
644
+
645
+	/**
646
+	 * Picks out the form value that relates to this form input,
647
+	 * and stores it as the sanitized value on the form input, and sets the normalized value.
648
+	 * Returns whether or not any validation errors occurred
649
+	 *
650
+	 * @param array $req_data
651
+	 * @return boolean whether or not there was an error
652
+	 * @throws EE_Error
653
+	 */
654
+	protected function _normalize($req_data)
655
+	{
656
+		// any existing validation errors don't apply so clear them
657
+		$this->_validation_errors = array();
658
+		// if the input is disabled, ignore whatever input was sent in
659
+		if ($this->isDisabled()) {
660
+			$this->_set_raw_value(null);
661
+			$this->_set_normalized_value($this->get_default());
662
+			return false;
663
+		}
664
+		try {
665
+			$raw_input = $this->find_form_data_for_this_section($req_data);
666
+			// super simple sanitization for now
667
+			if (is_array($raw_input)) {
668
+				$raw_value = array();
669
+				foreach ($raw_input as $key => $value) {
670
+					$raw_value[ $key ] = $this->_sanitize($value);
671
+				}
672
+				$this->_set_raw_value($raw_value);
673
+			} else {
674
+				$this->_set_raw_value($this->_sanitize($raw_input));
675
+			}
676
+			// we want to mostly leave the input alone in case we need to re-display it to the user
677
+			$this->_set_normalized_value($this->_normalization_strategy->normalize($this->raw_value()));
678
+			return false;
679
+		} catch (EE_Validation_Error $e) {
680
+			$this->add_validation_error($e);
681
+			return true;
682
+		}
683
+	}
684
+
685
+
686
+	/**
687
+	 * @return string
688
+	 * @throws EE_Error
689
+	 */
690
+	public function html_name()
691
+	{
692
+		$this->_set_default_html_name_if_empty();
693
+		return $this->_html_name;
694
+	}
695
+
696
+
697
+	/**
698
+	 * @return string
699
+	 * @throws EE_Error
700
+	 */
701
+	public function html_label_id()
702
+	{
703
+		return ! empty($this->_html_label_id) ? $this->_html_label_id : $this->html_id() . '-lbl';
704
+	}
705
+
706
+
707
+
708
+	/**
709
+	 * @return string
710
+	 */
711
+	public function html_label_class()
712
+	{
713
+		return $this->_html_label_class;
714
+	}
715
+
716
+
717
+
718
+	/**
719
+	 * @return string
720
+	 */
721
+	public function html_label_style()
722
+	{
723
+		return $this->_html_label_style;
724
+	}
725
+
726
+
727
+
728
+	/**
729
+	 * @return string
730
+	 */
731
+	public function html_label_text()
732
+	{
733
+		return $this->_html_label_text;
734
+	}
735
+
736
+
737
+
738
+	/**
739
+	 * @return string
740
+	 */
741
+	public function html_help_text()
742
+	{
743
+		return $this->_html_help_text;
744
+	}
745
+
746
+
747
+
748
+	/**
749
+	 * @return string
750
+	 */
751
+	public function html_help_class()
752
+	{
753
+		return $this->_html_help_class;
754
+	}
755
+
756
+
757
+
758
+	/**
759
+	 * @return string
760
+	 */
761
+	public function html_help_style()
762
+	{
763
+		return $this->_html_style;
764
+	}
765
+
766
+
767
+
768
+	/**
769
+	 * returns the raw, UNSAFE, input, almost exactly as the user submitted it.
770
+	 * Please note that almost all client code should instead use the normalized_value;
771
+	 * or possibly raw_value_in_form (which prepares the string for displaying in an HTML attribute on a tag,
772
+	 * mostly by escaping quotes)
773
+	 * Note, we do not store the exact original value sent in the user's request because
774
+	 * it may have malicious content, and we MIGHT want to store the form input in a transient or something...
775
+	 * in which case, we would have stored the malicious content to our database.
776
+	 *
777
+	 * @return string
778
+	 */
779
+	public function raw_value()
780
+	{
781
+		return $this->_raw_value;
782
+	}
783
+
784
+
785
+
786
+	/**
787
+	 * Returns a string safe to usage in form inputs when displaying, because
788
+	 * it escapes all html entities
789
+	 *
790
+	 * @return string
791
+	 */
792
+	public function raw_value_in_form()
793
+	{
794
+		return htmlentities($this->raw_value(), ENT_QUOTES, 'UTF-8');
795
+	}
796
+
797
+
798
+
799
+	/**
800
+	 * returns the value after it's been sanitized, and then converted into it's proper type
801
+	 * in PHP. Eg, a string, an int, an array,
802
+	 *
803
+	 * @return mixed
804
+	 */
805
+	public function normalized_value()
806
+	{
807
+		return $this->_normalized_value;
808
+	}
809
+
810
+
811
+
812
+	/**
813
+	 * Returns the normalized value is a presentable way. By default this is just
814
+	 * the normalized value by itself, but it can be overridden for when that's not
815
+	 * the best thing to display
816
+	 *
817
+	 * @return string
818
+	 */
819
+	public function pretty_value()
820
+	{
821
+		return $this->_normalized_value;
822
+	}
823
+
824
+
825
+
826
+	/**
827
+	 * When generating the JS for the jquery validation rules like<br>
828
+	 * <code>$( "#myform" ).validate({
829
+	 * rules: {
830
+	 * password: "required",
831
+	 * password_again: {
832
+	 * equalTo: "#password"
833
+	 * }
834
+	 * }
835
+	 * });</code>
836
+	 * if this field had the name 'password_again', it should return
837
+	 * <br><code>password_again: {
838
+	 * equalTo: "#password"
839
+	 * }</code>
840
+	 *
841
+	 * @return array
842
+	 */
843
+	public function get_jquery_validation_rules()
844
+	{
845
+		$jquery_validation_js = array();
846
+		$jquery_validation_rules = array();
847
+		foreach ($this->get_validation_strategies() as $validation_strategy) {
848
+			$jquery_validation_rules = array_replace_recursive(
849
+				$jquery_validation_rules,
850
+				$validation_strategy->get_jquery_validation_rule_array()
851
+			);
852
+		}
853
+		if (! empty($jquery_validation_rules)) {
854
+			foreach ($this->get_display_strategy()->get_html_input_ids(true) as $html_id_with_pound_sign) {
855
+				$jquery_validation_js[ $html_id_with_pound_sign ] = $jquery_validation_rules;
856
+			}
857
+		}
858
+		return $jquery_validation_js;
859
+	}
860
+
861
+
862
+
863
+	/**
864
+	 * Sets the input's default value for use in displaying in the form. Note: value should be
865
+	 * normalized (Eg, if providing a default of ra Yes_NO_Input you would provide TRUE or FALSE, not '1' or '0')
866
+	 *
867
+	 * @param mixed $value
868
+	 * @return void
869
+	 */
870
+	public function set_default($value)
871
+	{
872
+		$this->_default = $value;
873
+		$this->_set_normalized_value($value);
874
+		$this->_set_raw_value($value);
875
+	}
876
+
877
+
878
+
879
+	/**
880
+	 * Sets the normalized value on this input
881
+	 *
882
+	 * @param mixed $value
883
+	 */
884
+	protected function _set_normalized_value($value)
885
+	{
886
+		$this->_normalized_value = $value;
887
+	}
888
+
889
+
890
+
891
+	/**
892
+	 * Sets the raw value on this input (ie, exactly as the user submitted it)
893
+	 *
894
+	 * @param mixed $value
895
+	 */
896
+	protected function _set_raw_value($value)
897
+	{
898
+		$this->_raw_value = $this->_normalization_strategy->unnormalize($value);
899
+	}
900
+
901
+
902
+
903
+	/**
904
+	 * Sets the HTML label text after it has already been defined
905
+	 *
906
+	 * @param string $label
907
+	 * @return void
908
+	 */
909
+	public function set_html_label_text($label)
910
+	{
911
+		$this->_html_label_text = $label;
912
+	}
913
+
914
+
915
+
916
+	/**
917
+	 * Sets whether or not this field is required, and adjusts the validation strategy.
918
+	 * If you want to use the EE_Conditionally_Required_Validation_Strategy,
919
+	 * please add it as a validation strategy using add_validation_strategy as normal
920
+	 *
921
+	 * @param boolean $required boolean
922
+	 * @param null    $required_text
923
+	 */
924
+	public function set_required($required = true, $required_text = null)
925
+	{
926
+		$required = filter_var($required, FILTER_VALIDATE_BOOLEAN);
927
+		// whether $required is a string or a boolean, we want to add a required validation strategy
928
+		if ($required) {
929
+			$this->_add_validation_strategy(new EE_Required_Validation_Strategy($required_text));
930
+		} else {
931
+			$this->remove_validation_strategy('EE_Required_Validation_Strategy');
932
+		}
933
+		$this->_required = $required;
934
+	}
935
+
936
+
937
+
938
+	/**
939
+	 * Returns whether or not this field is required
940
+	 *
941
+	 * @return boolean
942
+	 */
943
+	public function required()
944
+	{
945
+		return $this->_required;
946
+	}
947
+
948
+
949
+
950
+	/**
951
+	 * @param string $required_css_class
952
+	 */
953
+	public function set_required_css_class($required_css_class)
954
+	{
955
+		$this->_required_css_class = $required_css_class;
956
+	}
957
+
958
+
959
+
960
+	/**
961
+	 * @return string
962
+	 */
963
+	public function required_css_class()
964
+	{
965
+		return $this->_required_css_class;
966
+	}
967
+
968
+
969
+
970
+	/**
971
+	 * @param bool $add_required
972
+	 * @return string
973
+	 */
974
+	public function html_class($add_required = false)
975
+	{
976
+		return $add_required && $this->required()
977
+			? $this->required_css_class() . ' ' . $this->_html_class
978
+			: $this->_html_class;
979
+	}
980
+
981
+
982
+	/**
983
+	 * Sets the help text, in case
984
+	 *
985
+	 * @param string $text
986
+	 */
987
+	public function set_html_help_text($text)
988
+	{
989
+		$this->_html_help_text = $text;
990
+	}
991
+
992
+
993
+
994
+	/**
995
+	 * Uses the sensitive data removal strategy to remove the sensitive data from this
996
+	 * input. If there is any kind of sensitive data removal on this input, we clear
997
+	 * out the raw value completely
998
+	 *
999
+	 * @return void
1000
+	 */
1001
+	public function clean_sensitive_data()
1002
+	{
1003
+		// if we do ANY kind of sensitive data removal on this, then just clear out the raw value
1004
+		// if we need more logic than this we'll make a strategy for it
1005
+		if (
1006
+			$this->_sensitive_data_removal_strategy
1007
+			&& ! $this->_sensitive_data_removal_strategy instanceof EE_No_Sensitive_Data_Removal
1008
+		) {
1009
+			$this->_set_raw_value(null);
1010
+		}
1011
+		// and clean the normalized value according to the appropriate strategy
1012
+		$this->_set_normalized_value(
1013
+			$this->get_sensitive_data_removal_strategy()->remove_sensitive_data(
1014
+				$this->_normalized_value
1015
+			)
1016
+		);
1017
+	}
1018
+
1019
+
1020
+
1021
+	/**
1022
+	 * @param bool   $primary
1023
+	 * @param string $button_size
1024
+	 * @param string $other_attributes
1025
+	 */
1026
+	public function set_button_css_attributes($primary = true, $button_size = '', $other_attributes = '')
1027
+	{
1028
+		$button_css_attributes = 'button';
1029
+		$button_css_attributes .= $primary === true ? ' button--primary' : ' button--secondary';
1030
+		switch ($button_size) {
1031
+			case 'xs':
1032
+			case 'extra-small':
1033
+				$button_css_attributes .= ' button-xs';
1034
+				break;
1035
+			case 'sm':
1036
+			case 'small':
1037
+				$button_css_attributes .= ' button-sm';
1038
+				break;
1039
+			case 'lg':
1040
+			case 'large':
1041
+				$button_css_attributes .= ' button-lg';
1042
+				break;
1043
+			case 'block':
1044
+				$button_css_attributes .= ' button-block';
1045
+				break;
1046
+			case 'md':
1047
+			case 'medium':
1048
+			default:
1049
+				$button_css_attributes .= '';
1050
+		}
1051
+		$this->_button_css_attributes .= ! empty($other_attributes)
1052
+			? $button_css_attributes . ' ' . $other_attributes
1053
+			: $button_css_attributes;
1054
+	}
1055
+
1056
+
1057
+
1058
+	/**
1059
+	 * @return string
1060
+	 */
1061
+	public function button_css_attributes()
1062
+	{
1063
+		if (empty($this->_button_css_attributes)) {
1064
+			$this->set_button_css_attributes();
1065
+		}
1066
+		return $this->_button_css_attributes;
1067
+	}
1068
+
1069
+
1070
+
1071
+	/**
1072
+	 * find_form_data_for_this_section
1073
+	 * using this section's name and its parents, finds the value of the form data that corresponds to it.
1074
+	 * For example, if this form section's HTML name is my_form[subform][form_input_1],
1075
+	 * then it's value should be in request at request['my_form']['subform']['form_input_1'].
1076
+	 * (If that doesn't exist, we also check for this subsection's name
1077
+	 * at the TOP LEVEL of the request data. Eg request['form_input_1'].)
1078
+	 * This function finds its value in the form.
1079
+	 *
1080
+	 * @param array $req_data
1081
+	 * @return mixed whatever the raw value of this form section is in the request data
1082
+	 * @throws EE_Error
1083
+	 */
1084
+	public function find_form_data_for_this_section($req_data)
1085
+	{
1086
+		$name_parts = $this->getInputNameParts();
1087
+		// now get the value for the input
1088
+		$value = $this->findRequestForSectionUsingNameParts($name_parts, $req_data);
1089
+		// check if this thing's name is at the TOP level of the request data
1090
+		if ($value === null && isset($req_data[ $this->name() ])) {
1091
+			$value = $req_data[ $this->name() ];
1092
+		}
1093
+		return $value;
1094
+	}
1095
+
1096
+
1097
+	/**
1098
+	 * If this input's name is something like "foo[bar][baz]"
1099
+	 * returns an array like `array('foo','bar',baz')`
1100
+	 *
1101
+	 * @return array
1102
+	 * @throws EE_Error
1103
+	 */
1104
+	protected function getInputNameParts()
1105
+	{
1106
+		// break up the html name by "[]"
1107
+		if (strpos($this->html_name(), '[') !== false) {
1108
+			$before_any_brackets = substr($this->html_name(), 0, strpos($this->html_name(), '['));
1109
+		} else {
1110
+			$before_any_brackets = $this->html_name();
1111
+		}
1112
+		// grab all of the segments
1113
+		preg_match_all('~\[([^]]*)\]~', $this->html_name(), $matches);
1114
+		if (isset($matches[1]) && is_array($matches[1])) {
1115
+			$name_parts = $matches[1];
1116
+			array_unshift($name_parts, $before_any_brackets);
1117
+		} else {
1118
+			$name_parts = array($before_any_brackets);
1119
+		}
1120
+		return $name_parts;
1121
+	}
1122
+
1123
+
1124
+
1125
+	/**
1126
+	 * @param array $html_name_parts
1127
+	 * @param array $req_data
1128
+	 * @return array | NULL
1129
+	 */
1130
+	public function findRequestForSectionUsingNameParts($html_name_parts, $req_data)
1131
+	{
1132
+		$first_part_to_consider = array_shift($html_name_parts);
1133
+		if (isset($req_data[ $first_part_to_consider ])) {
1134
+			if (empty($html_name_parts)) {
1135
+				return $req_data[ $first_part_to_consider ];
1136
+			} else {
1137
+				return $this->findRequestForSectionUsingNameParts(
1138
+					$html_name_parts,
1139
+					$req_data[ $first_part_to_consider ]
1140
+				);
1141
+			}
1142
+		} else {
1143
+			return null;
1144
+		}
1145
+	}
1146
+
1147
+
1148
+
1149
+	/**
1150
+	 * Checks if this form input's data is in the request data
1151
+	 *
1152
+	 * @param array $req_data
1153
+	 * @return boolean
1154
+	 * @throws EE_Error
1155
+	 */
1156
+	public function form_data_present_in($req_data = null)
1157
+	{
1158
+		if ($req_data === null) {
1159
+			/** @var RequestInterface $request */
1160
+			$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
1161
+			$req_data = $request->postParams();
1162
+		}
1163
+		$checked_value = $this->find_form_data_for_this_section($req_data);
1164
+		if ($checked_value !== null) {
1165
+			return true;
1166
+		} else {
1167
+			return false;
1168
+		}
1169
+	}
1170
+
1171
+
1172
+
1173
+	/**
1174
+	 * Overrides parent to add js data from validation and display strategies
1175
+	 *
1176
+	 * @param array $form_other_js_data
1177
+	 * @return array
1178
+	 */
1179
+	public function get_other_js_data($form_other_js_data = array())
1180
+	{
1181
+		return $this->get_other_js_data_from_strategies($form_other_js_data);
1182
+	}
1183
+
1184
+
1185
+
1186
+	/**
1187
+	 * Gets other JS data for localization from this input's strategies, like
1188
+	 * the validation strategies and the display strategy
1189
+	 *
1190
+	 * @param array $form_other_js_data
1191
+	 * @return array
1192
+	 */
1193
+	public function get_other_js_data_from_strategies($form_other_js_data = array())
1194
+	{
1195
+		$form_other_js_data = $this->get_display_strategy()->get_other_js_data($form_other_js_data);
1196
+		foreach ($this->get_validation_strategies() as $validation_strategy) {
1197
+			$form_other_js_data = $validation_strategy->get_other_js_data($form_other_js_data);
1198
+		}
1199
+		return $form_other_js_data;
1200
+	}
1201
+
1202
+
1203
+
1204
+	/**
1205
+	 * Override parent because we want to give our strategies an opportunity to enqueue some js and css
1206
+	 *
1207
+	 * @return void
1208
+	 */
1209
+	public function enqueue_js()
1210
+	{
1211
+		// ask our display strategy and validation strategies if they have js to enqueue
1212
+		$this->enqueue_js_from_strategies();
1213
+	}
1214
+
1215
+
1216
+
1217
+	/**
1218
+	 * Tells strategies when its ok to enqueue their js and css
1219
+	 *
1220
+	 * @return void
1221
+	 */
1222
+	public function enqueue_js_from_strategies()
1223
+	{
1224
+		$this->get_display_strategy()->enqueue_js();
1225
+		foreach ($this->get_validation_strategies() as $validation_strategy) {
1226
+			$validation_strategy->enqueue_js();
1227
+		}
1228
+	}
1229
+
1230
+
1231
+
1232
+	/**
1233
+	 * Gets the default value set on the input (not the current value, which may have been
1234
+	 * changed because of a form submission). If no default was set, this us null.
1235
+	 * @return mixed
1236
+	 */
1237
+	public function get_default()
1238
+	{
1239
+		return $this->_default;
1240
+	}
1241
+
1242
+
1243
+
1244
+	/**
1245
+	 * Makes this input disabled. That means it will have the HTML attribute 'disabled="disabled"',
1246
+	 * and server-side if any input was received it will be ignored
1247
+	 */
1248
+	public function disable($disable = true)
1249
+	{
1250
+		$disabled_attribute = ' disabled="disabled"';
1251
+		$this->disabled = filter_var($disable, FILTER_VALIDATE_BOOLEAN);
1252
+		if ($this->disabled) {
1253
+			if (strpos($this->_other_html_attributes, $disabled_attribute) === false) {
1254
+				$this->_other_html_attributes .= $disabled_attribute;
1255
+			}
1256
+			$this->_set_normalized_value($this->get_default());
1257
+		} else {
1258
+			$this->_other_html_attributes = str_replace($disabled_attribute, '', $this->_other_html_attributes);
1259
+		}
1260
+	}
1261
+
1262
+
1263
+
1264
+	/**
1265
+	 * Returns whether or not this input is currently disabled.
1266
+	 * @return bool
1267
+	 */
1268
+	public function isDisabled()
1269
+	{
1270
+		return $this->disabled;
1271
+	}
1272 1272
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Tabbed_Content.helper.php 1 patch
Indentation   +194 added lines, -194 removed lines patch added patch discarded remove patch
@@ -13,249 +13,249 @@
 block discarded – undo
13 13
  */
14 14
 class EEH_Tabbed_Content
15 15
 {
16
-    /**
17
-     * assembles and returns the html structure for tabs
18
-     *
19
-     * @static
20
-     * @param array $tabs_contents an array of the content for each tab [required]
21
-     * @param array $tabs_names    a numerically indexed array of names for each tab [optional]
22
-     *                             - if this isn't included then we use the indexes for $tabs_content as the tab names)
23
-     * @param bool  $small_tabs
24
-     * @param bool  $tabs_content
25
-     * @return string the assembled html string containing the tabbed content for display.
26
-     * @throws EE_Error
27
-     */
28
-    public static function display($tabs_contents, $tabs_names = [], $small_tabs = true, $tabs_content = true)
29
-    {
16
+	/**
17
+	 * assembles and returns the html structure for tabs
18
+	 *
19
+	 * @static
20
+	 * @param array $tabs_contents an array of the content for each tab [required]
21
+	 * @param array $tabs_names    a numerically indexed array of names for each tab [optional]
22
+	 *                             - if this isn't included then we use the indexes for $tabs_content as the tab names)
23
+	 * @param bool  $small_tabs
24
+	 * @param bool  $tabs_content
25
+	 * @return string the assembled html string containing the tabbed content for display.
26
+	 * @throws EE_Error
27
+	 */
28
+	public static function display($tabs_contents, $tabs_names = [], $small_tabs = true, $tabs_content = true)
29
+	{
30 30
 
31
-        // first check if $tabs_names is not empty then the count must match the count of $tabs_content otherwise we've got a problem houston
32
-        if (! empty($tabs_names) && (count((array) $tabs_names) != count((array) $tabs_content))) {
33
-            throw new EE_Error(
34
-                esc_html__('The count for $tabs_names and $tabs_content does not match.', 'event_espresso')
35
-            );
36
-        }
31
+		// first check if $tabs_names is not empty then the count must match the count of $tabs_content otherwise we've got a problem houston
32
+		if (! empty($tabs_names) && (count((array) $tabs_names) != count((array) $tabs_content))) {
33
+			throw new EE_Error(
34
+				esc_html__('The count for $tabs_names and $tabs_content does not match.', 'event_espresso')
35
+			);
36
+		}
37 37
 
38
-        // make sure we've got incoming data setup properly
39
-        $tabs         = ! empty($tabs_names)
40
-            ? (array) $tabs_names
41
-            : array_keys((array) $tabs_contents);
42
-        $tabs_content = ! empty($tabs_names)
43
-            ? array_combine((array) $tabs_names, (array) $tabs_content)
44
-            : $tabs_contents;
38
+		// make sure we've got incoming data setup properly
39
+		$tabs         = ! empty($tabs_names)
40
+			? (array) $tabs_names
41
+			: array_keys((array) $tabs_contents);
42
+		$tabs_content = ! empty($tabs_names)
43
+			? array_combine((array) $tabs_names, (array) $tabs_content)
44
+			: $tabs_contents;
45 45
 
46
-        $tabs_html         = '';
47
-        $tabs_content_html = '';
46
+		$tabs_html         = '';
47
+		$tabs_content_html = '';
48 48
 
49
-        $index = 0;
50
-        foreach ($tabs as $tab) {
51
-            $active            = $index === 0;
52
-            $tabs_html         .= self::tab($tab, $active);
53
-            $tabs_content_html .= self::tab_content($tab, $tabs_content[ $tab ], $active);
54
-            $index++;
55
-        }
49
+		$index = 0;
50
+		foreach ($tabs as $tab) {
51
+			$active            = $index === 0;
52
+			$tabs_html         .= self::tab($tab, $active);
53
+			$tabs_content_html .= self::tab_content($tab, $tabs_content[ $tab ], $active);
54
+			$index++;
55
+		}
56 56
 
57
-        $tabs_class = $small_tabs ? ' ee-nav-tabs-small' : '';
57
+		$tabs_class = $small_tabs ? ' ee-nav-tabs-small' : '';
58 58
 
59
-        return "
59
+		return "
60 60
     <div class='ee-nav-tabs{$tabs_class}'>
61 61
         <h2 class='nav-tab-wrapper'>{$tabs_html}</h2>
62 62
         {$tabs_content_html}
63 63
     </div>
64 64
     ";
65
-    }
65
+	}
66 66
 
67 67
 
68
-    /**
69
-     * display_admin_nav_tabs
70
-     * this returns the properly formatted tab html for EE_Admin_Pages.
71
-     * We are expecting an array of tabs in the following format
72
-     * array(
73
-     *    'nav_tab_name' => array(
74
-     *        'url' => 'url for tab',
75
-     *        'link_text' => 'tab text',
76
-     *        'css_class' => 'tab class' //including the nav-tab-active class if its active
77
-     *    )
78
-     * )
79
-     *
80
-     * @access public
81
-     * @static
82
-     * @param string[][] $nav_tabs tab array for nav tabs
83
-     * @return string
84
-     * @throws EE_Error
85
-     */
86
-    public static function display_admin_nav_tabs(array $nav_tabs = [], string $page_slug = '')
87
-    {
88
-        if (empty($nav_tabs)) {
89
-            throw new EE_Error(
90
-                esc_html__('Nav Tabs cannot be generated because the tab array is missing', 'event_espresso')
91
-            );
92
-        }
93
-        $tab_content = '';
94
-        $tab_count = 0;
95
-        foreach ($nav_tabs as $slug => $tab) {
96
-            $tab_count++;
97
-            $tab_content .= self::tab($slug, false, $tab['link_text'], $tab['url'], $tab['css_class']);
98
-        }
99
-        $aria_label = esc_attr__('Secondary menu', 'event_espresso');
100
-        $css_class = "ee-nav-tabs--{$tab_count}";
101
-        $css_class .= $page_slug ? " ee-nav-tabs--$page_slug" : '';
102
-        return "
68
+	/**
69
+	 * display_admin_nav_tabs
70
+	 * this returns the properly formatted tab html for EE_Admin_Pages.
71
+	 * We are expecting an array of tabs in the following format
72
+	 * array(
73
+	 *    'nav_tab_name' => array(
74
+	 *        'url' => 'url for tab',
75
+	 *        'link_text' => 'tab text',
76
+	 *        'css_class' => 'tab class' //including the nav-tab-active class if its active
77
+	 *    )
78
+	 * )
79
+	 *
80
+	 * @access public
81
+	 * @static
82
+	 * @param string[][] $nav_tabs tab array for nav tabs
83
+	 * @return string
84
+	 * @throws EE_Error
85
+	 */
86
+	public static function display_admin_nav_tabs(array $nav_tabs = [], string $page_slug = '')
87
+	{
88
+		if (empty($nav_tabs)) {
89
+			throw new EE_Error(
90
+				esc_html__('Nav Tabs cannot be generated because the tab array is missing', 'event_espresso')
91
+			);
92
+		}
93
+		$tab_content = '';
94
+		$tab_count = 0;
95
+		foreach ($nav_tabs as $slug => $tab) {
96
+			$tab_count++;
97
+			$tab_content .= self::tab($slug, false, $tab['link_text'], $tab['url'], $tab['css_class']);
98
+		}
99
+		$aria_label = esc_attr__('Secondary menu', 'event_espresso');
100
+		$css_class = "ee-nav-tabs--{$tab_count}";
101
+		$css_class .= $page_slug ? " ee-nav-tabs--$page_slug" : '';
102
+		return "
103 103
         <nav class='nav-tab-wrapper wp-clearfix {$css_class}' aria-label='{$aria_label}'>
104 104
             {$tab_content}
105 105
         </nav>
106 106
         ";
107
-    }
107
+	}
108 108
 
109 109
 
110
-    /**
111
-     * this simply returns a single tab given a tab name & content
112
-     *
113
-     * @param string      $name      name of tab
114
-     * @param bool        $active    true=tab active, false=tab not active
115
-     * @param bool|string $nice_name if string given then this value will be used for the tab link text.
116
-     * @param bool|string $url       If url given then tabs will be generated linking to the url.
117
-     * @param bool|string $css       If string given then the generated tab will include that as the class.
118
-     * @return string          html for tab
119
-     */
120
-    private static function tab($name, $active = false, $nice_name = false, $url = false, $css = false)
121
-    {
122
-        $nice_name = $nice_name ?: esc_html(ucwords(str_replace(['_', '-'], ' ', $name)));
123
-        $name      = self::generateTabID($name);
124
-        $class     = $css ? ' ' . esc_attr($css) : '';
125
-        $class     .= $active ? ' nav-tab-active' : '';
126
-        $url       = $url ?: '#' . esc_attr($name);
127
-        return "
110
+	/**
111
+	 * this simply returns a single tab given a tab name & content
112
+	 *
113
+	 * @param string      $name      name of tab
114
+	 * @param bool        $active    true=tab active, false=tab not active
115
+	 * @param bool|string $nice_name if string given then this value will be used for the tab link text.
116
+	 * @param bool|string $url       If url given then tabs will be generated linking to the url.
117
+	 * @param bool|string $css       If string given then the generated tab will include that as the class.
118
+	 * @return string          html for tab
119
+	 */
120
+	private static function tab($name, $active = false, $nice_name = false, $url = false, $css = false)
121
+	{
122
+		$nice_name = $nice_name ?: esc_html(ucwords(str_replace(['_', '-'], ' ', $name)));
123
+		$name      = self::generateTabID($name);
124
+		$class     = $css ? ' ' . esc_attr($css) : '';
125
+		$class     .= $active ? ' nav-tab-active' : '';
126
+		$url       = $url ?: '#' . esc_attr($name);
127
+		return "
128 128
         <a class='nav-tab{$class}' rel='{$name}' href='{$url}'>
129 129
             $nice_name
130 130
         </a>
131 131
         ";
132
-    }
132
+	}
133 133
 
134 134
 
135
-    /**
136
-     * @param string $tab_name
137
-     * @return string
138
-     * @since   4.10.14.p
139
-     */
140
-    private static function generateTabID($tab_name)
141
-    {
142
-        return 'ee-tab-' . esc_attr(str_replace(' ', '-', $tab_name));
143
-    }
135
+	/**
136
+	 * @param string $tab_name
137
+	 * @return string
138
+	 * @since   4.10.14.p
139
+	 */
140
+	private static function generateTabID($tab_name)
141
+	{
142
+		return 'ee-tab-' . esc_attr(str_replace(' ', '-', $tab_name));
143
+	}
144 144
 
145 145
 
146
-    /**
147
-     * this just returns the properly formatted tab content for our tab box.
148
-     *
149
-     * @param string $name        name of tab (used for selector)
150
-     * @param string $tab_content content of tab
151
-     * @param bool   $active
152
-     * @return string html for content area
153
-     */
154
-    private static function tab_content($name, $tab_content, $active = false)
155
-    {
156
-        $class = $active ? '' : ' hidden';
157
-        $name  = self::generateTabID($name);
158
-        return "
146
+	/**
147
+	 * this just returns the properly formatted tab content for our tab box.
148
+	 *
149
+	 * @param string $name        name of tab (used for selector)
150
+	 * @param string $tab_content content of tab
151
+	 * @param bool   $active
152
+	 * @return string html for content area
153
+	 */
154
+	private static function tab_content($name, $tab_content, $active = false)
155
+	{
156
+		$class = $active ? '' : ' hidden';
157
+		$name  = self::generateTabID($name);
158
+		return "
159 159
     <div class='nav-tab-content{$class}' id='{$name}'>
160 160
         {$tab_content}
161 161
         <div style='clear:both'></div>
162 162
     </div>";
163
-    }
163
+	}
164 164
 
165 165
 
166 166
 
167
-    /** HORIZONTAL TEXT LINKS **/
167
+	/** HORIZONTAL TEXT LINKS **/
168 168
 
169
-    /**
170
-     * This will take in an array of link items and spit out a formatted list of links that can be used to navigate to
171
-     * items. There is a corresponding js file that can be loaded to dynamically display containers with the same id as
172
-     * the href -ref.
173
-     *
174
-     * @param string[] $item_array      formatted array of items.  Format:
175
-     *                                  array(
176
-     *                                  'label' => esc_html__('localized label displayed'),
177
-     *                                  'class' => 'class_for_item',
178
-     *                                  'href' => '#some_item_id', //url/bookmark for item.  If you include a bookmark
179
-     *                                  the js will used this to show the container div.
180
-     *                                  'title' => esc_html__('localized text for the title attribute of the link'),
181
-     *                                  'slug' => 'slug_used_for_reference'
182
-     *                                  )
183
-     * @param string   $container_class class used for main container
184
-     * @param string   $sep             you can add in what is used as a separator between each link (or leave blank for
185
-     *                                  none)
186
-     * @param string   $default         You can include a string for the item that will receive the "item_display" class
187
-     *                                  for the js.
188
-     * @return string                  a html snippet of of all the formatted link elements.
189
-     */
190
-    public static function tab_text_links(array $item_array, $container_class = '', $sep = '|', $default = '')
191
-    {
192
-        $item_array = apply_filters('FHEE__EEH_Tabbed_Content__tab_text_links', $item_array, $container_class);
193
-        if (! is_array($item_array) || empty($item_array)) {
194
-            return false; // get out we don't have even the basic thing we need!
195
-        }
169
+	/**
170
+	 * This will take in an array of link items and spit out a formatted list of links that can be used to navigate to
171
+	 * items. There is a corresponding js file that can be loaded to dynamically display containers with the same id as
172
+	 * the href -ref.
173
+	 *
174
+	 * @param string[] $item_array      formatted array of items.  Format:
175
+	 *                                  array(
176
+	 *                                  'label' => esc_html__('localized label displayed'),
177
+	 *                                  'class' => 'class_for_item',
178
+	 *                                  'href' => '#some_item_id', //url/bookmark for item.  If you include a bookmark
179
+	 *                                  the js will used this to show the container div.
180
+	 *                                  'title' => esc_html__('localized text for the title attribute of the link'),
181
+	 *                                  'slug' => 'slug_used_for_reference'
182
+	 *                                  )
183
+	 * @param string   $container_class class used for main container
184
+	 * @param string   $sep             you can add in what is used as a separator between each link (or leave blank for
185
+	 *                                  none)
186
+	 * @param string   $default         You can include a string for the item that will receive the "item_display" class
187
+	 *                                  for the js.
188
+	 * @return string                  a html snippet of of all the formatted link elements.
189
+	 */
190
+	public static function tab_text_links(array $item_array, $container_class = '', $sep = '|', $default = '')
191
+	{
192
+		$item_array = apply_filters('FHEE__EEH_Tabbed_Content__tab_text_links', $item_array, $container_class);
193
+		if (! is_array($item_array) || empty($item_array)) {
194
+			return false; // get out we don't have even the basic thing we need!
195
+		}
196 196
 
197
-        $defaults        = [
198
-            'label' => esc_html__('Item', 'event_espresso'),
199
-            'class' => '',
200
-            'href'  => '',
201
-            'title' => esc_attr__('Link for Item', 'event_espresso'),
202
-            'slug'  => 'item_slug',
203
-        ];
204
-        $container_class = ! empty($container_class) ? ' ' . esc_attr($container_class) : '';
205
-        $list            = '';
206
-        $list_length     = count($item_array);
207
-        // if we're' adding separators, set $current to 1, otherwise set it to list length + 1
208
-        // then we'll increment $current while looping and only add separators if $current is < list length
209
-        // (if we aren't adding separators $current will always be > list length cuz it started at list length + 1)
210
-        $current = empty($sep) ? $list_length + 1 : 1;
211
-        foreach ($item_array as $item) {
212
-            $item          = wp_parse_args($item, $defaults);
213
-            $item['class'] .= $default === $item['slug'] ? ' item_display' : '';
214
-            $list          .= self::textLinkItem($item);
215
-            $list          .= $current < $list_length ? self::textLinkSeparator($sep) : '';
216
-            $current++;
217
-        }
197
+		$defaults        = [
198
+			'label' => esc_html__('Item', 'event_espresso'),
199
+			'class' => '',
200
+			'href'  => '',
201
+			'title' => esc_attr__('Link for Item', 'event_espresso'),
202
+			'slug'  => 'item_slug',
203
+		];
204
+		$container_class = ! empty($container_class) ? ' ' . esc_attr($container_class) : '';
205
+		$list            = '';
206
+		$list_length     = count($item_array);
207
+		// if we're' adding separators, set $current to 1, otherwise set it to list length + 1
208
+		// then we'll increment $current while looping and only add separators if $current is < list length
209
+		// (if we aren't adding separators $current will always be > list length cuz it started at list length + 1)
210
+		$current = empty($sep) ? $list_length + 1 : 1;
211
+		foreach ($item_array as $item) {
212
+			$item          = wp_parse_args($item, $defaults);
213
+			$item['class'] .= $default === $item['slug'] ? ' item_display' : '';
214
+			$list          .= self::textLinkItem($item);
215
+			$list          .= $current < $list_length ? self::textLinkSeparator($sep) : '';
216
+			$current++;
217
+		}
218 218
 
219
-        return "
219
+		return "
220 220
         <div class='ee-text-links{$container_class}'>{$list}</div>
221 221
         ";
222
-    }
222
+	}
223 223
 
224 224
 
225
-    /**
226
-     * @param string[] $item
227
-     * @return string
228
-     */
229
-    private static function textLinkItem(array $item)
230
-    {
231
-        $class = $item['class'] ? esc_attr($item['class']) : '';
232
-        $label = esc_html($item['label']);
233
-        $href  = $item['href'] ? esc_attr($item['href']) : '';
234
-        $icon  = $item['icon'] ?? '';
235
-        $title = esc_attr($item['title']);
236
-        $tag = $item['tag'] ?? 'a';
225
+	/**
226
+	 * @param string[] $item
227
+	 * @return string
228
+	 */
229
+	private static function textLinkItem(array $item)
230
+	{
231
+		$class = $item['class'] ? esc_attr($item['class']) : '';
232
+		$label = esc_html($item['label']);
233
+		$href  = $item['href'] ? esc_attr($item['href']) : '';
234
+		$icon  = $item['icon'] ?? '';
235
+		$title = esc_attr($item['title']);
236
+		$tag = $item['tag'] ?? 'a';
237 237
 
238 238
 
239
-        return ! empty($href)
240
-            ? "
239
+		return ! empty($href)
240
+			? "
241 241
             <{$tag} class='{$class} ee-text-link ee-aria-tooltip' href='#{$href}' aria-label='{$title}'>
242 242
                 {$icon}{$label}
243 243
             </{$tag}>
244 244
             "
245
-            : $label;
246
-    }
245
+			: $label;
246
+	}
247 247
 
248 248
 
249
-    /**
250
-     * @param string $separator
251
-     * @return string
252
-     * @since   4.10.14.p
253
-     */
254
-    private static function textLinkSeparator($separator)
255
-    {
256
-        $separator = esc_html($separator);
257
-        return "
249
+	/**
250
+	 * @param string $separator
251
+	 * @return string
252
+	 * @since   4.10.14.p
253
+	 */
254
+	private static function textLinkSeparator($separator)
255
+	{
256
+		$separator = esc_html($separator);
257
+		return "
258 258
         <span class='ee-text-link-sep'>{$separator}</span>
259 259
         ";
260
-    }
260
+	}
261 261
 }
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 1 patch
Indentation   +1358 added lines, -1358 removed lines patch added patch discarded remove patch
@@ -14,1368 +14,1368 @@
 block discarded – undo
14 14
  */
15 15
 class Extend_Events_Admin_Page extends Events_Admin_Page
16 16
 {
17
-    /**
18
-     * @var EE_Admin_Config
19
-     */
20
-    protected $admin_config;
21
-
22
-
23
-    /**
24
-     * Extend_Events_Admin_Page constructor.
25
-     *
26
-     * @param bool $routing
27
-     * @throws EE_Error
28
-     * @throws ReflectionException
29
-     */
30
-    public function __construct($routing = true)
31
-    {
32
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
33
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
34
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
35
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
36
-        }
37
-        parent::__construct($routing);
38
-        $this->admin_config = $this->loader->getShared('EE_Admin_Config');
39
-    }
40
-
41
-
42
-    /**
43
-     * Sets routes.
44
-     *
45
-     * @throws EE_Error
46
-     */
47
-    protected function _extend_page_config()
48
-    {
49
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
50
-        // is there a evt_id in the request?
51
-        $EVT_ID             = $this->request->getRequestParam('EVT_ID', 0, 'int');
52
-        $EVT_ID             = $this->request->getRequestParam('post', $EVT_ID, 'int');
53
-        $TKT_ID             = $this->request->getRequestParam('TKT_ID', 0, 'int');
54
-        $new_page_routes    = [
55
-            'duplicate_event'          => [
56
-                'func'       => '_duplicate_event',
57
-                'capability' => 'ee_edit_event',
58
-                'obj_id'     => $EVT_ID,
59
-                'noheader'   => true,
60
-            ],
61
-            'import_page'              => [
62
-                'func'       => '_import_page',
63
-                'capability' => 'import',
64
-            ],
65
-            'import'                   => [
66
-                'func'       => '_import_events',
67
-                'capability' => 'import',
68
-                'noheader'   => true,
69
-            ],
70
-            'import_events'            => [
71
-                'func'       => '_import_events',
72
-                'capability' => 'import',
73
-                'noheader'   => true,
74
-            ],
75
-            'export_events'            => [
76
-                'func'       => '_events_export',
77
-                'capability' => 'export',
78
-                'noheader'   => true,
79
-            ],
80
-            'export_categories'        => [
81
-                'func'       => '_categories_export',
82
-                'capability' => 'export',
83
-                'noheader'   => true,
84
-            ],
85
-            'sample_export_file'       => [
86
-                'func'       => '_sample_export_file',
87
-                'capability' => 'export',
88
-                'noheader'   => true,
89
-            ],
90
-            'update_template_settings' => [
91
-                'func'       => '_update_template_settings',
92
-                'capability' => 'manage_options',
93
-                'noheader'   => true,
94
-            ],
95
-            'ticket_list_table'        => [
96
-                'func'       => '_tickets_overview_list_table',
97
-                'capability' => 'ee_read_default_tickets',
98
-            ],
99
-        ];
100
-        $this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
101
-        $this->_page_config['edit']['metaboxes'][]       = '_premium_event_editor_meta_boxes';
102
-        // don't load these meta boxes if using the advanced editor
103
-        if (
104
-            ! $this->admin_config->useAdvancedEditor()
105
-            || ! $this->feature->allowed('use_default_ticket_manager')
106
-        ) {
107
-            $this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
108
-            $this->_page_config['edit']['qtips'][]       = 'EE_Event_Editor_Tips';
109
-
110
-            $legacy_editor_page_routes = [
111
-                'trash_ticket'    => [
112
-                    'func'       => '_trash_or_restore_ticket',
113
-                    'capability' => 'ee_delete_default_ticket',
114
-                    'obj_id'     => $TKT_ID,
115
-                    'noheader'   => true,
116
-                    'args'       => ['trash' => true],
117
-                ],
118
-                'trash_tickets'   => [
119
-                    'func'       => '_trash_or_restore_ticket',
120
-                    'capability' => 'ee_delete_default_tickets',
121
-                    'noheader'   => true,
122
-                    'args'       => ['trash' => true],
123
-                ],
124
-                'restore_ticket'  => [
125
-                    'func'       => '_trash_or_restore_ticket',
126
-                    'capability' => 'ee_delete_default_ticket',
127
-                    'obj_id'     => $TKT_ID,
128
-                    'noheader'   => true,
129
-                ],
130
-                'restore_tickets' => [
131
-                    'func'       => '_trash_or_restore_ticket',
132
-                    'capability' => 'ee_delete_default_tickets',
133
-                    'noheader'   => true,
134
-                ],
135
-                'delete_ticket'   => [
136
-                    'func'       => '_delete_ticket',
137
-                    'capability' => 'ee_delete_default_ticket',
138
-                    'obj_id'     => $TKT_ID,
139
-                    'noheader'   => true,
140
-                ],
141
-                'delete_tickets'  => [
142
-                    'func'       => '_delete_ticket',
143
-                    'capability' => 'ee_delete_default_tickets',
144
-                    'noheader'   => true,
145
-                ],
146
-            ];
147
-            $new_page_routes           = array_merge($new_page_routes, $legacy_editor_page_routes);
148
-        }
149
-
150
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
151
-        // partial route/config override
152
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
153
-        $this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
154
-        // add tickets tab but only if there are more than one default ticket!
155
-        $ticket_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
156
-            [['TKT_is_default' => 1]],
157
-            'TKT_ID',
158
-            true
159
-        );
160
-        if ($ticket_count > 1) {
161
-            $new_page_config = [
162
-                'ticket_list_table' => [
163
-                    'nav'           => [
164
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
165
-                        'icon'  => 'dashicons-tickets-alt',
166
-                        'order' => 60,
167
-                    ],
168
-                    'list_table'    => 'Tickets_List_Table',
169
-                    'require_nonce' => false,
170
-                ],
171
-            ];
172
-        }
173
-        // template settings
174
-        $new_page_config['template_settings'] = [
175
-            'nav'           => [
176
-                'label' => esc_html__('Templates', 'event_espresso'),
177
-                'icon' => 'dashicons-layout',
178
-                'order' => 30,
179
-            ],
180
-            'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
181
-            'help_tabs'     => [
182
-                'general_settings_templates_help_tab' => [
183
-                    'title'    => esc_html__('Templates', 'event_espresso'),
184
-                    'filename' => 'general_settings_templates',
185
-                ],
186
-            ],
187
-            'require_nonce' => false,
188
-        ];
189
-        $this->_page_config                   = array_merge($this->_page_config, $new_page_config);
190
-        // add filters and actions
191
-        // modifying _views
192
-        add_filter(
193
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
194
-            [$this, 'add_additional_datetime_button'],
195
-            10,
196
-            2
197
-        );
198
-        add_filter(
199
-            'FHEE_event_datetime_metabox_clone_button_template',
200
-            [$this, 'add_datetime_clone_button'],
201
-            10,
202
-            2
203
-        );
204
-        add_filter(
205
-            'FHEE_event_datetime_metabox_timezones_template',
206
-            [$this, 'datetime_timezones_template'],
207
-            10,
208
-            2
209
-        );
210
-        // filters for event list table
211
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', [$this, 'list_table_filters'], 10, 2);
212
-        add_filter(
213
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
214
-            [$this, 'extra_list_table_actions'],
215
-            10,
216
-            2
217
-        );
218
-        // legend item
219
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', [$this, 'additional_legend_items']);
220
-        add_action('admin_init', [$this, 'admin_init']);
221
-    }
222
-
223
-
224
-    /**
225
-     * admin_init
226
-     */
227
-    public function admin_init()
228
-    {
229
-        EE_Registry::$i18n_js_strings = array_merge(
230
-            EE_Registry::$i18n_js_strings,
231
-            [
232
-                'image_confirm'          => esc_html__(
233
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
234
-                    'event_espresso'
235
-                ),
236
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
237
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
238
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
239
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
240
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
241
-            ]
242
-        );
243
-    }
244
-
245
-
246
-    /**
247
-     * Add per page screen options to the default ticket list table view.
248
-     *
249
-     * @throws InvalidArgumentException
250
-     * @throws InvalidDataTypeException
251
-     * @throws InvalidInterfaceException
252
-     */
253
-    protected function _add_screen_options_ticket_list_table()
254
-    {
255
-        $this->_per_page_screen_option();
256
-    }
257
-
258
-
259
-    /**
260
-     * @param string $return
261
-     * @param int    $id
262
-     * @param string $new_title
263
-     * @param string $new_slug
264
-     * @return string
265
-     */
266
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
267
-    {
268
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
269
-        // make sure this is only when editing
270
-        if (! empty($id)) {
271
-            $href   = EE_Admin_Page::add_query_args_and_nonce(
272
-                ['action' => 'duplicate_event', 'EVT_ID' => $id],
273
-                $this->_admin_base_url
274
-            );
275
-            $title  = esc_attr__('Duplicate Event', 'event_espresso');
276
-            $return .= '<a href="'
277
-                       . $href
278
-                       . '" title="'
279
-                       . $title
280
-                       . '" id="ee-duplicate-event-button" class="button button--small button--secondary"  value="duplicate_event">'
281
-                       . $title
282
-                       . '</a>';
283
-        }
284
-        return $return;
285
-    }
286
-
287
-
288
-    /**
289
-     * Set the list table views for the default ticket list table view.
290
-     */
291
-    public function _set_list_table_views_ticket_list_table()
292
-    {
293
-        $this->_views = [
294
-            'all'     => [
295
-                'slug'        => 'all',
296
-                'label'       => esc_html__('All', 'event_espresso'),
297
-                'count'       => 0,
298
-                'bulk_action' => [
299
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
300
-                ],
301
-            ],
302
-            'trashed' => [
303
-                'slug'        => 'trashed',
304
-                'label'       => esc_html__('Trash', 'event_espresso'),
305
-                'count'       => 0,
306
-                'bulk_action' => [
307
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
308
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
309
-                ],
310
-            ],
311
-        ];
312
-    }
313
-
314
-
315
-    /**
316
-     * Enqueue scripts and styles for the event editor.
317
-     */
318
-    public function load_scripts_styles_edit()
319
-    {
320
-        if (! $this->admin_config->useAdvancedEditor()) {
321
-            wp_register_script(
322
-                'ee-event-editor-heartbeat',
323
-                EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
324
-                ['ee_admin_js', 'heartbeat'],
325
-                EVENT_ESPRESSO_VERSION,
326
-                true
327
-            );
328
-            wp_enqueue_script('ee-accounting');
329
-            wp_enqueue_script('ee-event-editor-heartbeat');
330
-        }
331
-        wp_enqueue_script('event_editor_js');
332
-        // styles
333
-        wp_enqueue_style('espresso-ui-theme');
334
-    }
335
-
336
-
337
-    /**
338
-     * Returns template for the additional datetime.
339
-     *
340
-     * @param string $template
341
-     * @param array  $template_args
342
-     * @return string
343
-     * @throws DomainException
344
-     */
345
-    public function add_additional_datetime_button($template, $template_args)
346
-    {
347
-        return EEH_Template::display_template(
348
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
349
-            $template_args,
350
-            true
351
-        );
352
-    }
353
-
354
-
355
-    /**
356
-     * Returns the template for cloning a datetime.
357
-     *
358
-     * @param $template
359
-     * @param $template_args
360
-     * @return string
361
-     * @throws DomainException
362
-     */
363
-    public function add_datetime_clone_button($template, $template_args)
364
-    {
365
-        return EEH_Template::display_template(
366
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
367
-            $template_args,
368
-            true
369
-        );
370
-    }
371
-
372
-
373
-    /**
374
-     * Returns the template for datetime timezones.
375
-     *
376
-     * @param $template
377
-     * @param $template_args
378
-     * @return string
379
-     * @throws DomainException
380
-     */
381
-    public function datetime_timezones_template($template, $template_args)
382
-    {
383
-        return EEH_Template::display_template(
384
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
385
-            $template_args,
386
-            true
387
-        );
388
-    }
389
-
390
-
391
-    /**
392
-     * Sets the views for the default list table view.
393
-     *
394
-     * @throws EE_Error
395
-     */
396
-    protected function _set_list_table_views_default()
397
-    {
398
-        parent::_set_list_table_views_default();
399
-        $new_views    = [
400
-            'today' => [
401
-                'slug'        => 'today',
402
-                'label'       => esc_html__('Today', 'event_espresso'),
403
-                'count'       => $this->total_events_today(),
404
-                'bulk_action' => [
405
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
406
-                ],
407
-            ],
408
-            'month' => [
409
-                'slug'        => 'month',
410
-                'label'       => esc_html__('This Month', 'event_espresso'),
411
-                'count'       => $this->total_events_this_month(),
412
-                'bulk_action' => [
413
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
414
-                ],
415
-            ],
416
-        ];
417
-        $this->_views = array_merge($this->_views, $new_views);
418
-    }
419
-
420
-
421
-    /**
422
-     * Returns the extra action links for the default list table view.
423
-     *
424
-     * @param array    $action_links
425
-     * @param EE_Event $event
426
-     * @return array
427
-     * @throws EE_Error
428
-     * @throws ReflectionException
429
-     */
430
-    public function extra_list_table_actions(array $action_links, EE_Event $event)
431
-    {
432
-        if (
433
-            EE_Registry::instance()->CAP->current_user_can(
434
-                'ee_read_registrations',
435
-                'espresso_registrations_reports',
436
-                $event->ID()
437
-            )
438
-        ) {
439
-            $reports_link = EE_Admin_Page::add_query_args_and_nonce(
440
-                [
441
-                    'action' => 'reports',
442
-                    'EVT_ID' => $event->ID(),
443
-                ],
444
-                REG_ADMIN_URL
445
-            );
446
-
447
-            $action_links[]     = '
17
+	/**
18
+	 * @var EE_Admin_Config
19
+	 */
20
+	protected $admin_config;
21
+
22
+
23
+	/**
24
+	 * Extend_Events_Admin_Page constructor.
25
+	 *
26
+	 * @param bool $routing
27
+	 * @throws EE_Error
28
+	 * @throws ReflectionException
29
+	 */
30
+	public function __construct($routing = true)
31
+	{
32
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
33
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
34
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
35
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
36
+		}
37
+		parent::__construct($routing);
38
+		$this->admin_config = $this->loader->getShared('EE_Admin_Config');
39
+	}
40
+
41
+
42
+	/**
43
+	 * Sets routes.
44
+	 *
45
+	 * @throws EE_Error
46
+	 */
47
+	protected function _extend_page_config()
48
+	{
49
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
50
+		// is there a evt_id in the request?
51
+		$EVT_ID             = $this->request->getRequestParam('EVT_ID', 0, 'int');
52
+		$EVT_ID             = $this->request->getRequestParam('post', $EVT_ID, 'int');
53
+		$TKT_ID             = $this->request->getRequestParam('TKT_ID', 0, 'int');
54
+		$new_page_routes    = [
55
+			'duplicate_event'          => [
56
+				'func'       => '_duplicate_event',
57
+				'capability' => 'ee_edit_event',
58
+				'obj_id'     => $EVT_ID,
59
+				'noheader'   => true,
60
+			],
61
+			'import_page'              => [
62
+				'func'       => '_import_page',
63
+				'capability' => 'import',
64
+			],
65
+			'import'                   => [
66
+				'func'       => '_import_events',
67
+				'capability' => 'import',
68
+				'noheader'   => true,
69
+			],
70
+			'import_events'            => [
71
+				'func'       => '_import_events',
72
+				'capability' => 'import',
73
+				'noheader'   => true,
74
+			],
75
+			'export_events'            => [
76
+				'func'       => '_events_export',
77
+				'capability' => 'export',
78
+				'noheader'   => true,
79
+			],
80
+			'export_categories'        => [
81
+				'func'       => '_categories_export',
82
+				'capability' => 'export',
83
+				'noheader'   => true,
84
+			],
85
+			'sample_export_file'       => [
86
+				'func'       => '_sample_export_file',
87
+				'capability' => 'export',
88
+				'noheader'   => true,
89
+			],
90
+			'update_template_settings' => [
91
+				'func'       => '_update_template_settings',
92
+				'capability' => 'manage_options',
93
+				'noheader'   => true,
94
+			],
95
+			'ticket_list_table'        => [
96
+				'func'       => '_tickets_overview_list_table',
97
+				'capability' => 'ee_read_default_tickets',
98
+			],
99
+		];
100
+		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
101
+		$this->_page_config['edit']['metaboxes'][]       = '_premium_event_editor_meta_boxes';
102
+		// don't load these meta boxes if using the advanced editor
103
+		if (
104
+			! $this->admin_config->useAdvancedEditor()
105
+			|| ! $this->feature->allowed('use_default_ticket_manager')
106
+		) {
107
+			$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
108
+			$this->_page_config['edit']['qtips'][]       = 'EE_Event_Editor_Tips';
109
+
110
+			$legacy_editor_page_routes = [
111
+				'trash_ticket'    => [
112
+					'func'       => '_trash_or_restore_ticket',
113
+					'capability' => 'ee_delete_default_ticket',
114
+					'obj_id'     => $TKT_ID,
115
+					'noheader'   => true,
116
+					'args'       => ['trash' => true],
117
+				],
118
+				'trash_tickets'   => [
119
+					'func'       => '_trash_or_restore_ticket',
120
+					'capability' => 'ee_delete_default_tickets',
121
+					'noheader'   => true,
122
+					'args'       => ['trash' => true],
123
+				],
124
+				'restore_ticket'  => [
125
+					'func'       => '_trash_or_restore_ticket',
126
+					'capability' => 'ee_delete_default_ticket',
127
+					'obj_id'     => $TKT_ID,
128
+					'noheader'   => true,
129
+				],
130
+				'restore_tickets' => [
131
+					'func'       => '_trash_or_restore_ticket',
132
+					'capability' => 'ee_delete_default_tickets',
133
+					'noheader'   => true,
134
+				],
135
+				'delete_ticket'   => [
136
+					'func'       => '_delete_ticket',
137
+					'capability' => 'ee_delete_default_ticket',
138
+					'obj_id'     => $TKT_ID,
139
+					'noheader'   => true,
140
+				],
141
+				'delete_tickets'  => [
142
+					'func'       => '_delete_ticket',
143
+					'capability' => 'ee_delete_default_tickets',
144
+					'noheader'   => true,
145
+				],
146
+			];
147
+			$new_page_routes           = array_merge($new_page_routes, $legacy_editor_page_routes);
148
+		}
149
+
150
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
151
+		// partial route/config override
152
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
153
+		$this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
154
+		// add tickets tab but only if there are more than one default ticket!
155
+		$ticket_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
156
+			[['TKT_is_default' => 1]],
157
+			'TKT_ID',
158
+			true
159
+		);
160
+		if ($ticket_count > 1) {
161
+			$new_page_config = [
162
+				'ticket_list_table' => [
163
+					'nav'           => [
164
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
165
+						'icon'  => 'dashicons-tickets-alt',
166
+						'order' => 60,
167
+					],
168
+					'list_table'    => 'Tickets_List_Table',
169
+					'require_nonce' => false,
170
+				],
171
+			];
172
+		}
173
+		// template settings
174
+		$new_page_config['template_settings'] = [
175
+			'nav'           => [
176
+				'label' => esc_html__('Templates', 'event_espresso'),
177
+				'icon' => 'dashicons-layout',
178
+				'order' => 30,
179
+			],
180
+			'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
181
+			'help_tabs'     => [
182
+				'general_settings_templates_help_tab' => [
183
+					'title'    => esc_html__('Templates', 'event_espresso'),
184
+					'filename' => 'general_settings_templates',
185
+				],
186
+			],
187
+			'require_nonce' => false,
188
+		];
189
+		$this->_page_config                   = array_merge($this->_page_config, $new_page_config);
190
+		// add filters and actions
191
+		// modifying _views
192
+		add_filter(
193
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
194
+			[$this, 'add_additional_datetime_button'],
195
+			10,
196
+			2
197
+		);
198
+		add_filter(
199
+			'FHEE_event_datetime_metabox_clone_button_template',
200
+			[$this, 'add_datetime_clone_button'],
201
+			10,
202
+			2
203
+		);
204
+		add_filter(
205
+			'FHEE_event_datetime_metabox_timezones_template',
206
+			[$this, 'datetime_timezones_template'],
207
+			10,
208
+			2
209
+		);
210
+		// filters for event list table
211
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', [$this, 'list_table_filters'], 10, 2);
212
+		add_filter(
213
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
214
+			[$this, 'extra_list_table_actions'],
215
+			10,
216
+			2
217
+		);
218
+		// legend item
219
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', [$this, 'additional_legend_items']);
220
+		add_action('admin_init', [$this, 'admin_init']);
221
+	}
222
+
223
+
224
+	/**
225
+	 * admin_init
226
+	 */
227
+	public function admin_init()
228
+	{
229
+		EE_Registry::$i18n_js_strings = array_merge(
230
+			EE_Registry::$i18n_js_strings,
231
+			[
232
+				'image_confirm'          => esc_html__(
233
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
234
+					'event_espresso'
235
+				),
236
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
237
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
238
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
239
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
240
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
241
+			]
242
+		);
243
+	}
244
+
245
+
246
+	/**
247
+	 * Add per page screen options to the default ticket list table view.
248
+	 *
249
+	 * @throws InvalidArgumentException
250
+	 * @throws InvalidDataTypeException
251
+	 * @throws InvalidInterfaceException
252
+	 */
253
+	protected function _add_screen_options_ticket_list_table()
254
+	{
255
+		$this->_per_page_screen_option();
256
+	}
257
+
258
+
259
+	/**
260
+	 * @param string $return
261
+	 * @param int    $id
262
+	 * @param string $new_title
263
+	 * @param string $new_slug
264
+	 * @return string
265
+	 */
266
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
267
+	{
268
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
269
+		// make sure this is only when editing
270
+		if (! empty($id)) {
271
+			$href   = EE_Admin_Page::add_query_args_and_nonce(
272
+				['action' => 'duplicate_event', 'EVT_ID' => $id],
273
+				$this->_admin_base_url
274
+			);
275
+			$title  = esc_attr__('Duplicate Event', 'event_espresso');
276
+			$return .= '<a href="'
277
+					   . $href
278
+					   . '" title="'
279
+					   . $title
280
+					   . '" id="ee-duplicate-event-button" class="button button--small button--secondary"  value="duplicate_event">'
281
+					   . $title
282
+					   . '</a>';
283
+		}
284
+		return $return;
285
+	}
286
+
287
+
288
+	/**
289
+	 * Set the list table views for the default ticket list table view.
290
+	 */
291
+	public function _set_list_table_views_ticket_list_table()
292
+	{
293
+		$this->_views = [
294
+			'all'     => [
295
+				'slug'        => 'all',
296
+				'label'       => esc_html__('All', 'event_espresso'),
297
+				'count'       => 0,
298
+				'bulk_action' => [
299
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
300
+				],
301
+			],
302
+			'trashed' => [
303
+				'slug'        => 'trashed',
304
+				'label'       => esc_html__('Trash', 'event_espresso'),
305
+				'count'       => 0,
306
+				'bulk_action' => [
307
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
308
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
309
+				],
310
+			],
311
+		];
312
+	}
313
+
314
+
315
+	/**
316
+	 * Enqueue scripts and styles for the event editor.
317
+	 */
318
+	public function load_scripts_styles_edit()
319
+	{
320
+		if (! $this->admin_config->useAdvancedEditor()) {
321
+			wp_register_script(
322
+				'ee-event-editor-heartbeat',
323
+				EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
324
+				['ee_admin_js', 'heartbeat'],
325
+				EVENT_ESPRESSO_VERSION,
326
+				true
327
+			);
328
+			wp_enqueue_script('ee-accounting');
329
+			wp_enqueue_script('ee-event-editor-heartbeat');
330
+		}
331
+		wp_enqueue_script('event_editor_js');
332
+		// styles
333
+		wp_enqueue_style('espresso-ui-theme');
334
+	}
335
+
336
+
337
+	/**
338
+	 * Returns template for the additional datetime.
339
+	 *
340
+	 * @param string $template
341
+	 * @param array  $template_args
342
+	 * @return string
343
+	 * @throws DomainException
344
+	 */
345
+	public function add_additional_datetime_button($template, $template_args)
346
+	{
347
+		return EEH_Template::display_template(
348
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
349
+			$template_args,
350
+			true
351
+		);
352
+	}
353
+
354
+
355
+	/**
356
+	 * Returns the template for cloning a datetime.
357
+	 *
358
+	 * @param $template
359
+	 * @param $template_args
360
+	 * @return string
361
+	 * @throws DomainException
362
+	 */
363
+	public function add_datetime_clone_button($template, $template_args)
364
+	{
365
+		return EEH_Template::display_template(
366
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
367
+			$template_args,
368
+			true
369
+		);
370
+	}
371
+
372
+
373
+	/**
374
+	 * Returns the template for datetime timezones.
375
+	 *
376
+	 * @param $template
377
+	 * @param $template_args
378
+	 * @return string
379
+	 * @throws DomainException
380
+	 */
381
+	public function datetime_timezones_template($template, $template_args)
382
+	{
383
+		return EEH_Template::display_template(
384
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
385
+			$template_args,
386
+			true
387
+		);
388
+	}
389
+
390
+
391
+	/**
392
+	 * Sets the views for the default list table view.
393
+	 *
394
+	 * @throws EE_Error
395
+	 */
396
+	protected function _set_list_table_views_default()
397
+	{
398
+		parent::_set_list_table_views_default();
399
+		$new_views    = [
400
+			'today' => [
401
+				'slug'        => 'today',
402
+				'label'       => esc_html__('Today', 'event_espresso'),
403
+				'count'       => $this->total_events_today(),
404
+				'bulk_action' => [
405
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
406
+				],
407
+			],
408
+			'month' => [
409
+				'slug'        => 'month',
410
+				'label'       => esc_html__('This Month', 'event_espresso'),
411
+				'count'       => $this->total_events_this_month(),
412
+				'bulk_action' => [
413
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
414
+				],
415
+			],
416
+		];
417
+		$this->_views = array_merge($this->_views, $new_views);
418
+	}
419
+
420
+
421
+	/**
422
+	 * Returns the extra action links for the default list table view.
423
+	 *
424
+	 * @param array    $action_links
425
+	 * @param EE_Event $event
426
+	 * @return array
427
+	 * @throws EE_Error
428
+	 * @throws ReflectionException
429
+	 */
430
+	public function extra_list_table_actions(array $action_links, EE_Event $event)
431
+	{
432
+		if (
433
+			EE_Registry::instance()->CAP->current_user_can(
434
+				'ee_read_registrations',
435
+				'espresso_registrations_reports',
436
+				$event->ID()
437
+			)
438
+		) {
439
+			$reports_link = EE_Admin_Page::add_query_args_and_nonce(
440
+				[
441
+					'action' => 'reports',
442
+					'EVT_ID' => $event->ID(),
443
+				],
444
+				REG_ADMIN_URL
445
+			);
446
+
447
+			$action_links[]     = '
448 448
                 <a href="' . $reports_link . '" 
449 449
                     aria-label="' . esc_attr__('View Report', 'event_espresso') . '" 
450 450
                     class="ee-aria-tooltip button button--icon-only"
451 451
                 >
452 452
                     <span class="dashicons dashicons-chart-bar"></span>
453 453
                 </a>';
454
-        }
455
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
456
-            EE_Registry::instance()->load_helper('MSG_Template');
457
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
458
-                'see_notifications_for',
459
-                null,
460
-                ['EVT_ID' => $event->ID()]
461
-            );
462
-        }
463
-        return $action_links;
464
-    }
465
-
466
-
467
-    /**
468
-     * @param $items
469
-     * @return mixed
470
-     */
471
-    public function additional_legend_items($items)
472
-    {
473
-        if (
474
-            EE_Registry::instance()->CAP->current_user_can(
475
-                'ee_read_registrations',
476
-                'espresso_registrations_reports'
477
-            )
478
-        ) {
479
-            $items['reports'] = [
480
-                'class' => 'dashicons dashicons-chart-bar',
481
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
482
-            ];
483
-        }
484
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
485
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
486
-            // $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
487
-            // (can only use numeric offsets when treating strings as arrays)
488
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
489
-                $items['view_related_messages'] = [
490
-                    'class' => $related_for_icon['css_class'],
491
-                    'desc'  => $related_for_icon['label'],
492
-                ];
493
-            }
494
-        }
495
-        return $items;
496
-    }
497
-
498
-
499
-    /**
500
-     * This is the callback method for the duplicate event route
501
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
502
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
503
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
504
-     * After duplication the redirect is to the new event edit page.
505
-     *
506
-     * @return void
507
-     * @throws EE_Error If EE_Event is not available with given ID
508
-     * @throws ReflectionException
509
-     * @access protected
510
-     */
511
-    protected function _duplicate_event()
512
-    {
513
-        // first make sure the ID for the event is in the request.
514
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
515
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
516
-        if (! $EVT_ID) {
517
-            EE_Error::add_error(
518
-                esc_html__(
519
-                    'In order to duplicate an event an Event ID is required.  None was given.',
520
-                    'event_espresso'
521
-                ),
522
-                __FILE__,
523
-                __FUNCTION__,
524
-                __LINE__
525
-            );
526
-            $this->_redirect_after_action(false, '', '', [], true);
527
-            return;
528
-        }
529
-        // k we've got EVT_ID so let's use that to get the event we'll duplicate
530
-        $orig_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
531
-        if (! $orig_event instanceof EE_Event) {
532
-            throw new EE_Error(
533
-                sprintf(
534
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
535
-                    $EVT_ID
536
-                )
537
-            );
538
-        }
539
-        // k now let's clone the $orig_event before getting relations
540
-        $new_event = clone $orig_event;
541
-        // original datetimes
542
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
543
-        // other original relations
544
-        $orig_ven = $orig_event->get_many_related('Venue');
545
-        // reset the ID and modify other details to make it clear this is a dupe
546
-        $new_event->set('EVT_ID', 0);
547
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
548
-        $new_event->set('EVT_name', $new_name);
549
-        $new_event->set(
550
-            'EVT_slug',
551
-            wp_unique_post_slug(
552
-                sanitize_title($orig_event->name()),
553
-                0,
554
-                'publish',
555
-                'espresso_events',
556
-                0
557
-            )
558
-        );
559
-        $new_event->set('status', 'draft');
560
-        // duplicate discussion settings
561
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
562
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
563
-        // save the new event
564
-        $new_event->save();
565
-        // venues
566
-        foreach ($orig_ven as $ven) {
567
-            $new_event->_add_relation_to($ven, 'Venue');
568
-        }
569
-        $new_event->save();
570
-        // now we need to get the question group relations and handle that
571
-        // first primary question groups
572
-        $orig_primary_qgs = $orig_event->get_many_related(
573
-            'Question_Group',
574
-            [['Event_Question_Group.EQG_primary' => true]]
575
-        );
576
-        if (! empty($orig_primary_qgs)) {
577
-            foreach ($orig_primary_qgs as $obj) {
578
-                if ($obj instanceof EE_Question_Group) {
579
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
580
-                }
581
-            }
582
-        }
583
-        // next additional attendee question groups
584
-        $orig_additional_qgs = $orig_event->get_many_related(
585
-            'Question_Group',
586
-            [['Event_Question_Group.EQG_additional' => true]]
587
-        );
588
-        if (! empty($orig_additional_qgs)) {
589
-            foreach ($orig_additional_qgs as $obj) {
590
-                if ($obj instanceof EE_Question_Group) {
591
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
592
-                }
593
-            }
594
-        }
595
-
596
-        $new_event->save();
597
-
598
-        // k now that we have the new event saved we can loop through the datetimes and start adding relations.
599
-        $cloned_tickets = [];
600
-        foreach ($orig_datetimes as $orig_dtt) {
601
-            if (! $orig_dtt instanceof EE_Datetime) {
602
-                continue;
603
-            }
604
-            $new_dtt      = clone $orig_dtt;
605
-            $orig_tickets = $orig_dtt->tickets();
606
-            // save new dtt then add to event
607
-            $new_dtt->set('DTT_ID', 0);
608
-            $new_dtt->set('DTT_sold', 0);
609
-            $new_dtt->set_reserved(0);
610
-            $new_dtt->save();
611
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
612
-            $new_event->save();
613
-            // now let's get the ticket relations setup.
614
-            foreach ((array) $orig_tickets as $orig_ticket) {
615
-                // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
616
-                if (! $orig_ticket instanceof EE_Ticket) {
617
-                    continue;
618
-                }
619
-                // is this ticket archived?  If it is then let's skip
620
-                if ($orig_ticket->get('TKT_deleted')) {
621
-                    continue;
622
-                }
623
-                // does this original ticket already exist in the clone_tickets cache?
624
-                //  If so we'll just use the new ticket from it.
625
-                if (isset($cloned_tickets[ $orig_ticket->ID() ])) {
626
-                    $new_ticket = $cloned_tickets[ $orig_ticket->ID() ];
627
-                } else {
628
-                    $new_ticket = clone $orig_ticket;
629
-                    // get relations on the $orig_ticket that we need to setup.
630
-                    $orig_prices = $orig_ticket->prices();
631
-                    $new_ticket->set('TKT_ID', 0);
632
-                    $new_ticket->set('TKT_sold', 0);
633
-                    $new_ticket->set('TKT_reserved', 0);
634
-                    $new_ticket->save(); // make sure new ticket has ID.
635
-                    // price relations on new ticket need to be setup.
636
-                    foreach ($orig_prices as $orig_price) {
637
-                        $new_price = clone $orig_price;
638
-                        $new_price->set('PRC_ID', 0);
639
-                        $new_price->save();
640
-                        $new_ticket->_add_relation_to($new_price, 'Price');
641
-                        $new_ticket->save();
642
-                    }
643
-
644
-                    do_action(
645
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
646
-                        $orig_ticket,
647
-                        $new_ticket,
648
-                        $orig_prices,
649
-                        $orig_event,
650
-                        $orig_dtt,
651
-                        $new_dtt
652
-                    );
653
-                }
654
-                // k now we can add the new ticket as a relation to the new datetime
655
-                // and make sure its added to our cached $cloned_tickets array
656
-                // for use with later datetimes that have the same ticket.
657
-                $new_dtt->_add_relation_to($new_ticket, 'Ticket');
658
-                $new_dtt->save();
659
-                $cloned_tickets[ $orig_ticket->ID() ] = $new_ticket;
660
-            }
661
-        }
662
-        // clone taxonomy information
663
-        $taxonomies_to_clone_with = apply_filters(
664
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
665
-            ['espresso_event_categories', 'espresso_event_type', 'post_tag']
666
-        );
667
-        // get terms for original event (notice)
668
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
669
-        // loop through terms and add them to new event.
670
-        foreach ($orig_terms as $term) {
671
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
672
-        }
673
-
674
-        // duplicate other core WP_Post items for this event.
675
-        // post thumbnail (feature image).
676
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
677
-        if ($feature_image_id) {
678
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
679
-        }
680
-
681
-        // duplicate page_template setting
682
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
683
-        if ($page_template) {
684
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
685
-        }
686
-
687
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
688
-        // now let's redirect to the edit page for this duplicated event if we have a new event id.
689
-        if ($new_event->ID()) {
690
-            $redirect_args = [
691
-                'post'   => $new_event->ID(),
692
-                'action' => 'edit',
693
-            ];
694
-            EE_Error::add_success(
695
-                esc_html__(
696
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
697
-                    'event_espresso'
698
-                )
699
-            );
700
-        } else {
701
-            $redirect_args = [
702
-                'action' => 'default',
703
-            ];
704
-            EE_Error::add_error(
705
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
706
-                __FILE__,
707
-                __FUNCTION__,
708
-                __LINE__
709
-            );
710
-        }
711
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
712
-    }
713
-
714
-
715
-    /**
716
-     * Generates output for the import page.
717
-     *
718
-     * @throws EE_Error
719
-     */
720
-    protected function _import_page()
721
-    {
722
-        $title                                      = esc_html__('Import', 'event_espresso');
723
-        $intro                                      = esc_html__(
724
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
725
-            'event_espresso'
726
-        );
727
-
728
-        $form_url = EVENTS_ADMIN_URL;
729
-        $action   = 'import_events';
730
-        $type     = 'csv';
731
-
732
-        $this->_template_args['form'] = EE_Import::instance()->upload_form(
733
-            $title,
734
-            $intro,
735
-            $form_url,
736
-            $action,
737
-            $type
738
-        );
739
-
740
-        $this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
741
-            ['action' => 'sample_export_file'],
742
-            $this->_admin_base_url
743
-        );
744
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
745
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
746
-            $this->_template_args,
747
-            true
748
-        );
749
-        $this->display_admin_page_with_sidebar();
750
-    }
751
-
752
-
753
-    /**
754
-     * _import_events
755
-     * This handles displaying the screen and running imports for importing events.
756
-     *
757
-     * @return void
758
-     * @throws EE_Error
759
-     */
760
-    protected function _import_events()
761
-    {
762
-        require_once(EE_CLASSES . 'EE_Import.class.php');
763
-        $success = EE_Import::instance()->import();
764
-        $this->_redirect_after_action(
765
-            $success,
766
-            esc_html__('Import File', 'event_espresso'),
767
-            'ran',
768
-            ['action' => 'import_page'],
769
-            true
770
-        );
771
-    }
772
-
773
-
774
-    /**
775
-     * _events_export
776
-     * Will export all (or just the given event) to a Excel compatible file.
777
-     *
778
-     * @access protected
779
-     * @return void
780
-     */
781
-    protected function _events_export()
782
-    {
783
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
784
-        $EVT_ID = $this->request->getRequestParam('EVT_IDs', $EVT_ID, 'int');
785
-        $this->request->mergeRequestParams(
786
-            [
787
-                'export' => 'report',
788
-                'action' => 'all_event_data',
789
-                'EVT_ID' => $EVT_ID,
790
-            ]
791
-        );
792
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
793
-            require_once(EE_CLASSES . 'EE_Export.class.php');
794
-            $EE_Export = EE_Export::instance($this->request->requestParams());
795
-            $EE_Export->export();
796
-        }
797
-    }
798
-
799
-
800
-    /**
801
-     * handle category exports()
802
-     *
803
-     * @return void
804
-     */
805
-    protected function _categories_export()
806
-    {
807
-        $EVT_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
808
-        $this->request->mergeRequestParams(
809
-            [
810
-                'export' => 'report',
811
-                'action' => 'categories',
812
-                'EVT_ID' => $EVT_ID,
813
-            ]
814
-        );
815
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
816
-            require_once(EE_CLASSES . 'EE_Export.class.php');
817
-            $EE_Export = EE_Export::instance($this->request->requestParams());
818
-            $EE_Export->export();
819
-        }
820
-    }
821
-
822
-
823
-    /**
824
-     * Creates a sample CSV file for importing
825
-     */
826
-    protected function _sample_export_file()
827
-    {
828
-        $EE_Export = EE_Export::instance();
829
-        if ($EE_Export instanceof EE_Export) {
830
-            $EE_Export->export();
831
-        }
832
-    }
833
-
834
-
835
-    /*************        Template Settings        *************/
836
-    /**
837
-     * Generates template settings page output
838
-     *
839
-     * @throws DomainException
840
-     * @throws EE_Error
841
-     * @throws InvalidArgumentException
842
-     * @throws InvalidDataTypeException
843
-     * @throws InvalidInterfaceException
844
-     */
845
-    protected function _template_settings()
846
-    {
847
-        $this->_template_args['values'] = $this->_yes_no_values;
848
-        /**
849
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
850
-         * from General_Settings_Admin_Page to here.
851
-         */
852
-        $this->_template_args = apply_filters(
853
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
854
-            $this->_template_args
855
-        );
856
-        $this->_set_add_edit_form_tags('update_template_settings');
857
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
858
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
859
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
860
-            $this->_template_args,
861
-            true
862
-        );
863
-        $this->display_admin_page_with_sidebar();
864
-    }
865
-
866
-
867
-    /**
868
-     * Handler for updating template settings.
869
-     *
870
-     * @throws EE_Error
871
-     */
872
-    protected function _update_template_settings()
873
-    {
874
-        /**
875
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
876
-         * from General_Settings_Admin_Page to here.
877
-         */
878
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
879
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
880
-            EE_Registry::instance()->CFG->template_settings,
881
-            $this->request->requestParams()
882
-        );
883
-        // update custom post type slugs and detect if we need to flush rewrite rules
884
-        $old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
885
-
886
-        $event_cpt_slug = $this->request->getRequestParam('event_cpt_slug');
887
-
888
-        EE_Registry::instance()->CFG->core->event_cpt_slug = $event_cpt_slug
889
-            ? EEH_URL::slugify($event_cpt_slug, 'events')
890
-            : EE_Registry::instance()->CFG->core->event_cpt_slug;
891
-
892
-        $what    = esc_html__('Template Settings', 'event_espresso');
893
-        $success = $this->_update_espresso_configuration(
894
-            $what,
895
-            EE_Registry::instance()->CFG->template_settings,
896
-            __FILE__,
897
-            __FUNCTION__,
898
-            __LINE__
899
-        );
900
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
901
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
902
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
903
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
904
-            );
905
-            $rewrite_rules->flush();
906
-        }
907
-        $this->_redirect_after_action($success, $what, 'updated', ['action' => 'template_settings']);
908
-    }
909
-
910
-
911
-    /**
912
-     * _premium_event_editor_meta_boxes
913
-     * add all metaboxes related to the event_editor
914
-     *
915
-     * @access protected
916
-     * @return void
917
-     * @throws EE_Error
918
-     * @throws ReflectionException
919
-     */
920
-    protected function _premium_event_editor_meta_boxes()
921
-    {
922
-        $this->verify_cpt_object();
923
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
924
-        if (
925
-            ! $this->admin_config->useAdvancedEditor()
926
-            || ! $this->feature->allowed('use_reg_options_meta_box')
927
-        ) {
928
-            $this->addMetaBox(
929
-                'espresso_event_editor_event_options',
930
-                esc_html__('Event Registration Options', 'event_espresso'),
931
-                [$this, 'registration_options_meta_box'],
932
-                $this->page_slug,
933
-                'side',
934
-                'core'
935
-            );
936
-        }
937
-    }
938
-
939
-
940
-    /**
941
-     * override caf metabox
942
-     *
943
-     * @return void
944
-     * @throws EE_Error
945
-     * @throws ReflectionException
946
-     */
947
-    public function registration_options_meta_box()
948
-    {
949
-        $yes_no_values = [
950
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
951
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
952
-        ];
953
-
954
-        $default_reg_status_values = EEM_Registration::reg_status_array(
955
-            [
956
-                EEM_Registration::status_id_cancelled,
957
-                EEM_Registration::status_id_declined,
958
-                EEM_Registration::status_id_incomplete,
959
-                EEM_Registration::status_id_wait_list,
960
-            ],
961
-            true
962
-        );
963
-
964
-        $template_args['active_status']    = $this->_cpt_model_obj->pretty_active_status(false);
965
-        $template_args['_event']           = $this->_cpt_model_obj;
966
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
967
-
968
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
969
-            'default_reg_status',
970
-            $default_reg_status_values,
971
-            $this->_cpt_model_obj->default_registration_status()
972
-        );
973
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
974
-            'display_desc',
975
-            $yes_no_values,
976
-            $this->_cpt_model_obj->display_description()
977
-        );
978
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
979
-            'display_ticket_selector',
980
-            $yes_no_values,
981
-            $this->_cpt_model_obj->display_ticket_selector(),
982
-            '',
983
-            '',
984
-            false
985
-        );
986
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
987
-            'EVT_default_registration_status',
988
-            $default_reg_status_values,
989
-            $this->_cpt_model_obj->default_registration_status()
990
-        );
991
-        $template_args['additional_registration_options'] = apply_filters(
992
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
993
-            '',
994
-            $template_args,
995
-            $yes_no_values,
996
-            $default_reg_status_values
997
-        );
998
-        EEH_Template::display_template(
999
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
1000
-            $template_args
1001
-        );
1002
-    }
1003
-
1004
-
1005
-
1006
-    /**
1007
-     * wp_list_table_mods for caf
1008
-     * ============================
1009
-     */
1010
-    /**
1011
-     * hook into list table filters and provide filters for caffeinated list table
1012
-     *
1013
-     * @param array $old_filters    any existing filters present
1014
-     * @param array $list_table_obj the list table object
1015
-     * @return array                  new filters
1016
-     * @throws EE_Error
1017
-     * @throws ReflectionException
1018
-     */
1019
-    public function list_table_filters($old_filters, $list_table_obj)
1020
-    {
1021
-        $filters = [];
1022
-        // first month/year filters
1023
-        $filters[] = $this->espresso_event_months_dropdown();
1024
-        $status    = $this->request->getRequestParam('status');
1025
-        // active status dropdown
1026
-        if ($status !== 'draft') {
1027
-            $filters[] = $this->active_status_dropdown($this->request->getRequestParam('active_status'));
1028
-            $filters[] = $this->venuesDropdown($this->request->getRequestParam('venue'));
1029
-        }
1030
-        // category filter
1031
-        $filters[] = $this->category_dropdown();
1032
-        return array_merge($old_filters, $filters);
1033
-    }
1034
-
1035
-
1036
-    /**
1037
-     * espresso_event_months_dropdown
1038
-     *
1039
-     * @access public
1040
-     * @return string                dropdown listing month/year selections for events.
1041
-     * @throws EE_Error
1042
-     */
1043
-    public function espresso_event_months_dropdown()
1044
-    {
1045
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
1046
-        // Note we need to include any other filters that are set!
1047
-        return EEH_Form_Fields::generate_event_months_dropdown(
1048
-            $this->request->getRequestParam('month_range'),
1049
-            $this->request->getRequestParam('status'),
1050
-            $this->request->getRequestParam('EVT_CAT', 0, 'int'),
1051
-            $this->request->getRequestParam('active_status')
1052
-        );
1053
-    }
1054
-
1055
-
1056
-    /**
1057
-     * returns a list of "active" statuses on the event
1058
-     *
1059
-     * @param string $current_value whatever the current active status is
1060
-     * @return string
1061
-     */
1062
-    public function active_status_dropdown($current_value = '')
1063
-    {
1064
-        $select_name = 'active_status';
1065
-        $values      = [
1066
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1067
-            'active'   => esc_html__('Active', 'event_espresso'),
1068
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1069
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1070
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1071
-        ];
1072
-
1073
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value);
1074
-    }
1075
-
1076
-
1077
-    /**
1078
-     * returns a list of "venues"
1079
-     *
1080
-     * @param string $current_value whatever the current active status is
1081
-     * @return string
1082
-     * @throws EE_Error
1083
-     * @throws ReflectionException
1084
-     */
1085
-    protected function venuesDropdown($current_value = '')
1086
-    {
1087
-        $values = ['' => esc_html__('All Venues', 'event_espresso')];
1088
-        // populate the list of venues.
1089
-        $venues = EEM_Venue::instance()->get_all(['order_by' => ['VNU_name' => 'ASC']]);
1090
-
1091
-        foreach ($venues as $venue) {
1092
-            $values[ $venue->ID() ] = $venue->name();
1093
-        }
1094
-
1095
-        return EEH_Form_Fields::select_input('venue', $values, $current_value);
1096
-    }
1097
-
1098
-
1099
-    /**
1100
-     * output a dropdown of the categories for the category filter on the event admin list table
1101
-     *
1102
-     * @access  public
1103
-     * @return string html
1104
-     * @throws EE_Error
1105
-     * @throws ReflectionException
1106
-     */
1107
-    public function category_dropdown()
1108
-    {
1109
-        return EEH_Form_Fields::generate_event_category_dropdown(
1110
-            $this->request->getRequestParam('EVT_CAT', -1, 'int')
1111
-        );
1112
-    }
1113
-
1114
-
1115
-    /**
1116
-     * get total number of events today
1117
-     *
1118
-     * @access public
1119
-     * @return int
1120
-     * @throws EE_Error
1121
-     * @throws InvalidArgumentException
1122
-     * @throws InvalidDataTypeException
1123
-     * @throws InvalidInterfaceException
1124
-     */
1125
-    public function total_events_today()
1126
-    {
1127
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1128
-            'DTT_EVT_start',
1129
-            date('Y-m-d') . ' 00:00:00',
1130
-            'Y-m-d H:i:s',
1131
-            'UTC'
1132
-        );
1133
-        $end   = EEM_Datetime::instance()->convert_datetime_for_query(
1134
-            'DTT_EVT_start',
1135
-            date('Y-m-d') . ' 23:59:59',
1136
-            'Y-m-d H:i:s',
1137
-            'UTC'
1138
-        );
1139
-        $where = [
1140
-            'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1141
-        ];
1142
-        return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1143
-    }
1144
-
1145
-
1146
-    /**
1147
-     * get total number of events this month
1148
-     *
1149
-     * @access public
1150
-     * @return int
1151
-     * @throws EE_Error
1152
-     * @throws InvalidArgumentException
1153
-     * @throws InvalidDataTypeException
1154
-     * @throws InvalidInterfaceException
1155
-     */
1156
-    public function total_events_this_month()
1157
-    {
1158
-        // Dates
1159
-        $this_year_r     = date('Y');
1160
-        $this_month_r    = date('m');
1161
-        $days_this_month = date('t');
1162
-        $start           = EEM_Datetime::instance()->convert_datetime_for_query(
1163
-            'DTT_EVT_start',
1164
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1165
-            'Y-m-d H:i:s',
1166
-            'UTC'
1167
-        );
1168
-        $end             = EEM_Datetime::instance()->convert_datetime_for_query(
1169
-            'DTT_EVT_start',
1170
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1171
-            'Y-m-d H:i:s',
1172
-            'UTC'
1173
-        );
1174
-        $where           = [
1175
-            'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1176
-        ];
1177
-        return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1178
-    }
1179
-
1180
-
1181
-    /** DEFAULT TICKETS STUFF **/
1182
-
1183
-    /**
1184
-     * Output default tickets list table view.
1185
-     *
1186
-     * @throws EE_Error
1187
-     */
1188
-    public function _tickets_overview_list_table()
1189
-    {
1190
-        if (
1191
-            $this->admin_config->useAdvancedEditor()
1192
-            && $this->feature->allowed('use_default_ticket_manager')
1193
-        ) {
1194
-            // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1195
-            $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1196
-                EVENTS_CAF_TEMPLATE_PATH . 'default_tickets_moved_notice.template.php',
1197
-                [],
1198
-                true
1199
-            );
1200
-            $this->display_admin_page_with_no_sidebar();
1201
-        } else {
1202
-            $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1203
-            $this->display_admin_list_table_page_with_no_sidebar();
1204
-        }
1205
-    }
1206
-
1207
-
1208
-    /**
1209
-     * @param int  $per_page
1210
-     * @param bool $count
1211
-     * @param bool $trashed
1212
-     * @return EE_Soft_Delete_Base_Class[]|int
1213
-     * @throws EE_Error
1214
-     */
1215
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1216
-    {
1217
-        $orderby = $this->request->getRequestParam('orderby', 'TKT_name');
1218
-        $order   = $this->request->getRequestParam('order', 'ASC');
1219
-        switch ($orderby) {
1220
-            case 'TKT_name':
1221
-                $orderby = ['TKT_name' => $order];
1222
-                break;
1223
-            case 'TKT_price':
1224
-                $orderby = ['TKT_price' => $order];
1225
-                break;
1226
-            case 'TKT_uses':
1227
-                $orderby = ['TKT_uses' => $order];
1228
-                break;
1229
-            case 'TKT_min':
1230
-                $orderby = ['TKT_min' => $order];
1231
-                break;
1232
-            case 'TKT_max':
1233
-                $orderby = ['TKT_max' => $order];
1234
-                break;
1235
-            case 'TKT_qty':
1236
-                $orderby = ['TKT_qty' => $order];
1237
-                break;
1238
-        }
1239
-
1240
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
1241
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1242
-        $offset       = ($current_page - 1) * $per_page;
1243
-
1244
-        $where = [
1245
-            'TKT_is_default' => 1,
1246
-            'TKT_deleted'    => $trashed,
1247
-        ];
1248
-
1249
-        $search_term = $this->request->getRequestParam('s');
1250
-        if ($search_term) {
1251
-            $search_term = '%' . $search_term . '%';
1252
-            $where['OR'] = [
1253
-                'TKT_name'        => ['LIKE', $search_term],
1254
-                'TKT_description' => ['LIKE', $search_term],
1255
-            ];
1256
-        }
1257
-
1258
-        return $count
1259
-            ? EEM_Ticket::instance()->count_deleted_and_undeleted([$where])
1260
-            : EEM_Ticket::instance()->get_all_deleted_and_undeleted(
1261
-                [
1262
-                    $where,
1263
-                    'order_by' => $orderby,
1264
-                    'limit'    => [$offset, $per_page],
1265
-                    'group_by' => 'TKT_ID',
1266
-                ]
1267
-            );
1268
-    }
1269
-
1270
-
1271
-    /**
1272
-     * @param bool $trash
1273
-     * @throws EE_Error
1274
-     * @throws InvalidArgumentException
1275
-     * @throws InvalidDataTypeException
1276
-     * @throws InvalidInterfaceException
1277
-     */
1278
-    protected function _trash_or_restore_ticket($trash = false)
1279
-    {
1280
-        $success = 1;
1281
-        $TKT     = EEM_Ticket::instance();
1282
-        // checkboxes?
1283
-        $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1284
-        if (! empty($checkboxes)) {
1285
-            // if array has more than one element then success message should be plural
1286
-            $success = count($checkboxes) > 1 ? 2 : 1;
1287
-            // cycle thru the boxes
1288
-            while (list($TKT_ID, $value) = each($checkboxes)) {
1289
-                if ($trash) {
1290
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1291
-                        $success = 0;
1292
-                    }
1293
-                } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1294
-                    $success = 0;
1295
-                }
1296
-            }
1297
-        } else {
1298
-            // grab single id and trash
1299
-            $TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1300
-            if ($trash) {
1301
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1302
-                    $success = 0;
1303
-                }
1304
-            } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1305
-                $success = 0;
1306
-            }
1307
-        }
1308
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1309
-        $query_args  = [
1310
-            'action' => 'ticket_list_table',
1311
-            'status' => $trash ? '' : 'trashed',
1312
-        ];
1313
-        $this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1314
-    }
1315
-
1316
-
1317
-    /**
1318
-     * Handles trashing default ticket.
1319
-     *
1320
-     * @throws EE_Error
1321
-     * @throws ReflectionException
1322
-     */
1323
-    protected function _delete_ticket()
1324
-    {
1325
-        $success = 1;
1326
-        // checkboxes?
1327
-        $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1328
-        if (! empty($checkboxes)) {
1329
-            // if array has more than one element then success message should be plural
1330
-            $success = count($checkboxes) > 1 ? 2 : 1;
1331
-            // cycle thru the boxes
1332
-            while (list($TKT_ID, $value) = each($checkboxes)) {
1333
-                // delete
1334
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1335
-                    $success = 0;
1336
-                }
1337
-            }
1338
-        } else {
1339
-            // grab single id and trash
1340
-            $TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1341
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1342
-                $success = 0;
1343
-            }
1344
-        }
1345
-        $action_desc = 'deleted';
1346
-        $query_args  = [
1347
-            'action' => 'ticket_list_table',
1348
-            'status' => 'trashed',
1349
-        ];
1350
-        // fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1351
-        if (
1352
-            EEM_Ticket::instance()->count_deleted_and_undeleted(
1353
-                [['TKT_is_default' => 1]],
1354
-                'TKT_ID',
1355
-                true
1356
-            )
1357
-        ) {
1358
-            $query_args = [];
1359
-        }
1360
-        $this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1361
-    }
1362
-
1363
-
1364
-    /**
1365
-     * @param int $TKT_ID
1366
-     * @return bool|int
1367
-     * @throws EE_Error
1368
-     * @throws ReflectionException
1369
-     */
1370
-    protected function _delete_the_ticket($TKT_ID)
1371
-    {
1372
-        $ticket = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1373
-        if (! $ticket instanceof EE_Ticket) {
1374
-            return false;
1375
-        }
1376
-        $ticket->_remove_relations('Datetime');
1377
-        // delete all related prices first
1378
-        $ticket->delete_related_permanently('Price');
1379
-        return $ticket->delete_permanently();
1380
-    }
454
+		}
455
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
456
+			EE_Registry::instance()->load_helper('MSG_Template');
457
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
458
+				'see_notifications_for',
459
+				null,
460
+				['EVT_ID' => $event->ID()]
461
+			);
462
+		}
463
+		return $action_links;
464
+	}
465
+
466
+
467
+	/**
468
+	 * @param $items
469
+	 * @return mixed
470
+	 */
471
+	public function additional_legend_items($items)
472
+	{
473
+		if (
474
+			EE_Registry::instance()->CAP->current_user_can(
475
+				'ee_read_registrations',
476
+				'espresso_registrations_reports'
477
+			)
478
+		) {
479
+			$items['reports'] = [
480
+				'class' => 'dashicons dashicons-chart-bar',
481
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
482
+			];
483
+		}
484
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
485
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
486
+			// $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
487
+			// (can only use numeric offsets when treating strings as arrays)
488
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
489
+				$items['view_related_messages'] = [
490
+					'class' => $related_for_icon['css_class'],
491
+					'desc'  => $related_for_icon['label'],
492
+				];
493
+			}
494
+		}
495
+		return $items;
496
+	}
497
+
498
+
499
+	/**
500
+	 * This is the callback method for the duplicate event route
501
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
502
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
503
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
504
+	 * After duplication the redirect is to the new event edit page.
505
+	 *
506
+	 * @return void
507
+	 * @throws EE_Error If EE_Event is not available with given ID
508
+	 * @throws ReflectionException
509
+	 * @access protected
510
+	 */
511
+	protected function _duplicate_event()
512
+	{
513
+		// first make sure the ID for the event is in the request.
514
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
515
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
516
+		if (! $EVT_ID) {
517
+			EE_Error::add_error(
518
+				esc_html__(
519
+					'In order to duplicate an event an Event ID is required.  None was given.',
520
+					'event_espresso'
521
+				),
522
+				__FILE__,
523
+				__FUNCTION__,
524
+				__LINE__
525
+			);
526
+			$this->_redirect_after_action(false, '', '', [], true);
527
+			return;
528
+		}
529
+		// k we've got EVT_ID so let's use that to get the event we'll duplicate
530
+		$orig_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
531
+		if (! $orig_event instanceof EE_Event) {
532
+			throw new EE_Error(
533
+				sprintf(
534
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
535
+					$EVT_ID
536
+				)
537
+			);
538
+		}
539
+		// k now let's clone the $orig_event before getting relations
540
+		$new_event = clone $orig_event;
541
+		// original datetimes
542
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
543
+		// other original relations
544
+		$orig_ven = $orig_event->get_many_related('Venue');
545
+		// reset the ID and modify other details to make it clear this is a dupe
546
+		$new_event->set('EVT_ID', 0);
547
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
548
+		$new_event->set('EVT_name', $new_name);
549
+		$new_event->set(
550
+			'EVT_slug',
551
+			wp_unique_post_slug(
552
+				sanitize_title($orig_event->name()),
553
+				0,
554
+				'publish',
555
+				'espresso_events',
556
+				0
557
+			)
558
+		);
559
+		$new_event->set('status', 'draft');
560
+		// duplicate discussion settings
561
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
562
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
563
+		// save the new event
564
+		$new_event->save();
565
+		// venues
566
+		foreach ($orig_ven as $ven) {
567
+			$new_event->_add_relation_to($ven, 'Venue');
568
+		}
569
+		$new_event->save();
570
+		// now we need to get the question group relations and handle that
571
+		// first primary question groups
572
+		$orig_primary_qgs = $orig_event->get_many_related(
573
+			'Question_Group',
574
+			[['Event_Question_Group.EQG_primary' => true]]
575
+		);
576
+		if (! empty($orig_primary_qgs)) {
577
+			foreach ($orig_primary_qgs as $obj) {
578
+				if ($obj instanceof EE_Question_Group) {
579
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
580
+				}
581
+			}
582
+		}
583
+		// next additional attendee question groups
584
+		$orig_additional_qgs = $orig_event->get_many_related(
585
+			'Question_Group',
586
+			[['Event_Question_Group.EQG_additional' => true]]
587
+		);
588
+		if (! empty($orig_additional_qgs)) {
589
+			foreach ($orig_additional_qgs as $obj) {
590
+				if ($obj instanceof EE_Question_Group) {
591
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
592
+				}
593
+			}
594
+		}
595
+
596
+		$new_event->save();
597
+
598
+		// k now that we have the new event saved we can loop through the datetimes and start adding relations.
599
+		$cloned_tickets = [];
600
+		foreach ($orig_datetimes as $orig_dtt) {
601
+			if (! $orig_dtt instanceof EE_Datetime) {
602
+				continue;
603
+			}
604
+			$new_dtt      = clone $orig_dtt;
605
+			$orig_tickets = $orig_dtt->tickets();
606
+			// save new dtt then add to event
607
+			$new_dtt->set('DTT_ID', 0);
608
+			$new_dtt->set('DTT_sold', 0);
609
+			$new_dtt->set_reserved(0);
610
+			$new_dtt->save();
611
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
612
+			$new_event->save();
613
+			// now let's get the ticket relations setup.
614
+			foreach ((array) $orig_tickets as $orig_ticket) {
615
+				// it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
616
+				if (! $orig_ticket instanceof EE_Ticket) {
617
+					continue;
618
+				}
619
+				// is this ticket archived?  If it is then let's skip
620
+				if ($orig_ticket->get('TKT_deleted')) {
621
+					continue;
622
+				}
623
+				// does this original ticket already exist in the clone_tickets cache?
624
+				//  If so we'll just use the new ticket from it.
625
+				if (isset($cloned_tickets[ $orig_ticket->ID() ])) {
626
+					$new_ticket = $cloned_tickets[ $orig_ticket->ID() ];
627
+				} else {
628
+					$new_ticket = clone $orig_ticket;
629
+					// get relations on the $orig_ticket that we need to setup.
630
+					$orig_prices = $orig_ticket->prices();
631
+					$new_ticket->set('TKT_ID', 0);
632
+					$new_ticket->set('TKT_sold', 0);
633
+					$new_ticket->set('TKT_reserved', 0);
634
+					$new_ticket->save(); // make sure new ticket has ID.
635
+					// price relations on new ticket need to be setup.
636
+					foreach ($orig_prices as $orig_price) {
637
+						$new_price = clone $orig_price;
638
+						$new_price->set('PRC_ID', 0);
639
+						$new_price->save();
640
+						$new_ticket->_add_relation_to($new_price, 'Price');
641
+						$new_ticket->save();
642
+					}
643
+
644
+					do_action(
645
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
646
+						$orig_ticket,
647
+						$new_ticket,
648
+						$orig_prices,
649
+						$orig_event,
650
+						$orig_dtt,
651
+						$new_dtt
652
+					);
653
+				}
654
+				// k now we can add the new ticket as a relation to the new datetime
655
+				// and make sure its added to our cached $cloned_tickets array
656
+				// for use with later datetimes that have the same ticket.
657
+				$new_dtt->_add_relation_to($new_ticket, 'Ticket');
658
+				$new_dtt->save();
659
+				$cloned_tickets[ $orig_ticket->ID() ] = $new_ticket;
660
+			}
661
+		}
662
+		// clone taxonomy information
663
+		$taxonomies_to_clone_with = apply_filters(
664
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
665
+			['espresso_event_categories', 'espresso_event_type', 'post_tag']
666
+		);
667
+		// get terms for original event (notice)
668
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
669
+		// loop through terms and add them to new event.
670
+		foreach ($orig_terms as $term) {
671
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
672
+		}
673
+
674
+		// duplicate other core WP_Post items for this event.
675
+		// post thumbnail (feature image).
676
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
677
+		if ($feature_image_id) {
678
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
679
+		}
680
+
681
+		// duplicate page_template setting
682
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
683
+		if ($page_template) {
684
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
685
+		}
686
+
687
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
688
+		// now let's redirect to the edit page for this duplicated event if we have a new event id.
689
+		if ($new_event->ID()) {
690
+			$redirect_args = [
691
+				'post'   => $new_event->ID(),
692
+				'action' => 'edit',
693
+			];
694
+			EE_Error::add_success(
695
+				esc_html__(
696
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
697
+					'event_espresso'
698
+				)
699
+			);
700
+		} else {
701
+			$redirect_args = [
702
+				'action' => 'default',
703
+			];
704
+			EE_Error::add_error(
705
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
706
+				__FILE__,
707
+				__FUNCTION__,
708
+				__LINE__
709
+			);
710
+		}
711
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
712
+	}
713
+
714
+
715
+	/**
716
+	 * Generates output for the import page.
717
+	 *
718
+	 * @throws EE_Error
719
+	 */
720
+	protected function _import_page()
721
+	{
722
+		$title                                      = esc_html__('Import', 'event_espresso');
723
+		$intro                                      = esc_html__(
724
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
725
+			'event_espresso'
726
+		);
727
+
728
+		$form_url = EVENTS_ADMIN_URL;
729
+		$action   = 'import_events';
730
+		$type     = 'csv';
731
+
732
+		$this->_template_args['form'] = EE_Import::instance()->upload_form(
733
+			$title,
734
+			$intro,
735
+			$form_url,
736
+			$action,
737
+			$type
738
+		);
739
+
740
+		$this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
741
+			['action' => 'sample_export_file'],
742
+			$this->_admin_base_url
743
+		);
744
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
745
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
746
+			$this->_template_args,
747
+			true
748
+		);
749
+		$this->display_admin_page_with_sidebar();
750
+	}
751
+
752
+
753
+	/**
754
+	 * _import_events
755
+	 * This handles displaying the screen and running imports for importing events.
756
+	 *
757
+	 * @return void
758
+	 * @throws EE_Error
759
+	 */
760
+	protected function _import_events()
761
+	{
762
+		require_once(EE_CLASSES . 'EE_Import.class.php');
763
+		$success = EE_Import::instance()->import();
764
+		$this->_redirect_after_action(
765
+			$success,
766
+			esc_html__('Import File', 'event_espresso'),
767
+			'ran',
768
+			['action' => 'import_page'],
769
+			true
770
+		);
771
+	}
772
+
773
+
774
+	/**
775
+	 * _events_export
776
+	 * Will export all (or just the given event) to a Excel compatible file.
777
+	 *
778
+	 * @access protected
779
+	 * @return void
780
+	 */
781
+	protected function _events_export()
782
+	{
783
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
784
+		$EVT_ID = $this->request->getRequestParam('EVT_IDs', $EVT_ID, 'int');
785
+		$this->request->mergeRequestParams(
786
+			[
787
+				'export' => 'report',
788
+				'action' => 'all_event_data',
789
+				'EVT_ID' => $EVT_ID,
790
+			]
791
+		);
792
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
793
+			require_once(EE_CLASSES . 'EE_Export.class.php');
794
+			$EE_Export = EE_Export::instance($this->request->requestParams());
795
+			$EE_Export->export();
796
+		}
797
+	}
798
+
799
+
800
+	/**
801
+	 * handle category exports()
802
+	 *
803
+	 * @return void
804
+	 */
805
+	protected function _categories_export()
806
+	{
807
+		$EVT_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
808
+		$this->request->mergeRequestParams(
809
+			[
810
+				'export' => 'report',
811
+				'action' => 'categories',
812
+				'EVT_ID' => $EVT_ID,
813
+			]
814
+		);
815
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
816
+			require_once(EE_CLASSES . 'EE_Export.class.php');
817
+			$EE_Export = EE_Export::instance($this->request->requestParams());
818
+			$EE_Export->export();
819
+		}
820
+	}
821
+
822
+
823
+	/**
824
+	 * Creates a sample CSV file for importing
825
+	 */
826
+	protected function _sample_export_file()
827
+	{
828
+		$EE_Export = EE_Export::instance();
829
+		if ($EE_Export instanceof EE_Export) {
830
+			$EE_Export->export();
831
+		}
832
+	}
833
+
834
+
835
+	/*************        Template Settings        *************/
836
+	/**
837
+	 * Generates template settings page output
838
+	 *
839
+	 * @throws DomainException
840
+	 * @throws EE_Error
841
+	 * @throws InvalidArgumentException
842
+	 * @throws InvalidDataTypeException
843
+	 * @throws InvalidInterfaceException
844
+	 */
845
+	protected function _template_settings()
846
+	{
847
+		$this->_template_args['values'] = $this->_yes_no_values;
848
+		/**
849
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
850
+		 * from General_Settings_Admin_Page to here.
851
+		 */
852
+		$this->_template_args = apply_filters(
853
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
854
+			$this->_template_args
855
+		);
856
+		$this->_set_add_edit_form_tags('update_template_settings');
857
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
858
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
859
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
860
+			$this->_template_args,
861
+			true
862
+		);
863
+		$this->display_admin_page_with_sidebar();
864
+	}
865
+
866
+
867
+	/**
868
+	 * Handler for updating template settings.
869
+	 *
870
+	 * @throws EE_Error
871
+	 */
872
+	protected function _update_template_settings()
873
+	{
874
+		/**
875
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
876
+		 * from General_Settings_Admin_Page to here.
877
+		 */
878
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
879
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
880
+			EE_Registry::instance()->CFG->template_settings,
881
+			$this->request->requestParams()
882
+		);
883
+		// update custom post type slugs and detect if we need to flush rewrite rules
884
+		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
885
+
886
+		$event_cpt_slug = $this->request->getRequestParam('event_cpt_slug');
887
+
888
+		EE_Registry::instance()->CFG->core->event_cpt_slug = $event_cpt_slug
889
+			? EEH_URL::slugify($event_cpt_slug, 'events')
890
+			: EE_Registry::instance()->CFG->core->event_cpt_slug;
891
+
892
+		$what    = esc_html__('Template Settings', 'event_espresso');
893
+		$success = $this->_update_espresso_configuration(
894
+			$what,
895
+			EE_Registry::instance()->CFG->template_settings,
896
+			__FILE__,
897
+			__FUNCTION__,
898
+			__LINE__
899
+		);
900
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
901
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
902
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
903
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
904
+			);
905
+			$rewrite_rules->flush();
906
+		}
907
+		$this->_redirect_after_action($success, $what, 'updated', ['action' => 'template_settings']);
908
+	}
909
+
910
+
911
+	/**
912
+	 * _premium_event_editor_meta_boxes
913
+	 * add all metaboxes related to the event_editor
914
+	 *
915
+	 * @access protected
916
+	 * @return void
917
+	 * @throws EE_Error
918
+	 * @throws ReflectionException
919
+	 */
920
+	protected function _premium_event_editor_meta_boxes()
921
+	{
922
+		$this->verify_cpt_object();
923
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
924
+		if (
925
+			! $this->admin_config->useAdvancedEditor()
926
+			|| ! $this->feature->allowed('use_reg_options_meta_box')
927
+		) {
928
+			$this->addMetaBox(
929
+				'espresso_event_editor_event_options',
930
+				esc_html__('Event Registration Options', 'event_espresso'),
931
+				[$this, 'registration_options_meta_box'],
932
+				$this->page_slug,
933
+				'side',
934
+				'core'
935
+			);
936
+		}
937
+	}
938
+
939
+
940
+	/**
941
+	 * override caf metabox
942
+	 *
943
+	 * @return void
944
+	 * @throws EE_Error
945
+	 * @throws ReflectionException
946
+	 */
947
+	public function registration_options_meta_box()
948
+	{
949
+		$yes_no_values = [
950
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
951
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
952
+		];
953
+
954
+		$default_reg_status_values = EEM_Registration::reg_status_array(
955
+			[
956
+				EEM_Registration::status_id_cancelled,
957
+				EEM_Registration::status_id_declined,
958
+				EEM_Registration::status_id_incomplete,
959
+				EEM_Registration::status_id_wait_list,
960
+			],
961
+			true
962
+		);
963
+
964
+		$template_args['active_status']    = $this->_cpt_model_obj->pretty_active_status(false);
965
+		$template_args['_event']           = $this->_cpt_model_obj;
966
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
967
+
968
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
969
+			'default_reg_status',
970
+			$default_reg_status_values,
971
+			$this->_cpt_model_obj->default_registration_status()
972
+		);
973
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
974
+			'display_desc',
975
+			$yes_no_values,
976
+			$this->_cpt_model_obj->display_description()
977
+		);
978
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
979
+			'display_ticket_selector',
980
+			$yes_no_values,
981
+			$this->_cpt_model_obj->display_ticket_selector(),
982
+			'',
983
+			'',
984
+			false
985
+		);
986
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
987
+			'EVT_default_registration_status',
988
+			$default_reg_status_values,
989
+			$this->_cpt_model_obj->default_registration_status()
990
+		);
991
+		$template_args['additional_registration_options'] = apply_filters(
992
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
993
+			'',
994
+			$template_args,
995
+			$yes_no_values,
996
+			$default_reg_status_values
997
+		);
998
+		EEH_Template::display_template(
999
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
1000
+			$template_args
1001
+		);
1002
+	}
1003
+
1004
+
1005
+
1006
+	/**
1007
+	 * wp_list_table_mods for caf
1008
+	 * ============================
1009
+	 */
1010
+	/**
1011
+	 * hook into list table filters and provide filters for caffeinated list table
1012
+	 *
1013
+	 * @param array $old_filters    any existing filters present
1014
+	 * @param array $list_table_obj the list table object
1015
+	 * @return array                  new filters
1016
+	 * @throws EE_Error
1017
+	 * @throws ReflectionException
1018
+	 */
1019
+	public function list_table_filters($old_filters, $list_table_obj)
1020
+	{
1021
+		$filters = [];
1022
+		// first month/year filters
1023
+		$filters[] = $this->espresso_event_months_dropdown();
1024
+		$status    = $this->request->getRequestParam('status');
1025
+		// active status dropdown
1026
+		if ($status !== 'draft') {
1027
+			$filters[] = $this->active_status_dropdown($this->request->getRequestParam('active_status'));
1028
+			$filters[] = $this->venuesDropdown($this->request->getRequestParam('venue'));
1029
+		}
1030
+		// category filter
1031
+		$filters[] = $this->category_dropdown();
1032
+		return array_merge($old_filters, $filters);
1033
+	}
1034
+
1035
+
1036
+	/**
1037
+	 * espresso_event_months_dropdown
1038
+	 *
1039
+	 * @access public
1040
+	 * @return string                dropdown listing month/year selections for events.
1041
+	 * @throws EE_Error
1042
+	 */
1043
+	public function espresso_event_months_dropdown()
1044
+	{
1045
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
1046
+		// Note we need to include any other filters that are set!
1047
+		return EEH_Form_Fields::generate_event_months_dropdown(
1048
+			$this->request->getRequestParam('month_range'),
1049
+			$this->request->getRequestParam('status'),
1050
+			$this->request->getRequestParam('EVT_CAT', 0, 'int'),
1051
+			$this->request->getRequestParam('active_status')
1052
+		);
1053
+	}
1054
+
1055
+
1056
+	/**
1057
+	 * returns a list of "active" statuses on the event
1058
+	 *
1059
+	 * @param string $current_value whatever the current active status is
1060
+	 * @return string
1061
+	 */
1062
+	public function active_status_dropdown($current_value = '')
1063
+	{
1064
+		$select_name = 'active_status';
1065
+		$values      = [
1066
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1067
+			'active'   => esc_html__('Active', 'event_espresso'),
1068
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1069
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1070
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1071
+		];
1072
+
1073
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value);
1074
+	}
1075
+
1076
+
1077
+	/**
1078
+	 * returns a list of "venues"
1079
+	 *
1080
+	 * @param string $current_value whatever the current active status is
1081
+	 * @return string
1082
+	 * @throws EE_Error
1083
+	 * @throws ReflectionException
1084
+	 */
1085
+	protected function venuesDropdown($current_value = '')
1086
+	{
1087
+		$values = ['' => esc_html__('All Venues', 'event_espresso')];
1088
+		// populate the list of venues.
1089
+		$venues = EEM_Venue::instance()->get_all(['order_by' => ['VNU_name' => 'ASC']]);
1090
+
1091
+		foreach ($venues as $venue) {
1092
+			$values[ $venue->ID() ] = $venue->name();
1093
+		}
1094
+
1095
+		return EEH_Form_Fields::select_input('venue', $values, $current_value);
1096
+	}
1097
+
1098
+
1099
+	/**
1100
+	 * output a dropdown of the categories for the category filter on the event admin list table
1101
+	 *
1102
+	 * @access  public
1103
+	 * @return string html
1104
+	 * @throws EE_Error
1105
+	 * @throws ReflectionException
1106
+	 */
1107
+	public function category_dropdown()
1108
+	{
1109
+		return EEH_Form_Fields::generate_event_category_dropdown(
1110
+			$this->request->getRequestParam('EVT_CAT', -1, 'int')
1111
+		);
1112
+	}
1113
+
1114
+
1115
+	/**
1116
+	 * get total number of events today
1117
+	 *
1118
+	 * @access public
1119
+	 * @return int
1120
+	 * @throws EE_Error
1121
+	 * @throws InvalidArgumentException
1122
+	 * @throws InvalidDataTypeException
1123
+	 * @throws InvalidInterfaceException
1124
+	 */
1125
+	public function total_events_today()
1126
+	{
1127
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1128
+			'DTT_EVT_start',
1129
+			date('Y-m-d') . ' 00:00:00',
1130
+			'Y-m-d H:i:s',
1131
+			'UTC'
1132
+		);
1133
+		$end   = EEM_Datetime::instance()->convert_datetime_for_query(
1134
+			'DTT_EVT_start',
1135
+			date('Y-m-d') . ' 23:59:59',
1136
+			'Y-m-d H:i:s',
1137
+			'UTC'
1138
+		);
1139
+		$where = [
1140
+			'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1141
+		];
1142
+		return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1143
+	}
1144
+
1145
+
1146
+	/**
1147
+	 * get total number of events this month
1148
+	 *
1149
+	 * @access public
1150
+	 * @return int
1151
+	 * @throws EE_Error
1152
+	 * @throws InvalidArgumentException
1153
+	 * @throws InvalidDataTypeException
1154
+	 * @throws InvalidInterfaceException
1155
+	 */
1156
+	public function total_events_this_month()
1157
+	{
1158
+		// Dates
1159
+		$this_year_r     = date('Y');
1160
+		$this_month_r    = date('m');
1161
+		$days_this_month = date('t');
1162
+		$start           = EEM_Datetime::instance()->convert_datetime_for_query(
1163
+			'DTT_EVT_start',
1164
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1165
+			'Y-m-d H:i:s',
1166
+			'UTC'
1167
+		);
1168
+		$end             = EEM_Datetime::instance()->convert_datetime_for_query(
1169
+			'DTT_EVT_start',
1170
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1171
+			'Y-m-d H:i:s',
1172
+			'UTC'
1173
+		);
1174
+		$where           = [
1175
+			'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1176
+		];
1177
+		return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1178
+	}
1179
+
1180
+
1181
+	/** DEFAULT TICKETS STUFF **/
1182
+
1183
+	/**
1184
+	 * Output default tickets list table view.
1185
+	 *
1186
+	 * @throws EE_Error
1187
+	 */
1188
+	public function _tickets_overview_list_table()
1189
+	{
1190
+		if (
1191
+			$this->admin_config->useAdvancedEditor()
1192
+			&& $this->feature->allowed('use_default_ticket_manager')
1193
+		) {
1194
+			// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1195
+			$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1196
+				EVENTS_CAF_TEMPLATE_PATH . 'default_tickets_moved_notice.template.php',
1197
+				[],
1198
+				true
1199
+			);
1200
+			$this->display_admin_page_with_no_sidebar();
1201
+		} else {
1202
+			$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1203
+			$this->display_admin_list_table_page_with_no_sidebar();
1204
+		}
1205
+	}
1206
+
1207
+
1208
+	/**
1209
+	 * @param int  $per_page
1210
+	 * @param bool $count
1211
+	 * @param bool $trashed
1212
+	 * @return EE_Soft_Delete_Base_Class[]|int
1213
+	 * @throws EE_Error
1214
+	 */
1215
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1216
+	{
1217
+		$orderby = $this->request->getRequestParam('orderby', 'TKT_name');
1218
+		$order   = $this->request->getRequestParam('order', 'ASC');
1219
+		switch ($orderby) {
1220
+			case 'TKT_name':
1221
+				$orderby = ['TKT_name' => $order];
1222
+				break;
1223
+			case 'TKT_price':
1224
+				$orderby = ['TKT_price' => $order];
1225
+				break;
1226
+			case 'TKT_uses':
1227
+				$orderby = ['TKT_uses' => $order];
1228
+				break;
1229
+			case 'TKT_min':
1230
+				$orderby = ['TKT_min' => $order];
1231
+				break;
1232
+			case 'TKT_max':
1233
+				$orderby = ['TKT_max' => $order];
1234
+				break;
1235
+			case 'TKT_qty':
1236
+				$orderby = ['TKT_qty' => $order];
1237
+				break;
1238
+		}
1239
+
1240
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
1241
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1242
+		$offset       = ($current_page - 1) * $per_page;
1243
+
1244
+		$where = [
1245
+			'TKT_is_default' => 1,
1246
+			'TKT_deleted'    => $trashed,
1247
+		];
1248
+
1249
+		$search_term = $this->request->getRequestParam('s');
1250
+		if ($search_term) {
1251
+			$search_term = '%' . $search_term . '%';
1252
+			$where['OR'] = [
1253
+				'TKT_name'        => ['LIKE', $search_term],
1254
+				'TKT_description' => ['LIKE', $search_term],
1255
+			];
1256
+		}
1257
+
1258
+		return $count
1259
+			? EEM_Ticket::instance()->count_deleted_and_undeleted([$where])
1260
+			: EEM_Ticket::instance()->get_all_deleted_and_undeleted(
1261
+				[
1262
+					$where,
1263
+					'order_by' => $orderby,
1264
+					'limit'    => [$offset, $per_page],
1265
+					'group_by' => 'TKT_ID',
1266
+				]
1267
+			);
1268
+	}
1269
+
1270
+
1271
+	/**
1272
+	 * @param bool $trash
1273
+	 * @throws EE_Error
1274
+	 * @throws InvalidArgumentException
1275
+	 * @throws InvalidDataTypeException
1276
+	 * @throws InvalidInterfaceException
1277
+	 */
1278
+	protected function _trash_or_restore_ticket($trash = false)
1279
+	{
1280
+		$success = 1;
1281
+		$TKT     = EEM_Ticket::instance();
1282
+		// checkboxes?
1283
+		$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1284
+		if (! empty($checkboxes)) {
1285
+			// if array has more than one element then success message should be plural
1286
+			$success = count($checkboxes) > 1 ? 2 : 1;
1287
+			// cycle thru the boxes
1288
+			while (list($TKT_ID, $value) = each($checkboxes)) {
1289
+				if ($trash) {
1290
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1291
+						$success = 0;
1292
+					}
1293
+				} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1294
+					$success = 0;
1295
+				}
1296
+			}
1297
+		} else {
1298
+			// grab single id and trash
1299
+			$TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1300
+			if ($trash) {
1301
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1302
+					$success = 0;
1303
+				}
1304
+			} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1305
+				$success = 0;
1306
+			}
1307
+		}
1308
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1309
+		$query_args  = [
1310
+			'action' => 'ticket_list_table',
1311
+			'status' => $trash ? '' : 'trashed',
1312
+		];
1313
+		$this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1314
+	}
1315
+
1316
+
1317
+	/**
1318
+	 * Handles trashing default ticket.
1319
+	 *
1320
+	 * @throws EE_Error
1321
+	 * @throws ReflectionException
1322
+	 */
1323
+	protected function _delete_ticket()
1324
+	{
1325
+		$success = 1;
1326
+		// checkboxes?
1327
+		$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1328
+		if (! empty($checkboxes)) {
1329
+			// if array has more than one element then success message should be plural
1330
+			$success = count($checkboxes) > 1 ? 2 : 1;
1331
+			// cycle thru the boxes
1332
+			while (list($TKT_ID, $value) = each($checkboxes)) {
1333
+				// delete
1334
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1335
+					$success = 0;
1336
+				}
1337
+			}
1338
+		} else {
1339
+			// grab single id and trash
1340
+			$TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1341
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1342
+				$success = 0;
1343
+			}
1344
+		}
1345
+		$action_desc = 'deleted';
1346
+		$query_args  = [
1347
+			'action' => 'ticket_list_table',
1348
+			'status' => 'trashed',
1349
+		];
1350
+		// fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1351
+		if (
1352
+			EEM_Ticket::instance()->count_deleted_and_undeleted(
1353
+				[['TKT_is_default' => 1]],
1354
+				'TKT_ID',
1355
+				true
1356
+			)
1357
+		) {
1358
+			$query_args = [];
1359
+		}
1360
+		$this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1361
+	}
1362
+
1363
+
1364
+	/**
1365
+	 * @param int $TKT_ID
1366
+	 * @return bool|int
1367
+	 * @throws EE_Error
1368
+	 * @throws ReflectionException
1369
+	 */
1370
+	protected function _delete_the_ticket($TKT_ID)
1371
+	{
1372
+		$ticket = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1373
+		if (! $ticket instanceof EE_Ticket) {
1374
+			return false;
1375
+		}
1376
+		$ticket->_remove_relations('Datetime');
1377
+		// delete all related prices first
1378
+		$ticket->delete_related_permanently('Price');
1379
+		return $ticket->delete_permanently();
1380
+	}
1381 1381
 }
Please login to merge, or discard this patch.
core/services/commands/registration/CreateRegistrationCommand.php 1 patch
Indentation   +147 added lines, -147 removed lines patch added patch discarded remove patch
@@ -24,151 +24,151 @@
 block discarded – undo
24 24
  */
25 25
 class CreateRegistrationCommand extends Command implements CommandRequiresCapCheckInterface
26 26
 {
27
-    /**
28
-     * @var EE_Transaction $transaction
29
-     */
30
-    private $transaction;
31
-
32
-    /**
33
-     * @var EE_Ticket $ticket
34
-     */
35
-    private $ticket;
36
-
37
-    /**
38
-     * @var EE_Line_Item $ticket_line_item
39
-     */
40
-    private $ticket_line_item;
41
-
42
-    /**
43
-     * @var int $reg_count
44
-     */
45
-    private $reg_count;
46
-
47
-    /**
48
-     * @var int $reg_group_size
49
-     */
50
-    private $reg_group_size;
51
-
52
-    /**
53
-     * @var string $reg_status
54
-     */
55
-    private $reg_status;
56
-
57
-    /**
58
-     * @var EE_Registration $registration
59
-     */
60
-    protected $registration;
61
-
62
-
63
-    /**
64
-     * CreateRegistrationCommand constructor.
65
-     *
66
-     * @param EE_Transaction $transaction
67
-     * @param EE_Line_Item   $ticket_line_item
68
-     * @param int            $reg_count
69
-     * @param int            $reg_group_size
70
-     * @param string         $reg_status
71
-     * @throws InvalidEntityException
72
-     */
73
-    public function __construct(
74
-        EE_Transaction $transaction,
75
-        EE_Line_Item $ticket_line_item,
76
-        $reg_count = 1,
77
-        $reg_group_size = 0,
78
-        $reg_status = EEM_Registration::status_id_incomplete
79
-    ) {
80
-        // grab the related ticket object for this line_item
81
-        $this->ticket = $ticket_line_item->ticket();
82
-        if (! $this->ticket instanceof EE_Ticket) {
83
-            throw new InvalidEntityException(
84
-                is_object($this->ticket) ? get_class($this->ticket) : gettype($this->ticket),
85
-                'EE_Ticket',
86
-                sprintf(
87
-                    esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'),
88
-                    $ticket_line_item->ID()
89
-                )
90
-            );
91
-        }
92
-        $this->transaction = $transaction;
93
-        $this->ticket_line_item = $ticket_line_item;
94
-        $this->reg_count = absint($reg_count);
95
-        $this->reg_group_size = absint($reg_group_size);
96
-        $this->reg_status = $reg_status;
97
-    }
98
-
99
-
100
-    /**
101
-     * @return CapCheckInterface
102
-     * @throws InvalidDataTypeException
103
-     */
104
-    public function getCapCheck()
105
-    {
106
-        if (! $this->cap_check instanceof CapCheckInterface) {
107
-            return new CapCheck('ee_edit_registrations', 'create_new_registration');
108
-        }
109
-        return $this->cap_check;
110
-    }
111
-
112
-
113
-    /**
114
-     * @return EE_Transaction
115
-     */
116
-    public function transaction()
117
-    {
118
-        return $this->transaction;
119
-    }
120
-
121
-
122
-    /**
123
-     * @return EE_Ticket
124
-     */
125
-    public function ticket()
126
-    {
127
-        return $this->ticket;
128
-    }
129
-
130
-
131
-    /**
132
-     * @return EE_Line_Item
133
-     */
134
-    public function ticketLineItem()
135
-    {
136
-        return $this->ticket_line_item;
137
-    }
138
-
139
-
140
-    /**
141
-     * @return int
142
-     */
143
-    public function regCount()
144
-    {
145
-        return $this->reg_count;
146
-    }
147
-
148
-
149
-    /**
150
-     * @return int
151
-     */
152
-    public function regGroupSize()
153
-    {
154
-        return $this->reg_group_size;
155
-    }
156
-
157
-
158
-    /**
159
-     * @return string
160
-     */
161
-    public function regStatus()
162
-    {
163
-        return $this->reg_status;
164
-    }
165
-
166
-
167
-    /**
168
-     * @return EE_Registration
169
-     */
170
-    public function registration()
171
-    {
172
-        return $this->registration;
173
-    }
27
+	/**
28
+	 * @var EE_Transaction $transaction
29
+	 */
30
+	private $transaction;
31
+
32
+	/**
33
+	 * @var EE_Ticket $ticket
34
+	 */
35
+	private $ticket;
36
+
37
+	/**
38
+	 * @var EE_Line_Item $ticket_line_item
39
+	 */
40
+	private $ticket_line_item;
41
+
42
+	/**
43
+	 * @var int $reg_count
44
+	 */
45
+	private $reg_count;
46
+
47
+	/**
48
+	 * @var int $reg_group_size
49
+	 */
50
+	private $reg_group_size;
51
+
52
+	/**
53
+	 * @var string $reg_status
54
+	 */
55
+	private $reg_status;
56
+
57
+	/**
58
+	 * @var EE_Registration $registration
59
+	 */
60
+	protected $registration;
61
+
62
+
63
+	/**
64
+	 * CreateRegistrationCommand constructor.
65
+	 *
66
+	 * @param EE_Transaction $transaction
67
+	 * @param EE_Line_Item   $ticket_line_item
68
+	 * @param int            $reg_count
69
+	 * @param int            $reg_group_size
70
+	 * @param string         $reg_status
71
+	 * @throws InvalidEntityException
72
+	 */
73
+	public function __construct(
74
+		EE_Transaction $transaction,
75
+		EE_Line_Item $ticket_line_item,
76
+		$reg_count = 1,
77
+		$reg_group_size = 0,
78
+		$reg_status = EEM_Registration::status_id_incomplete
79
+	) {
80
+		// grab the related ticket object for this line_item
81
+		$this->ticket = $ticket_line_item->ticket();
82
+		if (! $this->ticket instanceof EE_Ticket) {
83
+			throw new InvalidEntityException(
84
+				is_object($this->ticket) ? get_class($this->ticket) : gettype($this->ticket),
85
+				'EE_Ticket',
86
+				sprintf(
87
+					esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'),
88
+					$ticket_line_item->ID()
89
+				)
90
+			);
91
+		}
92
+		$this->transaction = $transaction;
93
+		$this->ticket_line_item = $ticket_line_item;
94
+		$this->reg_count = absint($reg_count);
95
+		$this->reg_group_size = absint($reg_group_size);
96
+		$this->reg_status = $reg_status;
97
+	}
98
+
99
+
100
+	/**
101
+	 * @return CapCheckInterface
102
+	 * @throws InvalidDataTypeException
103
+	 */
104
+	public function getCapCheck()
105
+	{
106
+		if (! $this->cap_check instanceof CapCheckInterface) {
107
+			return new CapCheck('ee_edit_registrations', 'create_new_registration');
108
+		}
109
+		return $this->cap_check;
110
+	}
111
+
112
+
113
+	/**
114
+	 * @return EE_Transaction
115
+	 */
116
+	public function transaction()
117
+	{
118
+		return $this->transaction;
119
+	}
120
+
121
+
122
+	/**
123
+	 * @return EE_Ticket
124
+	 */
125
+	public function ticket()
126
+	{
127
+		return $this->ticket;
128
+	}
129
+
130
+
131
+	/**
132
+	 * @return EE_Line_Item
133
+	 */
134
+	public function ticketLineItem()
135
+	{
136
+		return $this->ticket_line_item;
137
+	}
138
+
139
+
140
+	/**
141
+	 * @return int
142
+	 */
143
+	public function regCount()
144
+	{
145
+		return $this->reg_count;
146
+	}
147
+
148
+
149
+	/**
150
+	 * @return int
151
+	 */
152
+	public function regGroupSize()
153
+	{
154
+		return $this->reg_group_size;
155
+	}
156
+
157
+
158
+	/**
159
+	 * @return string
160
+	 */
161
+	public function regStatus()
162
+	{
163
+		return $this->reg_status;
164
+	}
165
+
166
+
167
+	/**
168
+	 * @return EE_Registration
169
+	 */
170
+	public function registration()
171
+	{
172
+		return $this->registration;
173
+	}
174 174
 }
Please login to merge, or discard this patch.
core/services/commands/CommandRequiresCapCheckInterface.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -13,8 +13,8 @@
 block discarded – undo
13 13
  */
14 14
 interface CommandRequiresCapCheckInterface
15 15
 {
16
-    /**
17
-     * @return CapCheckInterface
18
-     */
19
-    public function getCapCheck();
16
+	/**
17
+	 * @return CapCheckInterface
18
+	 */
19
+	public function getCapCheck();
20 20
 }
Please login to merge, or discard this patch.
core/services/routing/RouteHandler.php 2 patches
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -21,182 +21,182 @@
 block discarded – undo
21 21
  */
22 22
 class RouteHandler
23 23
 {
24
-    /**
25
-     * @var CapabilitiesCheckerInterface $capabilities_checker
26
-     */
27
-    private $capabilities_checker;
28
-
29
-    /**
30
-     * @var JsonDataNodeHandler $data_node_handler
31
-     */
32
-    private $data_node_handler;
33
-
34
-    /**
35
-     * @var LoaderInterface $loader
36
-     */
37
-    private $loader;
38
-
39
-    /**
40
-     * @var RequestInterface $request
41
-     */
42
-    protected $request;
43
-
44
-    /**
45
-     * @var RouteCollection $routes
46
-     */
47
-    private $routes;
48
-
49
-    /**
50
-     * @var boolean $print_data_nodes
51
-     */
52
-    private $print_data_nodes = true;
53
-
54
-    /**
55
-     * @var string $route_request_type
56
-     */
57
-    protected $route_request_type = '';
58
-
59
-
60
-    /**
61
-     * RouteHandler constructor.
62
-     *
63
-     * @param CapabilitiesCheckerInterface $capabilities_checker
64
-     * @param JsonDataNodeHandler $data_node_handler
65
-     * @param LoaderInterface     $loader
66
-     * @param RequestInterface    $request
67
-     * @param RouteCollection     $routes
68
-     */
69
-    public function __construct(
70
-        CapabilitiesCheckerInterface $capabilities_checker,
71
-        JsonDataNodeHandler $data_node_handler,
72
-        LoaderInterface $loader,
73
-        RequestInterface $request,
74
-        RouteCollection $routes
75
-    ) {
76
-        $this->capabilities_checker = $capabilities_checker;
77
-        $this->data_node_handler = $data_node_handler;
78
-        $this->loader            = $loader;
79
-        $this->request           = $request;
80
-        $this->routes            = $routes;
81
-    }
82
-
83
-
84
-    /**
85
-     * @param string $fqcn   Fully Qualified Class Name for Route
86
-     * @param bool   $handle if true [default] will immediately call RouteInterface::handleRequest() after adding
87
-     * @throws Exception
88
-     */
89
-    public function addRoute(string $fqcn, bool $handle = true)
90
-    {
91
-        try {
92
-            $route = $this->loader->getShared($fqcn);
93
-            $this->validateRoute($route, $fqcn);
94
-            if ($this->capabilities_checker->processCapCheck($route->getCapCheck(), true)) {
95
-                $this->routes->add($route);
96
-                $this->handle($route, $handle);
97
-            }
98
-        } catch (Exception $exception) {
99
-            new ExceptionStackTraceDisplay(
100
-                new DomainException(
101
-                    sprintf(
102
-                        esc_html__(
103
-                            'The following error occurred while trying to handle the "%1$s" route:%2$s%3$s',
104
-                            'event_espresso'
105
-                        ),
106
-                        $fqcn,
107
-                        '<br />',
108
-                        $exception->getMessage()
109
-                    )
110
-                )
111
-            );
112
-        }
113
-    }
114
-
115
-
116
-    /**
117
-     * @return string
118
-     */
119
-    public function getRouteRequestType(): string
120
-    {
121
-        return $this->route_request_type;
122
-    }
123
-
124
-
125
-    /**
126
-     * @param string $route_request_type
127
-     */
128
-    public function setRouteRequestType(string $route_request_type = '')
129
-    {
130
-        $this->route_request_type = ! empty($route_request_type) ? $route_request_type : $this->route_request_type;
131
-    }
132
-
133
-
134
-    /**
135
-     * @param RouteInterface $route
136
-     * @param bool           $handle if true [default] will immediately call RouteInterface::handleRequest()
137
-     */
138
-    public function handle(RouteInterface $route, bool $handle = true)
139
-    {
140
-        if ($handle && $route->isNotHandled()) {
141
-            $route->handleRequest();
142
-            if ($route instanceof PrimaryRoute) {
143
-                $this->setRouteRequestType($route->getRouteRequestType());
144
-            }
145
-            $data_node = $route->dataNode();
146
-            if ($data_node instanceof JsonDataNode) {
147
-                $this->data_node_handler->addDataNode($data_node);
148
-                $this->printDataNodes();
149
-            }
150
-        }
151
-    }
152
-
153
-
154
-    /**
155
-     * calls RouteInterface::handleRequest() on all Routes that
156
-     *      - match current request
157
-     *      - have yet to be handled
158
-     *
159
-     * @return void
160
-     */
161
-    public function handleRoutesForCurrentRequest()
162
-    {
163
-        $this->routes->handleRoutesForCurrentRequest();
164
-    }
165
-
166
-
167
-    /**
168
-     * @return void
169
-     */
170
-    private function printDataNodes()
171
-    {
172
-        if ($this->print_data_nodes) {
173
-            add_action('admin_footer', [$this->data_node_handler, 'printDataNode'], 0);
174
-            add_action('wp_footer', [$this->data_node_handler, 'printDataNode'], 0);
175
-            $this->print_data_nodes = false;
176
-        }
177
-    }
178
-
179
-
180
-    /**
181
-     * @param RouteInterface|null $route
182
-     * @param string              $fqcn
183
-     */
184
-    private function validateRoute(?RouteInterface $route, string $fqcn = '')
185
-    {
186
-        if (! $route instanceof RouteInterface) {
187
-            throw new InvalidClassException(
188
-                sprintf(
189
-                    /*
24
+	/**
25
+	 * @var CapabilitiesCheckerInterface $capabilities_checker
26
+	 */
27
+	private $capabilities_checker;
28
+
29
+	/**
30
+	 * @var JsonDataNodeHandler $data_node_handler
31
+	 */
32
+	private $data_node_handler;
33
+
34
+	/**
35
+	 * @var LoaderInterface $loader
36
+	 */
37
+	private $loader;
38
+
39
+	/**
40
+	 * @var RequestInterface $request
41
+	 */
42
+	protected $request;
43
+
44
+	/**
45
+	 * @var RouteCollection $routes
46
+	 */
47
+	private $routes;
48
+
49
+	/**
50
+	 * @var boolean $print_data_nodes
51
+	 */
52
+	private $print_data_nodes = true;
53
+
54
+	/**
55
+	 * @var string $route_request_type
56
+	 */
57
+	protected $route_request_type = '';
58
+
59
+
60
+	/**
61
+	 * RouteHandler constructor.
62
+	 *
63
+	 * @param CapabilitiesCheckerInterface $capabilities_checker
64
+	 * @param JsonDataNodeHandler $data_node_handler
65
+	 * @param LoaderInterface     $loader
66
+	 * @param RequestInterface    $request
67
+	 * @param RouteCollection     $routes
68
+	 */
69
+	public function __construct(
70
+		CapabilitiesCheckerInterface $capabilities_checker,
71
+		JsonDataNodeHandler $data_node_handler,
72
+		LoaderInterface $loader,
73
+		RequestInterface $request,
74
+		RouteCollection $routes
75
+	) {
76
+		$this->capabilities_checker = $capabilities_checker;
77
+		$this->data_node_handler = $data_node_handler;
78
+		$this->loader            = $loader;
79
+		$this->request           = $request;
80
+		$this->routes            = $routes;
81
+	}
82
+
83
+
84
+	/**
85
+	 * @param string $fqcn   Fully Qualified Class Name for Route
86
+	 * @param bool   $handle if true [default] will immediately call RouteInterface::handleRequest() after adding
87
+	 * @throws Exception
88
+	 */
89
+	public function addRoute(string $fqcn, bool $handle = true)
90
+	{
91
+		try {
92
+			$route = $this->loader->getShared($fqcn);
93
+			$this->validateRoute($route, $fqcn);
94
+			if ($this->capabilities_checker->processCapCheck($route->getCapCheck(), true)) {
95
+				$this->routes->add($route);
96
+				$this->handle($route, $handle);
97
+			}
98
+		} catch (Exception $exception) {
99
+			new ExceptionStackTraceDisplay(
100
+				new DomainException(
101
+					sprintf(
102
+						esc_html__(
103
+							'The following error occurred while trying to handle the "%1$s" route:%2$s%3$s',
104
+							'event_espresso'
105
+						),
106
+						$fqcn,
107
+						'<br />',
108
+						$exception->getMessage()
109
+					)
110
+				)
111
+			);
112
+		}
113
+	}
114
+
115
+
116
+	/**
117
+	 * @return string
118
+	 */
119
+	public function getRouteRequestType(): string
120
+	{
121
+		return $this->route_request_type;
122
+	}
123
+
124
+
125
+	/**
126
+	 * @param string $route_request_type
127
+	 */
128
+	public function setRouteRequestType(string $route_request_type = '')
129
+	{
130
+		$this->route_request_type = ! empty($route_request_type) ? $route_request_type : $this->route_request_type;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @param RouteInterface $route
136
+	 * @param bool           $handle if true [default] will immediately call RouteInterface::handleRequest()
137
+	 */
138
+	public function handle(RouteInterface $route, bool $handle = true)
139
+	{
140
+		if ($handle && $route->isNotHandled()) {
141
+			$route->handleRequest();
142
+			if ($route instanceof PrimaryRoute) {
143
+				$this->setRouteRequestType($route->getRouteRequestType());
144
+			}
145
+			$data_node = $route->dataNode();
146
+			if ($data_node instanceof JsonDataNode) {
147
+				$this->data_node_handler->addDataNode($data_node);
148
+				$this->printDataNodes();
149
+			}
150
+		}
151
+	}
152
+
153
+
154
+	/**
155
+	 * calls RouteInterface::handleRequest() on all Routes that
156
+	 *      - match current request
157
+	 *      - have yet to be handled
158
+	 *
159
+	 * @return void
160
+	 */
161
+	public function handleRoutesForCurrentRequest()
162
+	{
163
+		$this->routes->handleRoutesForCurrentRequest();
164
+	}
165
+
166
+
167
+	/**
168
+	 * @return void
169
+	 */
170
+	private function printDataNodes()
171
+	{
172
+		if ($this->print_data_nodes) {
173
+			add_action('admin_footer', [$this->data_node_handler, 'printDataNode'], 0);
174
+			add_action('wp_footer', [$this->data_node_handler, 'printDataNode'], 0);
175
+			$this->print_data_nodes = false;
176
+		}
177
+	}
178
+
179
+
180
+	/**
181
+	 * @param RouteInterface|null $route
182
+	 * @param string              $fqcn
183
+	 */
184
+	private function validateRoute(?RouteInterface $route, string $fqcn = '')
185
+	{
186
+		if (! $route instanceof RouteInterface) {
187
+			throw new InvalidClassException(
188
+				sprintf(
189
+					/*
190 190
                      * translators:
191 191
                      * The supplied FQCN (Fully\Qualified\Class\Name) must be an instance of RouteInterface.
192 192
                      */
193
-                    esc_html__(
194
-                        'The supplied FQCN (%1$s) must be an instance of RouteInterface.',
195
-                        'event_espresso'
196
-                    ),
197
-                    $fqcn
198
-                )
199
-            );
200
-        }
201
-    }
193
+					esc_html__(
194
+						'The supplied FQCN (%1$s) must be an instance of RouteInterface.',
195
+						'event_espresso'
196
+					),
197
+					$fqcn
198
+				)
199
+			);
200
+		}
201
+	}
202 202
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -183,7 +183,7 @@
 block discarded – undo
183 183
      */
184 184
     private function validateRoute(?RouteInterface $route, string $fqcn = '')
185 185
     {
186
-        if (! $route instanceof RouteInterface) {
186
+        if ( ! $route instanceof RouteInterface) {
187 187
             throw new InvalidClassException(
188 188
                 sprintf(
189 189
                     /*
Please login to merge, or discard this patch.
core/services/routing/Route.php 1 patch
Indentation   +267 added lines, -267 removed lines patch added patch discarded remove patch
@@ -28,271 +28,271 @@
 block discarded – undo
28 28
  */
29 29
 abstract class Route implements RouteInterface, RequiresCapCheckInterface
30 30
 {
31
-    /**
32
-     * @var AssetManagerInterface $asset_manager
33
-     */
34
-    protected $asset_manager;
35
-
36
-    /**
37
-     * @var EE_Dependency_Map $dependency_map
38
-     */
39
-    protected $dependency_map;
40
-
41
-    /**
42
-     * @var JsonDataNode $data_node
43
-     */
44
-    protected $data_node;
45
-
46
-    /**
47
-     * @var LoaderInterface $loader
48
-     */
49
-    protected $loader;
50
-
51
-    /**
52
-     * @var RequestInterface $request
53
-     */
54
-    protected $request;
55
-
56
-    /**
57
-     * @var RouteMatchSpecificationInterface $specification
58
-     */
59
-    protected $specification;
60
-
61
-    /**
62
-     * @var boolean $handled
63
-     */
64
-    private $handled = false;
65
-
66
-    /**
67
-     * @var array $default_dependencies
68
-     */
69
-    protected static $default_dependencies = [
70
-        'EE_Dependency_Map'                           => EE_Dependency_Map::load_from_cache,
71
-        'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
72
-        'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
73
-    ];
74
-
75
-    /**
76
-     * @var array $full_dependencies
77
-     */
78
-    protected static $full_dependencies = [
79
-        'EE_Dependency_Map'                             => EE_Dependency_Map::load_from_cache,
80
-        'EventEspresso\core\services\loaders\Loader'    => EE_Dependency_Map::load_from_cache,
81
-        'EventEspresso\core\services\request\Request'   => EE_Dependency_Map::load_from_cache,
82
-        'EventEspresso\core\services\json\JsonDataNode' => EE_Dependency_Map::load_from_cache,
83
-        RouteMatchSpecificationInterface::class         => EE_Dependency_Map::load_from_cache,
84
-    ];
85
-
86
-
87
-    /**
88
-     * Route constructor.
89
-     *
90
-     * @param EE_Dependency_Map                     $dependency_map
91
-     * @param LoaderInterface                       $loader
92
-     * @param RequestInterface                      $request
93
-     * @param JsonDataNode|null                     $data_node
94
-     * @param RouteMatchSpecificationInterface|null $specification
95
-     */
96
-    public function __construct(
97
-        EE_Dependency_Map $dependency_map,
98
-        LoaderInterface $loader,
99
-        RequestInterface $request,
100
-        JsonDataNode $data_node = null,
101
-        RouteMatchSpecificationInterface $specification = null
102
-    ) {
103
-        $this->dependency_map = $dependency_map;
104
-        $this->data_node      = $data_node;
105
-        $this->loader         = $loader;
106
-        $this->request        = $request;
107
-        $this->setSpecification($specification);
108
-    }
109
-
110
-
111
-    /**
112
-     * @return void
113
-     */
114
-    abstract protected function registerDependencies();
115
-
116
-
117
-    /**
118
-     * implements logic required to run during request
119
-     *
120
-     * @return bool
121
-     */
122
-    abstract protected function requestHandler(): bool;
123
-
124
-
125
-    /**
126
-     * called just before matchesCurrentRequest()
127
-     * and allows Route to perform any setup required such as calling setSpecification()
128
-     *
129
-     * @return void
130
-     */
131
-    public function initialize()
132
-    {
133
-        // do nothing by default
134
-    }
135
-
136
-
137
-    /**
138
-     * returns true if the current request matches this route
139
-     * child classes can override and use Request directly to match route with request
140
-     * or supply a RouteMatchSpecification class and just use the below
141
-     *
142
-     * @return bool
143
-     */
144
-    public function matchesCurrentRequest(): bool
145
-    {
146
-        return $this->specification instanceof RouteMatchSpecificationInterface
147
-               && $this->specification->isMatchingRoute();
148
-    }
149
-
150
-
151
-    /**
152
-     * returns the FQCN for this route's JsonDataNode
153
-     *
154
-     * @return string
155
-     */
156
-    protected function dataNodeClass(): string
157
-    {
158
-        return '';
159
-    }
160
-
161
-
162
-    public function getCapCheck()
163
-    {
164
-        return new PublicCapabilities('', 'access Event Espresso route');
165
-    }
166
-
167
-
168
-    /**
169
-     * @return array
170
-     */
171
-    public static function getDefaultDependencies(): array
172
-    {
173
-        return self::$default_dependencies;
174
-    }
175
-
176
-
177
-    /**
178
-     * @return array
179
-     */
180
-    public static function getFullDependencies(): array
181
-    {
182
-        return self::$full_dependencies;
183
-    }
184
-
185
-
186
-    /**
187
-     * @param JsonDataNode|null $data_node
188
-     */
189
-    protected function setDataNode(JsonDataNode $data_node = null)
190
-    {
191
-        $this->data_node = $data_node;
192
-    }
193
-
194
-
195
-    /**
196
-     * @param RouteMatchSpecificationInterface|null $specification
197
-     */
198
-    protected function setSpecification(RouteMatchSpecificationInterface $specification = null)
199
-    {
200
-        $this->specification = $specification;
201
-    }
202
-
203
-
204
-    /**
205
-     * @return JsonDataNode
206
-     */
207
-    public function dataNode(): ?JsonDataNode
208
-    {
209
-        return $this->data_node;
210
-    }
211
-
212
-
213
-    /**
214
-     * runs route requestHandler() if
215
-     *      - route has not previously been handled
216
-     *      - route specification matches for current request
217
-     * sets route handled property based on results returned by requestHandler()
218
-     *
219
-     * @return bool
220
-     */
221
-    public function handleRequest(): bool
222
-    {
223
-        if ($this->isNotHandled()) {
224
-            $this->initialize();
225
-            if ($this->matchesCurrentRequest()) {
226
-                do_action('AHEE__EventEspresso_core_domain_entities_routes_handlers_Route__handleRequest', $this);
227
-                $this->registerDependencies();
228
-                $this->loadDataNode();
229
-                $this->verifyIsHandled($this->requestHandler());
230
-            }
231
-        }
232
-        return $this->handled;
233
-    }
234
-
235
-
236
-    /**
237
-     * @return bool
238
-     */
239
-    final public function isHandled(): bool
240
-    {
241
-        return $this->handled;
242
-    }
243
-
244
-
245
-    /**
246
-     * @return bool
247
-     */
248
-    final public function isNotHandled(): bool
249
-    {
250
-        return ! $this->handled;
251
-    }
252
-
253
-
254
-    /**
255
-     * @return void
256
-     */
257
-    private function loadDataNode()
258
-    {
259
-        $data_node_fqcn = $this->dataNodeClass();
260
-        if (! empty($data_node_fqcn)) {
261
-            $data_node = $this->loader->getShared($data_node_fqcn);
262
-            $this->setDataNode($data_node);
263
-        }
264
-    }
265
-
266
-
267
-    /**
268
-     * @param string $domain_fqcn
269
-     */
270
-    public function initializeBaristaForDomain(string $domain_fqcn)
271
-    {
272
-        if (apply_filters('FHEE__load_Barista', true)) {
273
-            /** @var BaristaFactory $factory */
274
-            $factory = $this->loader->getShared(BaristaFactory::class);
275
-            $barista = $factory->createFromDomainClass($domain_fqcn);
276
-            if ($barista instanceof BaristaInterface) {
277
-                $barista->initialize();
278
-            }
279
-        }
280
-    }
281
-
282
-
283
-    /**
284
-     * @var bool
285
-     */
286
-    private function verifyIsHandled($handled)
287
-    {
288
-        if (! is_bool($handled)) {
289
-            throw new DomainException(
290
-                esc_html__(
291
-                    'Route::requestHandler() must return a boolean to indicate whether the request has been handled or not.',
292
-                    'event_espresso'
293
-                )
294
-            );
295
-        }
296
-        $this->handled = filter_var($handled, FILTER_VALIDATE_BOOLEAN);
297
-    }
31
+	/**
32
+	 * @var AssetManagerInterface $asset_manager
33
+	 */
34
+	protected $asset_manager;
35
+
36
+	/**
37
+	 * @var EE_Dependency_Map $dependency_map
38
+	 */
39
+	protected $dependency_map;
40
+
41
+	/**
42
+	 * @var JsonDataNode $data_node
43
+	 */
44
+	protected $data_node;
45
+
46
+	/**
47
+	 * @var LoaderInterface $loader
48
+	 */
49
+	protected $loader;
50
+
51
+	/**
52
+	 * @var RequestInterface $request
53
+	 */
54
+	protected $request;
55
+
56
+	/**
57
+	 * @var RouteMatchSpecificationInterface $specification
58
+	 */
59
+	protected $specification;
60
+
61
+	/**
62
+	 * @var boolean $handled
63
+	 */
64
+	private $handled = false;
65
+
66
+	/**
67
+	 * @var array $default_dependencies
68
+	 */
69
+	protected static $default_dependencies = [
70
+		'EE_Dependency_Map'                           => EE_Dependency_Map::load_from_cache,
71
+		'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
72
+		'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
73
+	];
74
+
75
+	/**
76
+	 * @var array $full_dependencies
77
+	 */
78
+	protected static $full_dependencies = [
79
+		'EE_Dependency_Map'                             => EE_Dependency_Map::load_from_cache,
80
+		'EventEspresso\core\services\loaders\Loader'    => EE_Dependency_Map::load_from_cache,
81
+		'EventEspresso\core\services\request\Request'   => EE_Dependency_Map::load_from_cache,
82
+		'EventEspresso\core\services\json\JsonDataNode' => EE_Dependency_Map::load_from_cache,
83
+		RouteMatchSpecificationInterface::class         => EE_Dependency_Map::load_from_cache,
84
+	];
85
+
86
+
87
+	/**
88
+	 * Route constructor.
89
+	 *
90
+	 * @param EE_Dependency_Map                     $dependency_map
91
+	 * @param LoaderInterface                       $loader
92
+	 * @param RequestInterface                      $request
93
+	 * @param JsonDataNode|null                     $data_node
94
+	 * @param RouteMatchSpecificationInterface|null $specification
95
+	 */
96
+	public function __construct(
97
+		EE_Dependency_Map $dependency_map,
98
+		LoaderInterface $loader,
99
+		RequestInterface $request,
100
+		JsonDataNode $data_node = null,
101
+		RouteMatchSpecificationInterface $specification = null
102
+	) {
103
+		$this->dependency_map = $dependency_map;
104
+		$this->data_node      = $data_node;
105
+		$this->loader         = $loader;
106
+		$this->request        = $request;
107
+		$this->setSpecification($specification);
108
+	}
109
+
110
+
111
+	/**
112
+	 * @return void
113
+	 */
114
+	abstract protected function registerDependencies();
115
+
116
+
117
+	/**
118
+	 * implements logic required to run during request
119
+	 *
120
+	 * @return bool
121
+	 */
122
+	abstract protected function requestHandler(): bool;
123
+
124
+
125
+	/**
126
+	 * called just before matchesCurrentRequest()
127
+	 * and allows Route to perform any setup required such as calling setSpecification()
128
+	 *
129
+	 * @return void
130
+	 */
131
+	public function initialize()
132
+	{
133
+		// do nothing by default
134
+	}
135
+
136
+
137
+	/**
138
+	 * returns true if the current request matches this route
139
+	 * child classes can override and use Request directly to match route with request
140
+	 * or supply a RouteMatchSpecification class and just use the below
141
+	 *
142
+	 * @return bool
143
+	 */
144
+	public function matchesCurrentRequest(): bool
145
+	{
146
+		return $this->specification instanceof RouteMatchSpecificationInterface
147
+			   && $this->specification->isMatchingRoute();
148
+	}
149
+
150
+
151
+	/**
152
+	 * returns the FQCN for this route's JsonDataNode
153
+	 *
154
+	 * @return string
155
+	 */
156
+	protected function dataNodeClass(): string
157
+	{
158
+		return '';
159
+	}
160
+
161
+
162
+	public function getCapCheck()
163
+	{
164
+		return new PublicCapabilities('', 'access Event Espresso route');
165
+	}
166
+
167
+
168
+	/**
169
+	 * @return array
170
+	 */
171
+	public static function getDefaultDependencies(): array
172
+	{
173
+		return self::$default_dependencies;
174
+	}
175
+
176
+
177
+	/**
178
+	 * @return array
179
+	 */
180
+	public static function getFullDependencies(): array
181
+	{
182
+		return self::$full_dependencies;
183
+	}
184
+
185
+
186
+	/**
187
+	 * @param JsonDataNode|null $data_node
188
+	 */
189
+	protected function setDataNode(JsonDataNode $data_node = null)
190
+	{
191
+		$this->data_node = $data_node;
192
+	}
193
+
194
+
195
+	/**
196
+	 * @param RouteMatchSpecificationInterface|null $specification
197
+	 */
198
+	protected function setSpecification(RouteMatchSpecificationInterface $specification = null)
199
+	{
200
+		$this->specification = $specification;
201
+	}
202
+
203
+
204
+	/**
205
+	 * @return JsonDataNode
206
+	 */
207
+	public function dataNode(): ?JsonDataNode
208
+	{
209
+		return $this->data_node;
210
+	}
211
+
212
+
213
+	/**
214
+	 * runs route requestHandler() if
215
+	 *      - route has not previously been handled
216
+	 *      - route specification matches for current request
217
+	 * sets route handled property based on results returned by requestHandler()
218
+	 *
219
+	 * @return bool
220
+	 */
221
+	public function handleRequest(): bool
222
+	{
223
+		if ($this->isNotHandled()) {
224
+			$this->initialize();
225
+			if ($this->matchesCurrentRequest()) {
226
+				do_action('AHEE__EventEspresso_core_domain_entities_routes_handlers_Route__handleRequest', $this);
227
+				$this->registerDependencies();
228
+				$this->loadDataNode();
229
+				$this->verifyIsHandled($this->requestHandler());
230
+			}
231
+		}
232
+		return $this->handled;
233
+	}
234
+
235
+
236
+	/**
237
+	 * @return bool
238
+	 */
239
+	final public function isHandled(): bool
240
+	{
241
+		return $this->handled;
242
+	}
243
+
244
+
245
+	/**
246
+	 * @return bool
247
+	 */
248
+	final public function isNotHandled(): bool
249
+	{
250
+		return ! $this->handled;
251
+	}
252
+
253
+
254
+	/**
255
+	 * @return void
256
+	 */
257
+	private function loadDataNode()
258
+	{
259
+		$data_node_fqcn = $this->dataNodeClass();
260
+		if (! empty($data_node_fqcn)) {
261
+			$data_node = $this->loader->getShared($data_node_fqcn);
262
+			$this->setDataNode($data_node);
263
+		}
264
+	}
265
+
266
+
267
+	/**
268
+	 * @param string $domain_fqcn
269
+	 */
270
+	public function initializeBaristaForDomain(string $domain_fqcn)
271
+	{
272
+		if (apply_filters('FHEE__load_Barista', true)) {
273
+			/** @var BaristaFactory $factory */
274
+			$factory = $this->loader->getShared(BaristaFactory::class);
275
+			$barista = $factory->createFromDomainClass($domain_fqcn);
276
+			if ($barista instanceof BaristaInterface) {
277
+				$barista->initialize();
278
+			}
279
+		}
280
+	}
281
+
282
+
283
+	/**
284
+	 * @var bool
285
+	 */
286
+	private function verifyIsHandled($handled)
287
+	{
288
+		if (! is_bool($handled)) {
289
+			throw new DomainException(
290
+				esc_html__(
291
+					'Route::requestHandler() must return a boolean to indicate whether the request has been handled or not.',
292
+					'event_espresso'
293
+				)
294
+			);
295
+		}
296
+		$this->handled = filter_var($handled, FILTER_VALIDATE_BOOLEAN);
297
+	}
298 298
 }
Please login to merge, or discard this patch.