Completed
Branch FET/reg-form-v2 (f85ea5)
by
unknown
11:15 queued 08:51
created
core/domain/services/registration/form/SystemInputFieldNamesInterface.php 1 patch
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -4,32 +4,32 @@
 block discarded – undo
4 4
 
5 5
 interface SystemInputFieldNamesInterface
6 6
 {
7
-    const FIRST_NAME    = 'first-name';
7
+	const FIRST_NAME    = 'first-name';
8 8
 
9
-    const LAST_NAME     = 'last-name';
9
+	const LAST_NAME     = 'last-name';
10 10
 
11
-    const EMAIL         = 'email';
11
+	const EMAIL         = 'email';
12 12
 
13
-    const EMAIL_CONFIRM = 'email-confirmation';
13
+	const EMAIL_CONFIRM = 'email-confirmation';
14 14
 
15
-    const ADDRESS       = 'address';
15
+	const ADDRESS       = 'address';
16 16
 
17
-    const ADDRESS_2     = 'address-2';
17
+	const ADDRESS_2     = 'address-2';
18 18
 
19
-    const CITY          = 'city';
19
+	const CITY          = 'city';
20 20
 
21
-    const STATE         = 'state';
21
+	const STATE         = 'state';
22 22
 
23
-    const COUNTRY       = 'country';
23
+	const COUNTRY       = 'country';
24 24
 
25
-    const POSTAL_CODE   = 'postal-code';
25
+	const POSTAL_CODE   = 'postal-code';
26 26
 
27
-    const PHONE         = 'phone';
27
+	const PHONE         = 'phone';
28 28
 
29 29
 
30
-    /**
31
-     * @param string $field
32
-     * @return string
33
-     */
34
-    public function getInputName(string $field): string;
30
+	/**
31
+	 * @param string $field
32
+	 * @return string
33
+	 */
34
+	public function getInputName(string $field): string;
35 35
 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegForm.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -21,44 +21,44 @@
 block discarded – undo
21 21
 class RegForm extends RegFormBase
22 22
 {
23 23
 
24
-    /**
25
-     * RegForm constructor.
26
-     *
27
-     * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
28
-     * @param EE_Registration_Config                $reg_config
29
-     * @throws ReflectionException
30
-     * @throws EE_Error
31
-     */
32
-    public function __construct(
33
-        EE_SPCO_Reg_Step_Attendee_Information $reg_step,
34
-        EE_Registration_Config $reg_config
35
-    ) {
36
-        LoaderFactory::getShared(RegFormQuestionFactory::class, [[$this, 'addRequiredQuestion']]);
37
-        parent::__construct($reg_step, $reg_config);
38
-    }
24
+	/**
25
+	 * RegForm constructor.
26
+	 *
27
+	 * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
28
+	 * @param EE_Registration_Config                $reg_config
29
+	 * @throws ReflectionException
30
+	 * @throws EE_Error
31
+	 */
32
+	public function __construct(
33
+		EE_SPCO_Reg_Step_Attendee_Information $reg_step,
34
+		EE_Registration_Config $reg_config
35
+	) {
36
+		LoaderFactory::getShared(RegFormQuestionFactory::class, [[$this, 'addRequiredQuestion']]);
37
+		parent::__construct($reg_step, $reg_config);
38
+	}
39 39
 
40 40
 
41
-    /**
42
-     * @param EE_Registration $registration
43
-     * @param bool            $admin_request
44
-     * @param bool            $copy_attendee_info
45
-     * @param callable        $enablePrintCopyInfo
46
-     * @return RegistrantFormInterface
47
-     */
48
-    protected function getRegistrantForm(
49
-        EE_Registration $registration,
50
-        bool $admin_request,
51
-        bool $copy_attendee_info,
52
-        callable $enablePrintCopyInfo
53
-    ): RegistrantFormInterface {
54
-        return LoaderFactory::getNew(
55
-            RegistrantForm::class,
56
-            [
57
-                $registration,
58
-                $admin_request,
59
-                $copy_attendee_info,
60
-                $enablePrintCopyInfo,
61
-            ]
62
-        );
63
-    }
41
+	/**
42
+	 * @param EE_Registration $registration
43
+	 * @param bool            $admin_request
44
+	 * @param bool            $copy_attendee_info
45
+	 * @param callable        $enablePrintCopyInfo
46
+	 * @return RegistrantFormInterface
47
+	 */
48
+	protected function getRegistrantForm(
49
+		EE_Registration $registration,
50
+		bool $admin_request,
51
+		bool $copy_attendee_info,
52
+		callable $enablePrintCopyInfo
53
+	): RegistrantFormInterface {
54
+		return LoaderFactory::getNew(
55
+			RegistrantForm::class,
56
+			[
57
+				$registration,
58
+				$admin_request,
59
+				$copy_attendee_info,
60
+				$enablePrintCopyInfo,
61
+			]
62
+		);
63
+	}
64 64
 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegFormInputHandler.php 2 patches
Indentation   +265 added lines, -265 removed lines patch added patch discarded remove patch
@@ -16,295 +16,295 @@
 block discarded – undo
16 16
 class RegFormInputHandler
17 17
 {
18 18
 
19
-    /**
20
-     * @var EEM_Attendee
21
-     */
22
-    protected $attendee_model;
19
+	/**
20
+	 * @var EEM_Attendee
21
+	 */
22
+	protected $attendee_model;
23 23
 
24
-    /**
25
-     * @var string
26
-     */
27
-    protected $checkout_reg_url_link;
24
+	/**
25
+	 * @var string
26
+	 */
27
+	protected $checkout_reg_url_link;
28 28
 
29
-    /**
30
-     * @var array
31
-     */
32
-    protected $non_persistable_fields = [SystemInputFieldNamesInterface::EMAIL_CONFIRM];
29
+	/**
30
+	 * @var array
31
+	 */
32
+	protected $non_persistable_fields = [SystemInputFieldNamesInterface::EMAIL_CONFIRM];
33 33
 
34
-    /**
35
-     * @var RegistrantData
36
-     */
37
-    protected $registrant_data;
34
+	/**
35
+	 * @var RegistrantData
36
+	 */
37
+	protected $registrant_data;
38 38
 
39
-    /**
40
-     * @var array
41
-     */
42
-    protected $required_questions;
39
+	/**
40
+	 * @var array
41
+	 */
42
+	protected $required_questions;
43 43
 
44
-    /**
45
-     * @var SystemInputFieldNamesInterface
46
-     */
47
-    protected $system_input_field_names;
44
+	/**
45
+	 * @var SystemInputFieldNamesInterface
46
+	 */
47
+	protected $system_input_field_names;
48 48
 
49 49
 
50
-    /**
51
-     * RegFormHandler constructor.
52
-     */
53
-    public function __construct(
54
-        string $checkout_reg_url_link,
55
-        array $required_questions,
56
-        EEM_Attendee $attendee_model,
57
-        RegistrantData $registrant_data,
58
-        SystemInputFieldNamesInterface $system_input_field_names
59
-    ) {
60
-        $this->attendee_model           = $attendee_model;
61
-        $this->checkout_reg_url_link    = $checkout_reg_url_link;
62
-        $this->registrant_data          = $registrant_data;
63
-        $this->required_questions       = $required_questions;
64
-        $this->system_input_field_names = $system_input_field_names;
65
-    }
50
+	/**
51
+	 * RegFormHandler constructor.
52
+	 */
53
+	public function __construct(
54
+		string $checkout_reg_url_link,
55
+		array $required_questions,
56
+		EEM_Attendee $attendee_model,
57
+		RegistrantData $registrant_data,
58
+		SystemInputFieldNamesInterface $system_input_field_names
59
+	) {
60
+		$this->attendee_model           = $attendee_model;
61
+		$this->checkout_reg_url_link    = $checkout_reg_url_link;
62
+		$this->registrant_data          = $registrant_data;
63
+		$this->required_questions       = $required_questions;
64
+		$this->system_input_field_names = $system_input_field_names;
65
+	}
66 66
 
67 67
 
68
-    /**
69
-     * @param EE_Registration  $registration
70
-     * @param string           $reg_url_link
71
-     * @param int|string       $field
72
-     * @param float|int|string $value
73
-     * @return bool
74
-     * @throws EE_Error
75
-     * @throws ReflectionException
76
-     */
77
-    public function processFormInput(
78
-        EE_Registration $registration,
79
-        string $reg_url_link,
80
-        $field,
81
-        $value
82
-    ): bool {
83
-        // check for critical inputs
84
-        if (! $this->verifyCriticalAttendeeDetailsAreSetAndValidateEmail($field, $value)) {
85
-            echo "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
86
-            return false;
87
-        }
88
-        $value = $this->registrant_data->saveOrCopyPrimaryRegistrantData(
89
-            $reg_url_link,
90
-            $field,
91
-            $value
92
-        );
93
-        \EEH_Debug_Tools::printr($value, ' value >>====> ', __FILE__, __LINE__);
94
-        if (! $this->saveRegistrationFormInput($registration, $reg_url_link, $field, $value)) {
95
-            EE_Error::add_error(
96
-                sprintf(
97
-                    esc_html_x(
98
-                        'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
99
-                        'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"',
100
-                        'event_espresso'
101
-                    ),
102
-                    $field,
103
-                    $value
104
-                ),
105
-                __FILE__,
106
-                __FUNCTION__,
107
-                __LINE__
108
-            );
109
-            return false;
110
-        }
111
-        return true;
112
-    }
68
+	/**
69
+	 * @param EE_Registration  $registration
70
+	 * @param string           $reg_url_link
71
+	 * @param int|string       $field
72
+	 * @param float|int|string $value
73
+	 * @return bool
74
+	 * @throws EE_Error
75
+	 * @throws ReflectionException
76
+	 */
77
+	public function processFormInput(
78
+		EE_Registration $registration,
79
+		string $reg_url_link,
80
+		$field,
81
+		$value
82
+	): bool {
83
+		// check for critical inputs
84
+		if (! $this->verifyCriticalAttendeeDetailsAreSetAndValidateEmail($field, $value)) {
85
+			echo "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
86
+			return false;
87
+		}
88
+		$value = $this->registrant_data->saveOrCopyPrimaryRegistrantData(
89
+			$reg_url_link,
90
+			$field,
91
+			$value
92
+		);
93
+		\EEH_Debug_Tools::printr($value, ' value >>====> ', __FILE__, __LINE__);
94
+		if (! $this->saveRegistrationFormInput($registration, $reg_url_link, $field, $value)) {
95
+			EE_Error::add_error(
96
+				sprintf(
97
+					esc_html_x(
98
+						'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
99
+						'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"',
100
+						'event_espresso'
101
+					),
102
+					$field,
103
+					$value
104
+				),
105
+				__FILE__,
106
+				__FUNCTION__,
107
+				__LINE__
108
+			);
109
+			return false;
110
+		}
111
+		return true;
112
+	}
113 113
 
114 114
 
115
-    /**
116
-     * @param EE_Registration  $registration
117
-     * @param string           $reg_url_link
118
-     * @param int|string       $field the form input name
119
-     * @param float|int|string $value the input value
120
-     * @return bool
121
-     * @throws EE_Error
122
-     * @throws InvalidArgumentException
123
-     * @throws InvalidDataTypeException
124
-     * @throws InvalidInterfaceException
125
-     * @throws ReflectionException
126
-     */
127
-    protected function saveRegistrationFormInput(
128
-        EE_Registration $registration,
129
-        string $reg_url_link,
130
-        $field = '',
131
-        $value = ''
132
-    ): bool {
133
-        if ($this->bypassSaveRegFormInputValue($registration, $field, $value)) {
134
-            echo "\n#############################################################\n";
135
-            return true;
136
-        }
137
-        /*
115
+	/**
116
+	 * @param EE_Registration  $registration
117
+	 * @param string           $reg_url_link
118
+	 * @param int|string       $field the form input name
119
+	 * @param float|int|string $value the input value
120
+	 * @return bool
121
+	 * @throws EE_Error
122
+	 * @throws InvalidArgumentException
123
+	 * @throws InvalidDataTypeException
124
+	 * @throws InvalidInterfaceException
125
+	 * @throws ReflectionException
126
+	 */
127
+	protected function saveRegistrationFormInput(
128
+		EE_Registration $registration,
129
+		string $reg_url_link,
130
+		$field = '',
131
+		$value = ''
132
+	): bool {
133
+		if ($this->bypassSaveRegFormInputValue($registration, $field, $value)) {
134
+			echo "\n#############################################################\n";
135
+			return true;
136
+		}
137
+		/*
138 138
          * $answer_cache_id is the key used to find the EE_Answer we want
139 139
          * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
140 140
          */
141
-        $answer_cache_id   = $this->checkout_reg_url_link
142
-            ? $field . '-' . $reg_url_link
143
-            : $field;
144
-        $registrant_answer = $this->registrant_data->getRegistrantAnswer($reg_url_link, $answer_cache_id);
145
-        $answer_is_obj     = $registrant_answer instanceof EE_Answer;
146
-        // if this form input has a corresponding attendee property
147
-        if ($this->isAttendeeProperty($field)) {
148
-            $this->saveAttendeeProperty($registration, $reg_url_link, $field, $value, $registrant_answer);
149
-            return true;
150
-        }
151
-        if ($answer_is_obj) {
152
-            // save this data to the answer object
153
-            $registrant_answer->set_value($value);
154
-            $result = $registrant_answer->save();
155
-            return $result !== false;
156
-        }
157
-        foreach ($this->registrant_data->registrantAnswers($reg_url_link) as $answer) {
158
-            if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) {
159
-                $answer->set_value($value);
160
-                $result = $answer->save();
161
-                return $result !== false;
162
-            }
163
-        }
164
-        return false;
165
-    }
141
+		$answer_cache_id   = $this->checkout_reg_url_link
142
+			? $field . '-' . $reg_url_link
143
+			: $field;
144
+		$registrant_answer = $this->registrant_data->getRegistrantAnswer($reg_url_link, $answer_cache_id);
145
+		$answer_is_obj     = $registrant_answer instanceof EE_Answer;
146
+		// if this form input has a corresponding attendee property
147
+		if ($this->isAttendeeProperty($field)) {
148
+			$this->saveAttendeeProperty($registration, $reg_url_link, $field, $value, $registrant_answer);
149
+			return true;
150
+		}
151
+		if ($answer_is_obj) {
152
+			// save this data to the answer object
153
+			$registrant_answer->set_value($value);
154
+			$result = $registrant_answer->save();
155
+			return $result !== false;
156
+		}
157
+		foreach ($this->registrant_data->registrantAnswers($reg_url_link) as $answer) {
158
+			if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) {
159
+				$answer->set_value($value);
160
+				$result = $answer->save();
161
+				return $result !== false;
162
+			}
163
+		}
164
+		return false;
165
+	}
166 166
 
167 167
 
168
-    /**
169
-     * @param EE_Registration $registration
170
-     * @param string          $field
171
-     * @param mixed           $value
172
-     * @return bool
173
-     */
174
-    protected function bypassSaveRegFormInputValue(EE_Registration $registration, string $field, $value): bool
175
-    {
176
-        // fields like the "email confirmation" input are sent, but not saved
177
-        if (in_array($field, $this->non_persistable_fields, true)) {
178
-            return true;
179
-        }
180
-        // allow for plugins to hook in and do their own processing of the form input.
181
-        // For plugins to bypass normal processing here, they just need to return a truthy value.
182
-        // NOTE: this hook does the opposite of what its name implies...
183
-        // ie: returning true does NOT save the input here, meaning it needs to be saved externally.
184
-        // This should have been named something like  "bypass_save_registration_form_input"
185
-        return filter_var(
186
-            apply_filters(
187
-                'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
188
-                false,
189
-                $registration,
190
-                $field,
191
-                $value,
192
-                $this
193
-            ),
194
-            FILTER_VALIDATE_BOOLEAN
195
-        );
196
-    }
168
+	/**
169
+	 * @param EE_Registration $registration
170
+	 * @param string          $field
171
+	 * @param mixed           $value
172
+	 * @return bool
173
+	 */
174
+	protected function bypassSaveRegFormInputValue(EE_Registration $registration, string $field, $value): bool
175
+	{
176
+		// fields like the "email confirmation" input are sent, but not saved
177
+		if (in_array($field, $this->non_persistable_fields, true)) {
178
+			return true;
179
+		}
180
+		// allow for plugins to hook in and do their own processing of the form input.
181
+		// For plugins to bypass normal processing here, they just need to return a truthy value.
182
+		// NOTE: this hook does the opposite of what its name implies...
183
+		// ie: returning true does NOT save the input here, meaning it needs to be saved externally.
184
+		// This should have been named something like  "bypass_save_registration_form_input"
185
+		return filter_var(
186
+			apply_filters(
187
+				'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
188
+				false,
189
+				$registration,
190
+				$field,
191
+				$value,
192
+				$this
193
+			),
194
+			FILTER_VALIDATE_BOOLEAN
195
+		);
196
+	}
197 197
 
198 198
 
199
-    /**
200
-     * @param string $field
201
-     * @return bool
202
-     */
203
-    private function isAttendeeProperty(string $field): bool
204
-    {
205
-        // \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
206
-        // \EEH_Debug_Tools::printr($field, '$field', __FILE__, __LINE__);
207
-        switch ($field) {
208
-            case 'state':
209
-            case 'STA_ID':
210
-            case 'country':
211
-            case 'CNT_ISO':
212
-                return true;
213
-            default:
214
-                return $this->attendee_model->has_field("ATT_$field");
215
-        }
216
-    }
199
+	/**
200
+	 * @param string $field
201
+	 * @return bool
202
+	 */
203
+	private function isAttendeeProperty(string $field): bool
204
+	{
205
+		// \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
206
+		// \EEH_Debug_Tools::printr($field, '$field', __FILE__, __LINE__);
207
+		switch ($field) {
208
+			case 'state':
209
+			case 'STA_ID':
210
+			case 'country':
211
+			case 'CNT_ISO':
212
+				return true;
213
+			default:
214
+				return $this->attendee_model->has_field("ATT_$field");
215
+		}
216
+	}
217 217
 
218 218
 
219
-    /**
220
-     * @param string $field
221
-     * @return string
222
-     */
223
-    protected function renameFormInput(string $field): string
224
-    {
225
-        switch ($field) {
226
-            case 'state':
227
-            case 'STA_ID':
228
-                return 'STA_ID';
219
+	/**
220
+	 * @param string $field
221
+	 * @return string
222
+	 */
223
+	protected function renameFormInput(string $field): string
224
+	{
225
+		switch ($field) {
226
+			case 'state':
227
+			case 'STA_ID':
228
+				return 'STA_ID';
229 229
 
230
-            case 'country':
231
-            case 'CNT_ISO':
232
-                return 'CNT_ISO';
230
+			case 'country':
231
+			case 'CNT_ISO':
232
+				return 'CNT_ISO';
233 233
 
234
-            default:
235
-                return "ATT_$field";
236
-        }
237
-    }
234
+			default:
235
+				return "ATT_$field";
236
+		}
237
+	}
238 238
 
239 239
 
240
-    /**
241
-     * @param EE_Registration $registration
242
-     * @param string          $reg_url_link
243
-     * @param string          $field
244
-     * @param                 $value
245
-     * @param                 $registrant_answer
246
-     * @throws EE_Error
247
-     * @throws ReflectionException
248
-     */
249
-    protected function saveAttendeeProperty(
250
-        EE_Registration $registration,
251
-        string $reg_url_link,
252
-        string $field,
253
-        $value,
254
-        $registrant_answer
255
-    ) {
256
-        // rename form_inputs if they are EE_Attendee properties
257
-        $field = $this->renameFormInput($field);
258
-        $this->registrant_data->addRegistrantDataValue($reg_url_link, $field, $value);
259
-        if ($registrant_answer instanceof EE_Answer) {
260
-            // and delete the corresponding answer since we won't be storing this data in that object
261
-            $registration->_remove_relation_to($registrant_answer, 'Answer');
262
-            $registrant_answer->delete_permanently();
263
-        }
264
-    }
240
+	/**
241
+	 * @param EE_Registration $registration
242
+	 * @param string          $reg_url_link
243
+	 * @param string          $field
244
+	 * @param                 $value
245
+	 * @param                 $registrant_answer
246
+	 * @throws EE_Error
247
+	 * @throws ReflectionException
248
+	 */
249
+	protected function saveAttendeeProperty(
250
+		EE_Registration $registration,
251
+		string $reg_url_link,
252
+		string $field,
253
+		$value,
254
+		$registrant_answer
255
+	) {
256
+		// rename form_inputs if they are EE_Attendee properties
257
+		$field = $this->renameFormInput($field);
258
+		$this->registrant_data->addRegistrantDataValue($reg_url_link, $field, $value);
259
+		if ($registrant_answer instanceof EE_Answer) {
260
+			// and delete the corresponding answer since we won't be storing this data in that object
261
+			$registration->_remove_relation_to($registrant_answer, 'Answer');
262
+			$registrant_answer->delete_permanently();
263
+		}
264
+	}
265 265
 
266 266
 
267
-    /**
268
-     * @param int|string       $form_input
269
-     * @param float|int|string $input_value
270
-     * @return boolean
271
-     */
272
-    private function verifyCriticalAttendeeDetailsAreSetAndValidateEmail(
273
-        $form_input = '',
274
-        $input_value = ''
275
-    ): bool {
276
-        if (empty($input_value)) {
277
-            // if the form input isn't marked as being required, then just return
278
-            if (! isset($this->required_questions[ $form_input ]) || ! $this->required_questions[ $form_input ]) {
279
-                return true;
280
-            }
281
-            switch ($form_input) {
282
-                case 'fname':
283
-                    EE_Error::add_error(
284
-                        esc_html__('First Name is a required value.', 'event_espresso'),
285
-                        __FILE__,
286
-                        __FUNCTION__,
287
-                        __LINE__
288
-                    );
289
-                    return false;
290
-                case 'lname':
291
-                    EE_Error::add_error(
292
-                        esc_html__('Last Name is a required value.', 'event_espresso'),
293
-                        __FILE__,
294
-                        __FUNCTION__,
295
-                        __LINE__
296
-                    );
297
-                    return false;
298
-                case 'email':
299
-                    EE_Error::add_error(
300
-                        esc_html__('Please enter a valid email address.', 'event_espresso'),
301
-                        __FILE__,
302
-                        __FUNCTION__,
303
-                        __LINE__
304
-                    );
305
-                    return false;
306
-            }
307
-        }
308
-        return true;
309
-    }
267
+	/**
268
+	 * @param int|string       $form_input
269
+	 * @param float|int|string $input_value
270
+	 * @return boolean
271
+	 */
272
+	private function verifyCriticalAttendeeDetailsAreSetAndValidateEmail(
273
+		$form_input = '',
274
+		$input_value = ''
275
+	): bool {
276
+		if (empty($input_value)) {
277
+			// if the form input isn't marked as being required, then just return
278
+			if (! isset($this->required_questions[ $form_input ]) || ! $this->required_questions[ $form_input ]) {
279
+				return true;
280
+			}
281
+			switch ($form_input) {
282
+				case 'fname':
283
+					EE_Error::add_error(
284
+						esc_html__('First Name is a required value.', 'event_espresso'),
285
+						__FILE__,
286
+						__FUNCTION__,
287
+						__LINE__
288
+					);
289
+					return false;
290
+				case 'lname':
291
+					EE_Error::add_error(
292
+						esc_html__('Last Name is a required value.', 'event_espresso'),
293
+						__FILE__,
294
+						__FUNCTION__,
295
+						__LINE__
296
+					);
297
+					return false;
298
+				case 'email':
299
+					EE_Error::add_error(
300
+						esc_html__('Please enter a valid email address.', 'event_espresso'),
301
+						__FILE__,
302
+						__FUNCTION__,
303
+						__LINE__
304
+					);
305
+					return false;
306
+			}
307
+		}
308
+		return true;
309
+	}
310 310
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
         $value
82 82
     ): bool {
83 83
         // check for critical inputs
84
-        if (! $this->verifyCriticalAttendeeDetailsAreSetAndValidateEmail($field, $value)) {
84
+        if ( ! $this->verifyCriticalAttendeeDetailsAreSetAndValidateEmail($field, $value)) {
85 85
             echo "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
86 86
             return false;
87 87
         }
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
             $value
92 92
         );
93 93
         \EEH_Debug_Tools::printr($value, ' value >>====> ', __FILE__, __LINE__);
94
-        if (! $this->saveRegistrationFormInput($registration, $reg_url_link, $field, $value)) {
94
+        if ( ! $this->saveRegistrationFormInput($registration, $reg_url_link, $field, $value)) {
95 95
             EE_Error::add_error(
96 96
                 sprintf(
97 97
                     esc_html_x(
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
          * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
140 140
          */
141 141
         $answer_cache_id   = $this->checkout_reg_url_link
142
-            ? $field . '-' . $reg_url_link
142
+            ? $field.'-'.$reg_url_link
143 143
             : $field;
144 144
         $registrant_answer = $this->registrant_data->getRegistrantAnswer($reg_url_link, $answer_cache_id);
145 145
         $answer_is_obj     = $registrant_answer instanceof EE_Answer;
@@ -275,7 +275,7 @@  discard block
 block discarded – undo
275 275
     ): bool {
276 276
         if (empty($input_value)) {
277 277
             // if the form input isn't marked as being required, then just return
278
-            if (! isset($this->required_questions[ $form_input ]) || ! $this->required_questions[ $form_input ]) {
278
+            if ( ! isset($this->required_questions[$form_input]) || ! $this->required_questions[$form_input]) {
279 279
                 return true;
280 280
             }
281 281
             switch ($form_input) {
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegistrantForm.php 2 patches
Indentation   +91 added lines, -91 removed lines patch added patch discarded remove patch
@@ -14,101 +14,101 @@
 block discarded – undo
14 14
 class RegistrantForm extends BaseRegistrantForm
15 15
 {
16 16
 
17
-    /**
18
-     * @var EEM_Event_Question_Group
19
-     */
20
-    public $event_question_group_model;
17
+	/**
18
+	 * @var EEM_Event_Question_Group
19
+	 */
20
+	public $event_question_group_model;
21 21
 
22 22
 
23
-    /**
24
-     * RegistrantForm constructor.
25
-     *
26
-     * @param EE_Registration          $registration
27
-     * @param bool                     $admin_request
28
-     * @param bool                     $copy_attendee_info
29
-     * @param callable                 $enablePrintCopyInfo
30
-     * @param EEM_Event_Question_Group $event_question_group_model
31
-     * @throws EE_Error
32
-     * @throws ReflectionException
33
-     */
34
-    public function __construct(
35
-        EE_Registration $registration,
36
-        bool $admin_request,
37
-        bool $copy_attendee_info,
38
-        callable $enablePrintCopyInfo,
39
-        EEM_Event_Question_Group $event_question_group_model
40
-    ) {
41
-        $this->event_question_group_model = $event_question_group_model;
42
-        parent::__construct(
43
-            $this->generateFormArgs($registration, $admin_request, $copy_attendee_info, $enablePrintCopyInfo)
44
-        );
45
-    }
23
+	/**
24
+	 * RegistrantForm constructor.
25
+	 *
26
+	 * @param EE_Registration          $registration
27
+	 * @param bool                     $admin_request
28
+	 * @param bool                     $copy_attendee_info
29
+	 * @param callable                 $enablePrintCopyInfo
30
+	 * @param EEM_Event_Question_Group $event_question_group_model
31
+	 * @throws EE_Error
32
+	 * @throws ReflectionException
33
+	 */
34
+	public function __construct(
35
+		EE_Registration $registration,
36
+		bool $admin_request,
37
+		bool $copy_attendee_info,
38
+		callable $enablePrintCopyInfo,
39
+		EEM_Event_Question_Group $event_question_group_model
40
+	) {
41
+		$this->event_question_group_model = $event_question_group_model;
42
+		parent::__construct(
43
+			$this->generateFormArgs($registration, $admin_request, $copy_attendee_info, $enablePrintCopyInfo)
44
+		);
45
+	}
46 46
 
47 47
 
48
-    /**
49
-     * @param EE_Registration $registration
50
-     * @param bool            $admin_request
51
-     * @param bool            $copy_attendee_info
52
-     * @param callable        $enablePrintCopyInfo
53
-     * @return array
54
-     * @throws EE_Error
55
-     * @throws ReflectionException
56
-     */
57
-    private function generateFormArgs(
58
-        EE_Registration $registration,
59
-        bool $admin_request,
60
-        bool $copy_attendee_info,
61
-        callable $enablePrintCopyInfo
62
-    ): array {
63
-        static $attendee_nmbr = 1;
64
-        // verify that registration has valid event
65
-        if ($registration->event() instanceof EE_Event) {
66
-            $field_name      = 'Event_Question_Group.' . $this->event_question_group_model->fieldNameForContext(
67
-                    $registration->is_primary_registrant()
68
-                );
69
-            $question_groups = $registration->event()->question_groups(
70
-                apply_filters(
71
-                // @codingStandardsIgnoreStart
72
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
73
-                    // @codingStandardsIgnoreEnd
74
-                    [
75
-                        [
76
-                            'Event.EVT_ID' => $registration->event()->ID(),
77
-                            $field_name    => true,
78
-                        ],
79
-                        'order_by' => ['QSG_order' => 'ASC'],
80
-                    ],
81
-                    $registration,
82
-                    $this
83
-                )
84
-            );
85
-            if ($question_groups) {
86
-                // array of params to pass to parent constructor
87
-                $this->form_args = $this->generateTopLevelFormArgs($registration, $admin_request, $attendee_nmbr);
88
-                foreach ($question_groups as $question_group) {
89
-                    if ($question_group instanceof EE_Question_Group) {
90
-                        $question_group_reg_form                                         = LoaderFactory::getNew(
91
-                            RegFormQuestionGroup::class,
92
-                            [$registration, $question_group, $admin_request]
93
-                        );
94
-                        $this->form_args['subsections'][ $question_group->identifier() ] = apply_filters(
95
-                            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
96
-                            $question_group_reg_form,
97
-                            $registration,
98
-                            $question_group,
99
-                            $this
100
-                        );
101
-                    }
102
-                }
103
-                $this->addAdditionalAttendeeRegInfoInput($registration);
104
-                $this->enablePrintCopyInfo($attendee_nmbr, $copy_attendee_info, $enablePrintCopyInfo);
105
-                $this->addAdditionalPrimaryRegistrantInputs($registration);
106
-            }
107
-        }
108
-        $attendee_nmbr++;
48
+	/**
49
+	 * @param EE_Registration $registration
50
+	 * @param bool            $admin_request
51
+	 * @param bool            $copy_attendee_info
52
+	 * @param callable        $enablePrintCopyInfo
53
+	 * @return array
54
+	 * @throws EE_Error
55
+	 * @throws ReflectionException
56
+	 */
57
+	private function generateFormArgs(
58
+		EE_Registration $registration,
59
+		bool $admin_request,
60
+		bool $copy_attendee_info,
61
+		callable $enablePrintCopyInfo
62
+	): array {
63
+		static $attendee_nmbr = 1;
64
+		// verify that registration has valid event
65
+		if ($registration->event() instanceof EE_Event) {
66
+			$field_name      = 'Event_Question_Group.' . $this->event_question_group_model->fieldNameForContext(
67
+					$registration->is_primary_registrant()
68
+				);
69
+			$question_groups = $registration->event()->question_groups(
70
+				apply_filters(
71
+				// @codingStandardsIgnoreStart
72
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
73
+					// @codingStandardsIgnoreEnd
74
+					[
75
+						[
76
+							'Event.EVT_ID' => $registration->event()->ID(),
77
+							$field_name    => true,
78
+						],
79
+						'order_by' => ['QSG_order' => 'ASC'],
80
+					],
81
+					$registration,
82
+					$this
83
+				)
84
+			);
85
+			if ($question_groups) {
86
+				// array of params to pass to parent constructor
87
+				$this->form_args = $this->generateTopLevelFormArgs($registration, $admin_request, $attendee_nmbr);
88
+				foreach ($question_groups as $question_group) {
89
+					if ($question_group instanceof EE_Question_Group) {
90
+						$question_group_reg_form                                         = LoaderFactory::getNew(
91
+							RegFormQuestionGroup::class,
92
+							[$registration, $question_group, $admin_request]
93
+						);
94
+						$this->form_args['subsections'][ $question_group->identifier() ] = apply_filters(
95
+							'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
96
+							$question_group_reg_form,
97
+							$registration,
98
+							$question_group,
99
+							$this
100
+						);
101
+					}
102
+				}
103
+				$this->addAdditionalAttendeeRegInfoInput($registration);
104
+				$this->enablePrintCopyInfo($attendee_nmbr, $copy_attendee_info, $enablePrintCopyInfo);
105
+				$this->addAdditionalPrimaryRegistrantInputs($registration);
106
+			}
107
+		}
108
+		$attendee_nmbr++;
109 109
 
110
-        $this->setHasQuestions();
110
+		$this->setHasQuestions();
111 111
 
112
-        return $this->form_args;
113
-    }
112
+		return $this->form_args;
113
+	}
114 114
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -63,7 +63,7 @@  discard block
 block discarded – undo
63 63
         static $attendee_nmbr = 1;
64 64
         // verify that registration has valid event
65 65
         if ($registration->event() instanceof EE_Event) {
66
-            $field_name      = 'Event_Question_Group.' . $this->event_question_group_model->fieldNameForContext(
66
+            $field_name      = 'Event_Question_Group.'.$this->event_question_group_model->fieldNameForContext(
67 67
                     $registration->is_primary_registrant()
68 68
                 );
69 69
             $question_groups = $registration->event()->question_groups(
@@ -87,11 +87,11 @@  discard block
 block discarded – undo
87 87
                 $this->form_args = $this->generateTopLevelFormArgs($registration, $admin_request, $attendee_nmbr);
88 88
                 foreach ($question_groups as $question_group) {
89 89
                     if ($question_group instanceof EE_Question_Group) {
90
-                        $question_group_reg_form                                         = LoaderFactory::getNew(
90
+                        $question_group_reg_form = LoaderFactory::getNew(
91 91
                             RegFormQuestionGroup::class,
92 92
                             [$registration, $question_group, $admin_request]
93 93
                         );
94
-                        $this->form_args['subsections'][ $question_group->identifier() ] = apply_filters(
94
+                        $this->form_args['subsections'][$question_group->identifier()] = apply_filters(
95 95
                             'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
96 96
                             $question_group_reg_form,
97 97
                             $registration,
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/SystemInputFieldNames.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -17,36 +17,36 @@
 block discarded – undo
17 17
 class SystemInputFieldNames implements SystemInputFieldNamesInterface
18 18
 {
19 19
 
20
-    /**
21
-     * @param string $field
22
-     * @return string
23
-     */
24
-    public function getInputName(string $field): string
25
-    {
26
-        switch ($field) {
27
-            case SystemInputFieldNamesInterface::FIRST_NAME:
28
-                return EEM_Attendee::system_question_fname;
29
-            case SystemInputFieldNamesInterface::LAST_NAME:
30
-                return EEM_Attendee::system_question_lname;
31
-            case SystemInputFieldNamesInterface::EMAIL:
32
-                return EEM_Attendee::system_question_email;
33
-            case SystemInputFieldNamesInterface::EMAIL_CONFIRM:
34
-                return EEM_Attendee::system_question_email_confirm;
35
-            case SystemInputFieldNamesInterface::ADDRESS:
36
-                return EEM_Attendee::system_question_address;
37
-            case SystemInputFieldNamesInterface::ADDRESS_2:
38
-                return EEM_Attendee::system_question_address2;
39
-            case SystemInputFieldNamesInterface::CITY:
40
-                return EEM_Attendee::system_question_city;
41
-            case SystemInputFieldNamesInterface::STATE:
42
-                return EEM_Attendee::system_question_state;
43
-            case SystemInputFieldNamesInterface::COUNTRY:
44
-                return EEM_Attendee::system_question_country;
45
-            case SystemInputFieldNamesInterface::POSTAL_CODE:
46
-                return EEM_Attendee::system_question_zip;
47
-            case SystemInputFieldNamesInterface::PHONE:
48
-                return EEM_Attendee::system_question_phone;
49
-        }
50
-        return $field;
51
-    }
20
+	/**
21
+	 * @param string $field
22
+	 * @return string
23
+	 */
24
+	public function getInputName(string $field): string
25
+	{
26
+		switch ($field) {
27
+			case SystemInputFieldNamesInterface::FIRST_NAME:
28
+				return EEM_Attendee::system_question_fname;
29
+			case SystemInputFieldNamesInterface::LAST_NAME:
30
+				return EEM_Attendee::system_question_lname;
31
+			case SystemInputFieldNamesInterface::EMAIL:
32
+				return EEM_Attendee::system_question_email;
33
+			case SystemInputFieldNamesInterface::EMAIL_CONFIRM:
34
+				return EEM_Attendee::system_question_email_confirm;
35
+			case SystemInputFieldNamesInterface::ADDRESS:
36
+				return EEM_Attendee::system_question_address;
37
+			case SystemInputFieldNamesInterface::ADDRESS_2:
38
+				return EEM_Attendee::system_question_address2;
39
+			case SystemInputFieldNamesInterface::CITY:
40
+				return EEM_Attendee::system_question_city;
41
+			case SystemInputFieldNamesInterface::STATE:
42
+				return EEM_Attendee::system_question_state;
43
+			case SystemInputFieldNamesInterface::COUNTRY:
44
+				return EEM_Attendee::system_question_country;
45
+			case SystemInputFieldNamesInterface::POSTAL_CODE:
46
+				return EEM_Attendee::system_question_zip;
47
+			case SystemInputFieldNamesInterface::PHONE:
48
+				return EEM_Attendee::system_question_phone;
49
+		}
50
+		return $field;
51
+	}
52 52
 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegFormDependencyHandler.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -7,63 +7,63 @@
 block discarded – undo
7 7
 
8 8
 class RegFormDependencyHandler extends DependencyHandler
9 9
 {
10
-    /**
11
-     * @return void
12
-     */
13
-    public function registerDependencies()
14
-    {
15
-        $reg_form_dependencies = [
16
-            'EventEspresso\core\domain\services\registration\form\v1\RegForm'                  => [
17
-                null,
18
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
19
-            ],
20
-            'EventEspresso\core\domain\services\registration\form\v1\RegistrantForm'           => [
21
-                null,
22
-                null,
23
-                null,
24
-                null,
25
-                'EEM_Event_Question_Group' => EE_Dependency_Map::load_from_cache,
26
-            ],
27
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory'   => [
28
-                null,
29
-                'EEM_Answer' => EE_Dependency_Map::load_from_cache,
30
-            ],
31
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionGroup'     => [
32
-                null,
33
-                null,
34
-                null,
35
-                'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory' => EE_Dependency_Map::load_from_cache,
36
-            ],
37
-            'EventEspresso\core\domain\services\registration\form\base\CountryOptions'         => [
38
-                null,
39
-                'EEM_Answer'  => EE_Dependency_Map::load_from_cache,
40
-                'EEM_Country' => EE_Dependency_Map::load_from_cache,
41
-            ],
42
-            'EventEspresso\core\domain\services\registration\form\base\StateOptions'           => [
43
-                null,
44
-                'EEM_State' => EE_Dependency_Map::load_from_cache,
45
-            ],
46
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormHandler'           => [
47
-                null,
48
-                'EventEspresso\core\domain\services\registration\form\base\RegistrantData'         => EE_Dependency_Map::load_from_cache,
49
-                'EE_Form_Section_Proper'                                                           => EE_Dependency_Map::load_from_cache,
50
-                'EventEspresso\core\domain\services\registration\form\base\RegFormAttendeeFactory' => EE_Dependency_Map::load_from_cache,
51
-                'EE_Registration_Processor'                                                        => EE_Dependency_Map::load_from_cache,
52
-            ],
53
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormInputHandler'      => [
54
-                null,
55
-                null,
56
-                'EEM_Attendee'                                                                  => EE_Dependency_Map::load_from_cache,
57
-                'EventEspresso\core\domain\services\registration\form\base\RegistrantData'      => EE_Dependency_Map::load_from_cache,
58
-                'EventEspresso\core\domain\services\registration\form\v1\SystemInputFieldNames' => EE_Dependency_Map::load_from_cache,
59
-            ],
60
-            'EventEspresso\core\domain\services\registration\form\base\RegFormAttendeeFactory' => [
61
-                'EventEspresso\core\services\commands\CommandBus'                          => EE_Dependency_Map::load_from_cache,
62
-                'EventEspresso\core\domain\services\registration\form\base\RegistrantData' => EE_Dependency_Map::load_from_cache,
63
-            ],
64
-        ];
65
-        foreach ($reg_form_dependencies as $class => $dependencies) {
66
-            $this->dependency_map->registerDependencies($class, $dependencies);
67
-        }
68
-    }
10
+	/**
11
+	 * @return void
12
+	 */
13
+	public function registerDependencies()
14
+	{
15
+		$reg_form_dependencies = [
16
+			'EventEspresso\core\domain\services\registration\form\v1\RegForm'                  => [
17
+				null,
18
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
19
+			],
20
+			'EventEspresso\core\domain\services\registration\form\v1\RegistrantForm'           => [
21
+				null,
22
+				null,
23
+				null,
24
+				null,
25
+				'EEM_Event_Question_Group' => EE_Dependency_Map::load_from_cache,
26
+			],
27
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory'   => [
28
+				null,
29
+				'EEM_Answer' => EE_Dependency_Map::load_from_cache,
30
+			],
31
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionGroup'     => [
32
+				null,
33
+				null,
34
+				null,
35
+				'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory' => EE_Dependency_Map::load_from_cache,
36
+			],
37
+			'EventEspresso\core\domain\services\registration\form\base\CountryOptions'         => [
38
+				null,
39
+				'EEM_Answer'  => EE_Dependency_Map::load_from_cache,
40
+				'EEM_Country' => EE_Dependency_Map::load_from_cache,
41
+			],
42
+			'EventEspresso\core\domain\services\registration\form\base\StateOptions'           => [
43
+				null,
44
+				'EEM_State' => EE_Dependency_Map::load_from_cache,
45
+			],
46
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormHandler'           => [
47
+				null,
48
+				'EventEspresso\core\domain\services\registration\form\base\RegistrantData'         => EE_Dependency_Map::load_from_cache,
49
+				'EE_Form_Section_Proper'                                                           => EE_Dependency_Map::load_from_cache,
50
+				'EventEspresso\core\domain\services\registration\form\base\RegFormAttendeeFactory' => EE_Dependency_Map::load_from_cache,
51
+				'EE_Registration_Processor'                                                        => EE_Dependency_Map::load_from_cache,
52
+			],
53
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormInputHandler'      => [
54
+				null,
55
+				null,
56
+				'EEM_Attendee'                                                                  => EE_Dependency_Map::load_from_cache,
57
+				'EventEspresso\core\domain\services\registration\form\base\RegistrantData'      => EE_Dependency_Map::load_from_cache,
58
+				'EventEspresso\core\domain\services\registration\form\v1\SystemInputFieldNames' => EE_Dependency_Map::load_from_cache,
59
+			],
60
+			'EventEspresso\core\domain\services\registration\form\base\RegFormAttendeeFactory' => [
61
+				'EventEspresso\core\services\commands\CommandBus'                          => EE_Dependency_Map::load_from_cache,
62
+				'EventEspresso\core\domain\services\registration\form\base\RegistrantData' => EE_Dependency_Map::load_from_cache,
63
+			],
64
+		];
65
+		foreach ($reg_form_dependencies as $class => $dependencies) {
66
+			$this->dependency_map->registerDependencies($class, $dependencies);
67
+		}
68
+	}
69 69
 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegFormHandler.php 2 patches
Indentation   +76 added lines, -76 removed lines patch added patch discarded remove patch
@@ -16,86 +16,86 @@
 block discarded – undo
16 16
 class RegFormHandler extends RegFormHandlerBase
17 17
 {
18 18
 
19
-    /**
20
-     * @var RegFormInputHandler
21
-     */
22
-    public $input_handler;
19
+	/**
20
+	 * @var RegFormInputHandler
21
+	 */
22
+	public $input_handler;
23 23
 
24 24
 
25
-    /**
26
-     * RegFormHandler constructor.
27
-     */
28
-    public function __construct(
29
-        EE_Checkout $checkout,
30
-        RegistrantData $registrant_data,
31
-        EE_Form_Section_Proper $reg_form,
32
-        RegFormAttendeeFactory $attendee_factory,
33
-        EE_Registration_Processor $registration_processor
34
-    ) {
35
-        parent::__construct($checkout, $registrant_data, $reg_form, $attendee_factory, $registration_processor);
36
-    }
25
+	/**
26
+	 * RegFormHandler constructor.
27
+	 */
28
+	public function __construct(
29
+		EE_Checkout $checkout,
30
+		RegistrantData $registrant_data,
31
+		EE_Form_Section_Proper $reg_form,
32
+		RegFormAttendeeFactory $attendee_factory,
33
+		EE_Registration_Processor $registration_processor
34
+	) {
35
+		parent::__construct($checkout, $registrant_data, $reg_form, $attendee_factory, $registration_processor);
36
+	}
37 37
 
38 38
 
39
-    /**
40
-     * @return void
41
-     */
42
-    public function initializeInputHandler()
43
-    {
44
-        $reg_form            = $this->checkout->current_step->reg_form;
45
-        $required_questions  = $reg_form instanceof RegForm ? $reg_form->requiredQuestions() : [];
46
-        $this->input_handler = LoaderFactory::getShared(
47
-            RegFormInputHandler::class,
48
-            [$this->checkout->reg_url_link, $required_questions]
49
-        );
50
-    }
39
+	/**
40
+	 * @return void
41
+	 */
42
+	public function initializeInputHandler()
43
+	{
44
+		$reg_form            = $this->checkout->current_step->reg_form;
45
+		$required_questions  = $reg_form instanceof RegForm ? $reg_form->requiredQuestions() : [];
46
+		$this->input_handler = LoaderFactory::getShared(
47
+			RegFormInputHandler::class,
48
+			[$this->checkout->reg_url_link, $required_questions]
49
+		);
50
+	}
51 51
 
52 52
 
53
-    /**
54
-     * @param EE_Registration $registration
55
-     * @param string          $reg_url_link
56
-     * @param array           $reg_form_data
57
-     * @return bool
58
-     * @throws EE_Error
59
-     * @throws ReflectionException
60
-     */
61
-    protected function processRegFormData(
62
-        EE_Registration $registration,
63
-        string $reg_url_link,
64
-        array $reg_form_data
65
-    ): bool {
66
-        if (isset($reg_form_data[ $reg_url_link ])) {
67
-            // do we need to copy basic info from primary attendee ?
68
-            $copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
69
-                            && absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
70
-            $this->registrant_data->setCopyPrimary($copy_primary);
71
-            // filter form input data for this registration
72
-            $reg_form_data[ $reg_url_link ] = (array) apply_filters(
73
-                'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
74
-                $reg_form_data[ $reg_url_link ]
75
-            );
76
-            if (isset($reg_form_data['primary_attendee'])) {
77
-                $primary_reg_url_link = $reg_form_data['primary_attendee'] ?? '';
78
-                $this->registrant_data->addPrimaryRegistrantDataValue('reg_url_link', $primary_reg_url_link);
79
-                unset($reg_form_data['primary_attendee']);
80
-            }
81
-            // now loop through our array of valid post data && process attendee reg forms
82
-            foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
83
-                if (in_array($form_section, $this->non_input_form_sections, true)) {
84
-                    continue;
85
-                }
86
-                foreach ($form_inputs as $form_input => $input_value) {
87
-                    $input_processed = $this->input_handler->processFormInput(
88
-                        $registration,
89
-                        $reg_url_link,
90
-                        $form_input,
91
-                        $input_value
92
-                    );
93
-                    if (! $input_processed) {
94
-                        return false;
95
-                    }
96
-                }
97
-            }
98
-        }
99
-        return true;
100
-    }
53
+	/**
54
+	 * @param EE_Registration $registration
55
+	 * @param string          $reg_url_link
56
+	 * @param array           $reg_form_data
57
+	 * @return bool
58
+	 * @throws EE_Error
59
+	 * @throws ReflectionException
60
+	 */
61
+	protected function processRegFormData(
62
+		EE_Registration $registration,
63
+		string $reg_url_link,
64
+		array $reg_form_data
65
+	): bool {
66
+		if (isset($reg_form_data[ $reg_url_link ])) {
67
+			// do we need to copy basic info from primary attendee ?
68
+			$copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
69
+							&& absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
70
+			$this->registrant_data->setCopyPrimary($copy_primary);
71
+			// filter form input data for this registration
72
+			$reg_form_data[ $reg_url_link ] = (array) apply_filters(
73
+				'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
74
+				$reg_form_data[ $reg_url_link ]
75
+			);
76
+			if (isset($reg_form_data['primary_attendee'])) {
77
+				$primary_reg_url_link = $reg_form_data['primary_attendee'] ?? '';
78
+				$this->registrant_data->addPrimaryRegistrantDataValue('reg_url_link', $primary_reg_url_link);
79
+				unset($reg_form_data['primary_attendee']);
80
+			}
81
+			// now loop through our array of valid post data && process attendee reg forms
82
+			foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
83
+				if (in_array($form_section, $this->non_input_form_sections, true)) {
84
+					continue;
85
+				}
86
+				foreach ($form_inputs as $form_input => $input_value) {
87
+					$input_processed = $this->input_handler->processFormInput(
88
+						$registration,
89
+						$reg_url_link,
90
+						$form_input,
91
+						$input_value
92
+					);
93
+					if (! $input_processed) {
94
+						return false;
95
+					}
96
+				}
97
+			}
98
+		}
99
+		return true;
100
+	}
101 101
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -63,15 +63,15 @@  discard block
 block discarded – undo
63 63
         string $reg_url_link,
64 64
         array $reg_form_data
65 65
     ): bool {
66
-        if (isset($reg_form_data[ $reg_url_link ])) {
66
+        if (isset($reg_form_data[$reg_url_link])) {
67 67
             // do we need to copy basic info from primary attendee ?
68
-            $copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
69
-                            && absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
68
+            $copy_primary = isset($reg_form_data[$reg_url_link]['additional_attendee_reg_info'])
69
+                            && absint($reg_form_data[$reg_url_link]['additional_attendee_reg_info']) === 0;
70 70
             $this->registrant_data->setCopyPrimary($copy_primary);
71 71
             // filter form input data for this registration
72
-            $reg_form_data[ $reg_url_link ] = (array) apply_filters(
72
+            $reg_form_data[$reg_url_link] = (array) apply_filters(
73 73
                 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
74
-                $reg_form_data[ $reg_url_link ]
74
+                $reg_form_data[$reg_url_link]
75 75
             );
76 76
             if (isset($reg_form_data['primary_attendee'])) {
77 77
                 $primary_reg_url_link = $reg_form_data['primary_attendee'] ?? '';
@@ -79,7 +79,7 @@  discard block
 block discarded – undo
79 79
                 unset($reg_form_data['primary_attendee']);
80 80
             }
81 81
             // now loop through our array of valid post data && process attendee reg forms
82
-            foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
82
+            foreach ($reg_form_data[$reg_url_link] as $form_section => $form_inputs) {
83 83
                 if (in_array($form_section, $this->non_input_form_sections, true)) {
84 84
                     continue;
85 85
                 }
@@ -90,7 +90,7 @@  discard block
 block discarded – undo
90 90
                         $form_input,
91 91
                         $input_value
92 92
                     );
93
-                    if (! $input_processed) {
93
+                    if ( ! $input_processed) {
94 94
                         return false;
95 95
                     }
96 96
                 }
Please login to merge, or discard this patch.
core/domain/values/session/SessionLifespan.php 1 patch
Indentation   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -20,98 +20,98 @@
 block discarded – undo
20 20
 class SessionLifespan
21 21
 {
22 22
 
23
-    /**
24
-     * how long an EE session lasts in seconds
25
-     * default session lifespan of 1 hour (for not so instant IPNs)
26
-     *
27
-     * @var int $lifespan
28
-     */
29
-    private $lifespan;
30
-
31
-
32
-    /**
33
-     * SessionLifespan constructor.
34
-     *
35
-     * @param int $lifespan
36
-     * @throws DomainException
37
-     */
38
-    public function __construct(int $lifespan = DAY_IN_SECONDS)
39
-    {
40
-        $lifespan = absint($lifespan);
41
-        $lifespan = $lifespan > 0 ? $lifespan : (int) HOUR_IN_SECONDS;
42
-        $this->setLifespan($lifespan);
43
-    }
44
-
45
-
46
-    /**
47
-     * @param int $lifespan
48
-     * @throws DomainException
49
-     */
50
-    protected function setLifespan(int $lifespan)
51
-    {
52
-        if ($lifespan < MINUTE_IN_SECONDS) {
53
-            throw new DomainException(
54
-                esc_html__(
55
-                    'The session lifespan needs to be at least 60 seconds, and even that is extremely short',
56
-                    'event_espresso'
57
-                )
58
-            );
59
-        }
60
-        $this->lifespan = apply_filters(
61
-            'FHEE__EventEspresso_core_domain_values_session_SessionLifespan__setLifespan___lifespan',
62
-            // apply legacy filter for now but add doing it wrong notice in future
63
-            apply_filters(
64
-                'FHEE__EE_Session__construct___lifespan',
65
-                $lifespan
66
-            )
67
-        ) + 1;
68
-    }
69
-
70
-
71
-    /**
72
-     * @return int
73
-     */
74
-    public function inSeconds(): int
75
-    {
76
-        return $this->lifespan;
77
-    }
78
-
79
-
80
-    /**
81
-     * @param string $separator
82
-     * @return string
83
-     */
84
-    public function inHoursMinutesSeconds(string $separator = ':'): string
85
-    {
86
-        return sprintf(
87
-            '%02d%s%02d%s%02d',
88
-            floor($this->lifespan / HOUR_IN_SECONDS),
89
-            $separator,
90
-            ($this->lifespan / MINUTE_IN_SECONDS) % MINUTE_IN_SECONDS,
91
-            $separator,
92
-            $this->lifespan % MINUTE_IN_SECONDS
93
-        );
94
-    }
95
-
96
-
97
-    /**
98
-     * Returns a timestamp for when the session would expire based on this lifespan
99
-     *
100
-     * @param bool $utc If true, displays expiration in UTC
101
-     *                  If false, displays expiration in local time
102
-     * @return int
103
-     */
104
-    public function expiration(bool $utc = true): int
105
-    {
106
-        return (int) current_time('timestamp', $utc) - $this->lifespan;
107
-    }
108
-
109
-
110
-    /**
111
-     * @return string
112
-     */
113
-    public function __toString(): string
114
-    {
115
-        return (string) $this->inSeconds();
116
-    }
23
+	/**
24
+	 * how long an EE session lasts in seconds
25
+	 * default session lifespan of 1 hour (for not so instant IPNs)
26
+	 *
27
+	 * @var int $lifespan
28
+	 */
29
+	private $lifespan;
30
+
31
+
32
+	/**
33
+	 * SessionLifespan constructor.
34
+	 *
35
+	 * @param int $lifespan
36
+	 * @throws DomainException
37
+	 */
38
+	public function __construct(int $lifespan = DAY_IN_SECONDS)
39
+	{
40
+		$lifespan = absint($lifespan);
41
+		$lifespan = $lifespan > 0 ? $lifespan : (int) HOUR_IN_SECONDS;
42
+		$this->setLifespan($lifespan);
43
+	}
44
+
45
+
46
+	/**
47
+	 * @param int $lifespan
48
+	 * @throws DomainException
49
+	 */
50
+	protected function setLifespan(int $lifespan)
51
+	{
52
+		if ($lifespan < MINUTE_IN_SECONDS) {
53
+			throw new DomainException(
54
+				esc_html__(
55
+					'The session lifespan needs to be at least 60 seconds, and even that is extremely short',
56
+					'event_espresso'
57
+				)
58
+			);
59
+		}
60
+		$this->lifespan = apply_filters(
61
+			'FHEE__EventEspresso_core_domain_values_session_SessionLifespan__setLifespan___lifespan',
62
+			// apply legacy filter for now but add doing it wrong notice in future
63
+			apply_filters(
64
+				'FHEE__EE_Session__construct___lifespan',
65
+				$lifespan
66
+			)
67
+		) + 1;
68
+	}
69
+
70
+
71
+	/**
72
+	 * @return int
73
+	 */
74
+	public function inSeconds(): int
75
+	{
76
+		return $this->lifespan;
77
+	}
78
+
79
+
80
+	/**
81
+	 * @param string $separator
82
+	 * @return string
83
+	 */
84
+	public function inHoursMinutesSeconds(string $separator = ':'): string
85
+	{
86
+		return sprintf(
87
+			'%02d%s%02d%s%02d',
88
+			floor($this->lifespan / HOUR_IN_SECONDS),
89
+			$separator,
90
+			($this->lifespan / MINUTE_IN_SECONDS) % MINUTE_IN_SECONDS,
91
+			$separator,
92
+			$this->lifespan % MINUTE_IN_SECONDS
93
+		);
94
+	}
95
+
96
+
97
+	/**
98
+	 * Returns a timestamp for when the session would expire based on this lifespan
99
+	 *
100
+	 * @param bool $utc If true, displays expiration in UTC
101
+	 *                  If false, displays expiration in local time
102
+	 * @return int
103
+	 */
104
+	public function expiration(bool $utc = true): int
105
+	{
106
+		return (int) current_time('timestamp', $utc) - $this->lifespan;
107
+	}
108
+
109
+
110
+	/**
111
+	 * @return string
112
+	 */
113
+	public function __toString(): string
114
+	{
115
+		return (string) $this->inSeconds();
116
+	}
117 117
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/base/EE_Form_Section_Proper.form.php 1 patch
Indentation   +1526 added lines, -1526 removed lines patch added patch discarded remove patch
@@ -15,1530 +15,1530 @@
 block discarded – undo
15 15
 class EE_Form_Section_Proper extends EE_Form_Section_Validatable implements FormSectionProperInterface
16 16
 {
17 17
 
18
-    const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
19
-
20
-    /**
21
-     * Subsections
22
-     *
23
-     * @var EE_Form_Section_Validatable[]
24
-     */
25
-    protected $_subsections = array();
26
-
27
-    /**
28
-     * Strategy for laying out the form
29
-     *
30
-     * @var EE_Form_Section_Layout_Base
31
-     */
32
-    protected $_layout_strategy;
33
-
34
-    /**
35
-     * Whether or not this form has received and validated a form submission yet
36
-     *
37
-     * @var boolean
38
-     */
39
-    protected $_received_submission = false;
40
-
41
-    /**
42
-     * message displayed to users upon successful form submission
43
-     *
44
-     * @var string
45
-     */
46
-    protected $_form_submission_success_message = '';
47
-
48
-    /**
49
-     * message displayed to users upon unsuccessful form submission
50
-     *
51
-     * @var string
52
-     */
53
-    protected $_form_submission_error_message = '';
54
-
55
-    /**
56
-     * @var array like $_REQUEST
57
-     */
58
-    protected $cached_request_data;
59
-
60
-    /**
61
-     * Stores whether this form (and its sub-sections) were found to be valid or not.
62
-     * Starts off as null, but once the form is validated, it set to either true or false
63
-     * @var boolean|null
64
-     */
65
-    protected $is_valid;
66
-
67
-    /**
68
-     * Stores all the data that will localized for form validation
69
-     *
70
-     * @var array
71
-     */
72
-    protected static $_js_localization = array();
73
-
74
-    /**
75
-     * whether or not the form's localized validation JS vars have been set
76
-     *
77
-     * @type boolean
78
-     */
79
-    protected static $_scripts_localized = false;
80
-
81
-
82
-    /**
83
-     * when constructing a proper form section, calls _construct_finalize on children
84
-     * so that they know who their parent is, and what name they've been given.
85
-     *
86
-     * @param array[] $options_array   {
87
-     * @type          $subsections     EE_Form_Section_Validatable[] where keys are the section's name
88
-     * @type          $include         string[] numerically-indexed where values are section names to be included,
89
-     *                                 and in that order. This is handy if you want
90
-     *                                 the subsections to be ordered differently than the default, and if you override
91
-     *                                 which fields are shown
92
-     * @type          $exclude         string[] values are subsections to be excluded. This is handy if you want
93
-     *                                 to remove certain default subsections (note: if you specify BOTH 'include' AND
94
-     *                                 'exclude', the inclusions will be applied first, and the exclusions will exclude
95
-     *                                 items from that list of inclusions)
96
-     * @type          $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
97
-     *                                 } @see EE_Form_Section_Validatable::__construct()
98
-     * @throws EE_Error
99
-     */
100
-    public function __construct($options_array = array())
101
-    {
102
-        $options_array = (array) apply_filters(
103
-            'FHEE__EE_Form_Section_Proper___construct__options_array',
104
-            $options_array,
105
-            $this
106
-        );
107
-        // call parent first, as it may be setting the name
108
-        parent::__construct($options_array);
109
-        // if they've included subsections in the constructor, add them now
110
-        if (isset($options_array['include'])) {
111
-            // we are going to make sure we ONLY have those subsections to include
112
-            // AND we are going to make sure they're in that specified order
113
-            $reordered_subsections = array();
114
-            foreach ($options_array['include'] as $input_name) {
115
-                if (isset($this->_subsections[ $input_name ])) {
116
-                    $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ];
117
-                }
118
-            }
119
-            $this->_subsections = $reordered_subsections;
120
-        }
121
-        if (isset($options_array['exclude'])) {
122
-            $exclude            = $options_array['exclude'];
123
-            $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
124
-        }
125
-        if (isset($options_array['layout_strategy'])) {
126
-            $this->_layout_strategy = $options_array['layout_strategy'];
127
-        }
128
-        if (! $this->_layout_strategy) {
129
-            $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
130
-        }
131
-        $this->_layout_strategy->_construct_finalize($this);
132
-        // ok so we are definitely going to want the forms JS,
133
-        // so enqueue it or remember to enqueue it during wp_enqueue_scripts
134
-        if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) {
135
-            // ok so they've constructed this object after when they should have.
136
-            // just enqueue the generic form scripts and initialize the form immediately in the JS
137
-            EE_Form_Section_Proper::wp_enqueue_scripts(true);
138
-        } else {
139
-            add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
140
-            add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
141
-        }
142
-        add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
143
-        /**
144
-         * Gives other plugins a chance to hook in before construct finalize is called.
145
-         * The form probably doesn't yet have a parent form section.
146
-         * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form,
147
-         * assuming you don't care what the form section's name, HTML ID, or HTML name etc are.
148
-         * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end
149
-         *
150
-         * @since 4.9.32
151
-         * @param EE_Form_Section_Proper $this          before __construct is done, but all of its logic,
152
-         *                                              except maybe calling _construct_finalize has been done
153
-         * @param array                  $options_array options passed into the constructor
154
-         */
155
-        do_action(
156
-            'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called',
157
-            $this,
158
-            $options_array
159
-        );
160
-        if (isset($options_array['name'])) {
161
-            $this->_construct_finalize(null, $options_array['name']);
162
-        }
163
-    }
164
-
165
-
166
-    /**
167
-     * Finishes construction given the parent form section and this form section's name
168
-     *
169
-     * @param EE_Form_Section_Proper $parent_form_section
170
-     * @param string                 $name
171
-     * @throws EE_Error
172
-     */
173
-    public function _construct_finalize($parent_form_section, $name)
174
-    {
175
-        parent::_construct_finalize($parent_form_section, $name);
176
-        $this->_set_default_name_if_empty();
177
-        $this->_set_default_html_id_if_empty();
178
-        foreach ($this->_subsections as $subsection_name => $subsection) {
179
-            if ($subsection instanceof EE_Form_Section_Base) {
180
-                $subsection->_construct_finalize($this, $subsection_name);
181
-            } else {
182
-                throw new EE_Error(
183
-                    sprintf(
184
-                        esc_html__(
185
-                            'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
186
-                            'event_espresso'
187
-                        ),
188
-                        $subsection_name,
189
-                        get_class($this),
190
-                        $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
191
-                    )
192
-                );
193
-            }
194
-        }
195
-        /**
196
-         * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed.
197
-         * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID
198
-         * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done.
199
-         * This might only happen just before displaying the form, or just before it receives form submission data.
200
-         * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've
201
-         * ensured it has a name, HTML IDs, etc
202
-         *
203
-         * @param EE_Form_Section_Proper      $this
204
-         * @param EE_Form_Section_Proper|null $parent_form_section
205
-         * @param string                      $name
206
-         */
207
-        do_action(
208
-            'AHEE__EE_Form_Section_Proper___construct_finalize__end',
209
-            $this,
210
-            $parent_form_section,
211
-            $name
212
-        );
213
-    }
214
-
215
-
216
-    /**
217
-     * Gets the layout strategy for this form section
218
-     *
219
-     * @return EE_Form_Section_Layout_Base
220
-     */
221
-    public function get_layout_strategy()
222
-    {
223
-        return $this->_layout_strategy;
224
-    }
225
-
226
-
227
-    /**
228
-     * Gets the HTML for a single input for this form section according
229
-     * to the layout strategy
230
-     *
231
-     * @param EE_Form_Input_Base $input
232
-     * @return string
233
-     */
234
-    public function get_html_for_input($input)
235
-    {
236
-        return $this->_layout_strategy->layout_input($input);
237
-    }
238
-
239
-
240
-    /**
241
-     * was_submitted - checks if form inputs are present in request data
242
-     * Basically an alias for form_data_present_in() (which is used by both
243
-     * proper form sections and form inputs)
244
-     *
245
-     * @param null $form_data
246
-     * @return boolean
247
-     * @throws EE_Error
248
-     */
249
-    public function was_submitted($form_data = null)
250
-    {
251
-        return $this->form_data_present_in($form_data);
252
-    }
253
-
254
-    /**
255
-     * Gets the cached request data; but if there is none, or $req_data was set with
256
-     * something different, refresh the cache, and then return it
257
-     * @param null $req_data
258
-     * @return array
259
-     */
260
-    protected function getCachedRequest($req_data = null)
261
-    {
262
-        if (
263
-            $this->cached_request_data === null
264
-            || (
265
-                $req_data !== null
266
-                && $req_data !== $this->cached_request_data
267
-            )
268
-        ) {
269
-            $req_data = apply_filters(
270
-                'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data',
271
-                $req_data,
272
-                $this
273
-            );
274
-            if ($req_data === null) {
275
-                $req_data = array_merge($_GET, $_POST);
276
-            }
277
-            $req_data = apply_filters(
278
-                'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data',
279
-                $req_data,
280
-                $this
281
-            );
282
-            $this->cached_request_data = (array) $req_data;
283
-        }
284
-        return $this->cached_request_data;
285
-    }
286
-
287
-
288
-    /**
289
-     * After the form section is initially created, call this to sanitize the data in the submission
290
-     * which relates to this form section, validate it, and set it as properties on the form.
291
-     *
292
-     * @param array|null $req_data should usually be $_POST (the default).
293
-     *                             However, you CAN supply a different array.
294
-     *                             Consider using set_defaults() instead however.
295
-     *                             (If you rendered the form in the page using echo $form_x->get_html()
296
-     *                             the inputs will have the correct name in the request data for this function
297
-     *                             to find them and populate the form with them.
298
-     *                             If you have a flat form (with only input subsections),
299
-     *                             you can supply a flat array where keys
300
-     *                             are the form input names and values are their values)
301
-     * @param boolean    $validate whether or not to perform validation on this data. Default is,
302
-     *                             of course, to validate that data, and set errors on the invalid values.
303
-     *                             But if the data has already been validated
304
-     *                             (eg you validated the data then stored it in the DB)
305
-     *                             you may want to skip this step.
306
-     * @throws InvalidArgumentException
307
-     * @throws InvalidInterfaceException
308
-     * @throws InvalidDataTypeException
309
-     * @throws EE_Error
310
-     */
311
-    public function receive_form_submission($req_data = null, $validate = true)
312
-    {
313
-        $req_data = $this->getCachedRequest($req_data);
314
-        $this->_normalize($req_data);
315
-        if ($validate) {
316
-            $this->_validate();
317
-            // if it's invalid, we're going to want to re-display so remember what they submitted
318
-            if (! $this->is_valid()) {
319
-                $this->store_submitted_form_data_in_session();
320
-            }
321
-        }
322
-        if ($this->submission_error_message() === '' && ! $this->is_valid()) {
323
-            $this->set_submission_error_message();
324
-        }
325
-        do_action(
326
-            'AHEE__EE_Form_Section_Proper__receive_form_submission__end',
327
-            $req_data,
328
-            $this,
329
-            $validate
330
-        );
331
-    }
332
-
333
-
334
-    /**
335
-     * caches the originally submitted input values in the session
336
-     * so that they can be used to repopulate the form if it failed validation
337
-     *
338
-     * @return boolean whether or not the data was successfully stored in the session
339
-     * @throws InvalidArgumentException
340
-     * @throws InvalidInterfaceException
341
-     * @throws InvalidDataTypeException
342
-     * @throws EE_Error
343
-     */
344
-    protected function store_submitted_form_data_in_session()
345
-    {
346
-        return EE_Registry::instance()->SSN->set_session_data(
347
-            array(
348
-                EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
349
-            )
350
-        );
351
-    }
352
-
353
-
354
-    /**
355
-     * retrieves the originally submitted input values in the session
356
-     * so that they can be used to repopulate the form if it failed validation
357
-     *
358
-     * @return array
359
-     * @throws InvalidArgumentException
360
-     * @throws InvalidInterfaceException
361
-     * @throws InvalidDataTypeException
362
-     */
363
-    protected function get_submitted_form_data_from_session()
364
-    {
365
-        $session = EE_Registry::instance()->SSN;
366
-        if ($session instanceof EE_Session) {
367
-            return $session->get_session_data(
368
-                EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
369
-            );
370
-        }
371
-        return array();
372
-    }
373
-
374
-
375
-    /**
376
-     * flushed the originally submitted input values from the session
377
-     *
378
-     * @return boolean whether or not the data was successfully removed from the session
379
-     * @throws InvalidArgumentException
380
-     * @throws InvalidInterfaceException
381
-     * @throws InvalidDataTypeException
382
-     */
383
-    public static function flush_submitted_form_data_from_session()
384
-    {
385
-        return EE_Registry::instance()->SSN->reset_data(
386
-            array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY)
387
-        );
388
-    }
389
-
390
-
391
-    /**
392
-     * Populates this form and its subsections with data from the session.
393
-     * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
394
-     * validation errors when displaying too)
395
-     * Returns true if the form was populated from the session, false otherwise
396
-     *
397
-     * @return boolean
398
-     * @throws InvalidArgumentException
399
-     * @throws InvalidInterfaceException
400
-     * @throws InvalidDataTypeException
401
-     * @throws EE_Error
402
-     */
403
-    public function populate_from_session()
404
-    {
405
-        $form_data_in_session = $this->get_submitted_form_data_from_session();
406
-        if (empty($form_data_in_session)) {
407
-            return false;
408
-        }
409
-        $this->receive_form_submission($form_data_in_session);
410
-        add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session'));
411
-        if ($this->form_data_present_in($form_data_in_session)) {
412
-            return true;
413
-        }
414
-        return false;
415
-    }
416
-
417
-
418
-    /**
419
-     * Populates the default data for the form, given an array where keys are
420
-     * the input names, and values are their values (preferably normalized to be their
421
-     * proper PHP types, not all strings... although that should be ok too).
422
-     * Proper subsections are sub-arrays, the key being the subsection's name, and
423
-     * the value being an array formatted in teh same way
424
-     *
425
-     * @param array $default_data
426
-     * @throws EE_Error
427
-     */
428
-    public function populate_defaults($default_data)
429
-    {
430
-        foreach ($this->subsections(false) as $subsection_name => $subsection) {
431
-            if (isset($default_data[ $subsection_name ])) {
432
-                if ($subsection instanceof EE_Form_Input_Base) {
433
-                    $subsection->set_default($default_data[ $subsection_name ]);
434
-                } elseif ($subsection instanceof EE_Form_Section_Proper) {
435
-                    $subsection->populate_defaults($default_data[ $subsection_name ]);
436
-                }
437
-            }
438
-        }
439
-    }
440
-
441
-
442
-    /**
443
-     * returns true if subsection exists
444
-     *
445
-     * @param string $name
446
-     * @return boolean
447
-     */
448
-    public function subsection_exists($name)
449
-    {
450
-        return isset($this->_subsections[ $name ]) ? true : false;
451
-    }
452
-
453
-
454
-    /**
455
-     * Gets the subsection specified by its name
456
-     *
457
-     * @param string  $name
458
-     * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
459
-     *                                                      so that the inputs will be properly configured.
460
-     *                                                      However, some client code may be ok
461
-     *                                                      with construction finalize being called later
462
-     *                                                      (realizing that the subsections' html names
463
-     *                                                      might not be set yet, etc.)
464
-     * @return EE_Form_Section_Base
465
-     * @throws EE_Error
466
-     */
467
-    public function get_subsection($name, $require_construction_to_be_finalized = true)
468
-    {
469
-        if ($require_construction_to_be_finalized) {
470
-            $this->ensure_construct_finalized_called();
471
-        }
472
-        return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null;
473
-    }
474
-
475
-
476
-    /**
477
-     * Gets all the validatable subsections of this form section
478
-     *
479
-     * @return EE_Form_Section_Validatable[]
480
-     * @throws EE_Error
481
-     */
482
-    public function get_validatable_subsections()
483
-    {
484
-        $validatable_subsections = array();
485
-        foreach ($this->subsections() as $name => $obj) {
486
-            if ($obj instanceof EE_Form_Section_Validatable) {
487
-                $validatable_subsections[ $name ] = $obj;
488
-            }
489
-        }
490
-        return $validatable_subsections;
491
-    }
492
-
493
-
494
-    /**
495
-     * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child,
496
-     * throw an EE_Error.
497
-     *
498
-     * @param string  $name
499
-     * @param boolean $require_construction_to_be_finalized most client code should
500
-     *                                                      leave this as TRUE so that the inputs will be properly
501
-     *                                                      configured. However, some client code may be ok with
502
-     *                                                      construction finalize being called later
503
-     *                                                      (realizing that the subsections' html names might not be
504
-     *                                                      set yet, etc.)
505
-     * @return EE_Form_Input_Base
506
-     * @throws EE_Error
507
-     */
508
-    public function get_input($name, $require_construction_to_be_finalized = true)
509
-    {
510
-        $subsection = $this->get_subsection(
511
-            $name,
512
-            $require_construction_to_be_finalized
513
-        );
514
-        if (! $subsection instanceof EE_Form_Input_Base) {
515
-            throw new EE_Error(
516
-                sprintf(
517
-                    esc_html__(
518
-                        "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
519
-                        'event_espresso'
520
-                    ),
521
-                    $name,
522
-                    get_class($this),
523
-                    $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
524
-                )
525
-            );
526
-        }
527
-        return $subsection;
528
-    }
529
-
530
-
531
-    /**
532
-     * Like get_input(), gets the proper subsection of the form given the name,
533
-     * otherwise throws an EE_Error
534
-     *
535
-     * @param string  $name
536
-     * @param boolean $require_construction_to_be_finalized most client code should
537
-     *                                                      leave this as TRUE so that the inputs will be properly
538
-     *                                                      configured. However, some client code may be ok with
539
-     *                                                      construction finalize being called later
540
-     *                                                      (realizing that the subsections' html names might not be
541
-     *                                                      set yet, etc.)
542
-     * @return EE_Form_Section_Proper
543
-     * @throws EE_Error
544
-     */
545
-    public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
546
-    {
547
-        $subsection = $this->get_subsection(
548
-            $name,
549
-            $require_construction_to_be_finalized
550
-        );
551
-        if (! $subsection instanceof EE_Form_Section_Proper) {
552
-            throw new EE_Error(
553
-                sprintf(
554
-                    esc_html__(
555
-                        "Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'",
556
-                        'event_espresso'
557
-                    ),
558
-                    $name,
559
-                    get_class($this)
560
-                )
561
-            );
562
-        }
563
-        return $subsection;
564
-    }
565
-
566
-
567
-    /**
568
-     * Gets the value of the specified input. Should be called after receive_form_submission()
569
-     * or populate_defaults() on the form, where the normalized value on the input is set.
570
-     *
571
-     * @param string $name
572
-     * @return mixed depending on the input's type and its normalization strategy
573
-     * @throws EE_Error
574
-     */
575
-    public function get_input_value($name)
576
-    {
577
-        $input = $this->get_input($name);
578
-        return $input->normalized_value();
579
-    }
580
-
581
-
582
-    /**
583
-     * Checks if this form section itself is valid, and then checks its subsections
584
-     *
585
-     * @throws EE_Error
586
-     * @return boolean
587
-     */
588
-    public function is_valid()
589
-    {
590
-        if ($this->is_valid === null) {
591
-            if (! $this->has_received_submission()) {
592
-                throw new EE_Error(
593
-                    sprintf(
594
-                        esc_html__(
595
-                            'You cannot check if a form is valid before receiving the form submission using receive_form_submission',
596
-                            'event_espresso'
597
-                        )
598
-                    )
599
-                );
600
-            }
601
-            if (! parent::is_valid()) {
602
-                $this->is_valid = false;
603
-            } else {
604
-                // ok so no general errors to this entire form section.
605
-                // so let's check the subsections, but only set errors if that hasn't been done yet
606
-                $this->is_valid = true;
607
-                foreach ($this->get_validatable_subsections() as $subsection) {
608
-                    if (! $subsection->is_valid()) {
609
-                        $this->is_valid = false;
610
-                    }
611
-                }
612
-            }
613
-        }
614
-        return $this->is_valid;
615
-    }
616
-
617
-
618
-    /**
619
-     * gets the default name of this form section if none is specified
620
-     *
621
-     * @return void
622
-     */
623
-    protected function _set_default_name_if_empty()
624
-    {
625
-        if (! $this->_name) {
626
-            $classname    = get_class($this);
627
-            $default_name = str_replace('EE_', '', $classname);
628
-            $this->_name  = $default_name;
629
-        }
630
-    }
631
-
632
-
633
-    /**
634
-     * Returns the HTML for the form, except for the form opening and closing tags
635
-     * (as the form section doesn't know where you necessarily want to send the information to),
636
-     * and except for a submit button. Enqueues JS and CSS; if called early enough we will
637
-     * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
638
-     * Not doing_it_wrong because theoretically this CAN be used properly,
639
-     * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
640
-     * any CSS.
641
-     *
642
-     * @throws InvalidArgumentException
643
-     * @throws InvalidInterfaceException
644
-     * @throws InvalidDataTypeException
645
-     * @throws EE_Error
646
-     */
647
-    public function get_html_and_js()
648
-    {
649
-        $this->enqueue_js();
650
-        return $this->get_html();
651
-    }
652
-
653
-
654
-    /**
655
-     * returns HTML for displaying this form section. recursively calls display_section() on all subsections
656
-     *
657
-     * @param bool $display_previously_submitted_data
658
-     * @return string
659
-     * @throws InvalidArgumentException
660
-     * @throws InvalidInterfaceException
661
-     * @throws InvalidDataTypeException
662
-     * @throws EE_Error
663
-     * @throws EE_Error
664
-     * @throws EE_Error
665
-     */
666
-    public function get_html($display_previously_submitted_data = true)
667
-    {
668
-        $this->ensure_construct_finalized_called();
669
-        if ($display_previously_submitted_data) {
670
-            $this->populate_from_session();
671
-        }
672
-        return $this->_form_html_filter
673
-            ? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this)
674
-            : $this->_layout_strategy->layout_form();
675
-    }
676
-
677
-
678
-    /**
679
-     * enqueues JS and CSS for the form.
680
-     * It is preferred to call this before wp_enqueue_scripts so the
681
-     * scripts and styles can be put in the header, but if called later
682
-     * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
683
-     * only be in the header; but in HTML5 its ok in the body.
684
-     * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
685
-     * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
686
-     *
687
-     * @return void
688
-     * @throws EE_Error
689
-     */
690
-    public function enqueue_js()
691
-    {
692
-        $this->_enqueue_and_localize_form_js();
693
-        foreach ($this->subsections() as $subsection) {
694
-            $subsection->enqueue_js();
695
-        }
696
-    }
697
-
698
-
699
-    /**
700
-     * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
701
-     * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
702
-     * the wp_enqueue_scripts hook.
703
-     * However, registering the form js and localizing it can happen when we
704
-     * actually output the form (which is preferred, seeing how teh form's fields
705
-     * could change until it's actually outputted)
706
-     *
707
-     * @param boolean $init_form_validation_automatically whether or not we want the form validation
708
-     *                                                    to be triggered automatically or not
709
-     * @return void
710
-     */
711
-    public static function wp_enqueue_scripts($init_form_validation_automatically = true)
712
-    {
713
-        wp_register_script(
714
-            'ee_form_section_validation',
715
-            EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js',
716
-            array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'),
717
-            EVENT_ESPRESSO_VERSION,
718
-            true
719
-        );
720
-        wp_localize_script(
721
-            'ee_form_section_validation',
722
-            'ee_form_section_validation_init',
723
-            array('init' => $init_form_validation_automatically ? '1' : '0')
724
-        );
725
-    }
726
-
727
-
728
-    /**
729
-     * gets the variables used by form_section_validation.js.
730
-     * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
731
-     * but before the wordpress hook wp_loaded
732
-     *
733
-     * @throws EE_Error
734
-     */
735
-    public function _enqueue_and_localize_form_js()
736
-    {
737
-        $this->ensure_construct_finalized_called();
738
-        // actually, we don't want to localize just yet. There may be other forms on the page.
739
-        // so we need to add our form section data to a static variable accessible by all form sections
740
-        // and localize it just before the footer
741
-        $this->localize_validation_rules();
742
-        add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
743
-        add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
744
-    }
745
-
746
-
747
-    /**
748
-     * add our form section data to a static variable accessible by all form sections
749
-     *
750
-     * @param bool $return_for_subsection
751
-     * @return void
752
-     * @throws EE_Error
753
-     */
754
-    public function localize_validation_rules($return_for_subsection = false)
755
-    {
756
-        // we only want to localize vars ONCE for the entire form,
757
-        // so if the form section doesn't have a parent, then it must be the top dog
758
-        if ($return_for_subsection || ! $this->parent_section()) {
759
-            EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array(
760
-                'form_section_id'  => $this->html_id(true),
761
-                'validation_rules' => $this->get_jquery_validation_rules(),
762
-                'other_data'       => $this->get_other_js_data(),
763
-                'errors'           => $this->subsection_validation_errors_by_html_name(),
764
-            );
765
-            EE_Form_Section_Proper::$_scripts_localized                                = true;
766
-        }
767
-    }
768
-
769
-
770
-    /**
771
-     * Gets an array of extra data that will be useful for client-side javascript.
772
-     * This is primarily data added by inputs and forms in addition to any
773
-     * scripts they might enqueue
774
-     *
775
-     * @param array $form_other_js_data
776
-     * @return array
777
-     * @throws EE_Error
778
-     */
779
-    public function get_other_js_data($form_other_js_data = array())
780
-    {
781
-        foreach ($this->subsections() as $subsection) {
782
-            $form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
783
-        }
784
-        return $form_other_js_data;
785
-    }
786
-
787
-
788
-    /**
789
-     * Gets a flat array of inputs for this form section and its subsections.
790
-     * Keys are their form names, and values are the inputs themselves
791
-     *
792
-     * @return EE_Form_Input_Base
793
-     * @throws EE_Error
794
-     */
795
-    public function inputs_in_subsections()
796
-    {
797
-        $inputs = array();
798
-        foreach ($this->subsections() as $subsection) {
799
-            if ($subsection instanceof EE_Form_Input_Base) {
800
-                $inputs[ $subsection->html_name() ] = $subsection;
801
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
802
-                $inputs += $subsection->inputs_in_subsections();
803
-            }
804
-        }
805
-        return $inputs;
806
-    }
807
-
808
-
809
-    /**
810
-     * Gets a flat array of all the validation errors.
811
-     * Keys are html names (because those should be unique)
812
-     * and values are a string of all their validation errors
813
-     *
814
-     * @return string[]
815
-     * @throws EE_Error
816
-     */
817
-    public function subsection_validation_errors_by_html_name()
818
-    {
819
-        $inputs = $this->inputs();
820
-        $errors = array();
821
-        foreach ($inputs as $form_input) {
822
-            if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
823
-                $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string();
824
-            }
825
-        }
826
-        return $errors;
827
-    }
828
-
829
-
830
-    /**
831
-     * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
832
-     * Should be setup by each form during the _enqueues_and_localize_form_js
833
-     *
834
-     * @throws InvalidArgumentException
835
-     * @throws InvalidInterfaceException
836
-     * @throws InvalidDataTypeException
837
-     */
838
-    public static function localize_script_for_all_forms()
839
-    {
840
-        // allow inputs and stuff to hook in their JS and stuff here
841
-        do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
842
-        EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
843
-        $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
844
-            ? EE_Registry::instance()->CFG->registration->email_validation_level
845
-            : 'wp_default';
846
-        EE_Form_Section_Proper::$_js_localization['email_validation_level']   = $email_validation_level;
847
-        wp_enqueue_script('ee_form_section_validation');
848
-        wp_localize_script(
849
-            'ee_form_section_validation',
850
-            'ee_form_section_vars',
851
-            EE_Form_Section_Proper::$_js_localization
852
-        );
853
-    }
854
-
855
-
856
-    /**
857
-     * ensure_scripts_localized
858
-     *
859
-     * @throws EE_Error
860
-     */
861
-    public function ensure_scripts_localized()
862
-    {
863
-        if (! EE_Form_Section_Proper::$_scripts_localized) {
864
-            $this->_enqueue_and_localize_form_js();
865
-        }
866
-    }
867
-
868
-
869
-    /**
870
-     * Gets the hard-coded validation error messages to be used in the JS. The convention
871
-     * is that the key here should be the same as the custom validation rule put in the JS file
872
-     *
873
-     * @return array keys are custom validation rules, and values are internationalized strings
874
-     */
875
-    private static function _get_localized_error_messages()
876
-    {
877
-        return array(
878
-            'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'),
879
-            'regex'    => esc_html__('Please check your input', 'event_espresso'),
880
-        );
881
-    }
882
-
883
-
884
-    /**
885
-     * @return array
886
-     */
887
-    public static function js_localization()
888
-    {
889
-        return self::$_js_localization;
890
-    }
891
-
892
-
893
-    /**
894
-     * @return void
895
-     */
896
-    public static function reset_js_localization()
897
-    {
898
-        self::$_js_localization = array();
899
-    }
900
-
901
-
902
-    /**
903
-     * Gets the JS to put inside the jquery validation rules for subsection of this form section.
904
-     * See parent function for more...
905
-     *
906
-     * @return array
907
-     * @throws EE_Error
908
-     */
909
-    public function get_jquery_validation_rules()
910
-    {
911
-        $jquery_validation_rules = array();
912
-        foreach ($this->get_validatable_subsections() as $subsection) {
913
-            $jquery_validation_rules = array_merge(
914
-                $jquery_validation_rules,
915
-                $subsection->get_jquery_validation_rules()
916
-            );
917
-        }
918
-        return $jquery_validation_rules;
919
-    }
920
-
921
-
922
-    /**
923
-     * Sanitizes all the data and sets the sanitized value of each field
924
-     *
925
-     * @param array $req_data like $_POST
926
-     * @return void
927
-     * @throws EE_Error
928
-     */
929
-    protected function _normalize($req_data)
930
-    {
931
-        $this->_received_submission = true;
932
-        $this->_validation_errors   = array();
933
-        foreach ($this->get_validatable_subsections() as $subsection) {
934
-            try {
935
-                $subsection->_normalize($req_data);
936
-            } catch (EE_Validation_Error $e) {
937
-                $subsection->add_validation_error($e);
938
-            }
939
-        }
940
-    }
941
-
942
-
943
-    /**
944
-     * Performs validation on this form section and its subsections.
945
-     * For each subsection,
946
-     * calls _validate_{subsection_name} on THIS form (if the function exists)
947
-     * and passes it the subsection, then calls _validate on that subsection.
948
-     * If you need to perform validation on the form as a whole (considering multiple)
949
-     * you would be best to override this _validate method,
950
-     * calling parent::_validate() first.
951
-     *
952
-     * @throws EE_Error
953
-     */
954
-    protected function _validate()
955
-    {
956
-        // reset the cache of whether this form is valid or not- we're re-validating it now
957
-        $this->is_valid = null;
958
-        foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
959
-            if (method_exists($this, '_validate_' . $subsection_name)) {
960
-                call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
961
-            }
962
-            $subsection->_validate();
963
-        }
964
-    }
965
-
966
-
967
-    /**
968
-     * Gets all the validated inputs for the form section
969
-     *
970
-     * @return array
971
-     * @throws EE_Error
972
-     */
973
-    public function valid_data()
974
-    {
975
-        $inputs = array();
976
-        foreach ($this->subsections() as $subsection_name => $subsection) {
977
-            if ($subsection instanceof EE_Form_Section_Proper) {
978
-                $inputs[ $subsection_name ] = $subsection->valid_data();
979
-            } elseif ($subsection instanceof EE_Form_Input_Base) {
980
-                $inputs[ $subsection_name ] = $subsection->normalized_value();
981
-            }
982
-        }
983
-        return $inputs;
984
-    }
985
-
986
-
987
-    /**
988
-     * Gets all the inputs on this form section
989
-     *
990
-     * @return EE_Form_Input_Base[]
991
-     * @throws EE_Error
992
-     */
993
-    public function inputs()
994
-    {
995
-        $inputs = array();
996
-        foreach ($this->subsections() as $subsection_name => $subsection) {
997
-            if ($subsection instanceof EE_Form_Input_Base) {
998
-                $inputs[ $subsection_name ] = $subsection;
999
-            }
1000
-        }
1001
-        return $inputs;
1002
-    }
1003
-
1004
-
1005
-    /**
1006
-     * Gets all the subsections which are a proper form
1007
-     *
1008
-     * @return EE_Form_Section_Proper[]
1009
-     * @throws EE_Error
1010
-     */
1011
-    public function subforms()
1012
-    {
1013
-        $form_sections = array();
1014
-        foreach ($this->subsections() as $name => $obj) {
1015
-            if ($obj instanceof EE_Form_Section_Proper) {
1016
-                $form_sections[ $name ] = $obj;
1017
-            }
1018
-        }
1019
-        return $form_sections;
1020
-    }
1021
-
1022
-
1023
-    /**
1024
-     * Gets all the subsections (inputs, proper subsections, or html-only sections).
1025
-     * Consider using inputs() or subforms()
1026
-     * if you only want form inputs or proper form sections.
1027
-     *
1028
-     * @param boolean $require_construction_to_be_finalized most client code should
1029
-     *                                                      leave this as TRUE so that the inputs will be properly
1030
-     *                                                      configured. However, some client code may be ok with
1031
-     *                                                      construction finalize being called later
1032
-     *                                                      (realizing that the subsections' html names might not be
1033
-     *                                                      set yet, etc.)
1034
-     * @return EE_Form_Section_Proper[]
1035
-     * @throws EE_Error
1036
-     */
1037
-    public function subsections($require_construction_to_be_finalized = true)
1038
-    {
1039
-        if ($require_construction_to_be_finalized) {
1040
-            $this->ensure_construct_finalized_called();
1041
-        }
1042
-        return $this->_subsections;
1043
-    }
1044
-
1045
-
1046
-    /**
1047
-     * Returns whether this form has any subforms or inputs
1048
-     * @return bool
1049
-     */
1050
-    public function hasSubsections()
1051
-    {
1052
-        return ! empty($this->_subsections);
1053
-    }
1054
-
1055
-
1056
-    /**
1057
-     * Returns a simple array where keys are input names, and values are their normalized
1058
-     * values. (Similar to calling get_input_value on inputs)
1059
-     *
1060
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1061
-     *                                        or just this forms' direct children inputs
1062
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1063
-     *                                        or allow multidimensional array
1064
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
1065
-     *                                        with array keys being input names
1066
-     *                                        (regardless of whether they are from a subsection or not),
1067
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1068
-     *                                        where keys are always subsection names and values are either
1069
-     *                                        the input's normalized value, or an array like the top-level array
1070
-     * @throws EE_Error
1071
-     */
1072
-    public function input_values($include_subform_inputs = false, $flatten = false)
1073
-    {
1074
-        return $this->_input_values(false, $include_subform_inputs, $flatten);
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
1080
-     * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
1081
-     * is not necessarily the value we want to display to users. This creates an array
1082
-     * where keys are the input names, and values are their display values
1083
-     *
1084
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1085
-     *                                        or just this forms' direct children inputs
1086
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1087
-     *                                        or allow multidimensional array
1088
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
1089
-     *                                        with array keys being input names
1090
-     *                                        (regardless of whether they are from a subsection or not),
1091
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1092
-     *                                        where keys are always subsection names and values are either
1093
-     *                                        the input's normalized value, or an array like the top-level array
1094
-     * @throws EE_Error
1095
-     */
1096
-    public function input_pretty_values($include_subform_inputs = false, $flatten = false)
1097
-    {
1098
-        return $this->_input_values(true, $include_subform_inputs, $flatten);
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * Gets the input values from the form
1104
-     *
1105
-     * @param boolean $pretty                 Whether to retrieve the pretty value,
1106
-     *                                        or just the normalized value
1107
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1108
-     *                                        or just this forms' direct children inputs
1109
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1110
-     *                                        or allow multidimensional array
1111
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
1112
-     *                                        input names (regardless of whether they are from a subsection or not),
1113
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1114
-     *                                        where keys are always subsection names and values are either
1115
-     *                                        the input's normalized value, or an array like the top-level array
1116
-     * @throws EE_Error
1117
-     */
1118
-    public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
1119
-    {
1120
-        $input_values = array();
1121
-        foreach ($this->subsections() as $subsection_name => $subsection) {
1122
-            if ($subsection instanceof EE_Form_Input_Base) {
1123
-                $input_values[ $subsection_name ] = $pretty
1124
-                    ? $subsection->pretty_value()
1125
-                    : $subsection->normalized_value();
1126
-            } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1127
-                $subform_input_values = $subsection->_input_values(
1128
-                    $pretty,
1129
-                    $include_subform_inputs,
1130
-                    $flatten
1131
-                );
1132
-                if ($flatten) {
1133
-                    $input_values = array_merge($input_values, $subform_input_values);
1134
-                } else {
1135
-                    $input_values[ $subsection_name ] = $subform_input_values;
1136
-                }
1137
-            }
1138
-        }
1139
-        return $input_values;
1140
-    }
1141
-
1142
-
1143
-    /**
1144
-     * Gets the originally submitted input values from the form
1145
-     *
1146
-     * @param boolean $include_subforms  Whether to include inputs from subforms,
1147
-     *                                   or just this forms' direct children inputs
1148
-     * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1149
-     *                                   with array keys being input names
1150
-     *                                   (regardless of whether they are from a subsection or not),
1151
-     *                                   and if $flatten is FALSE it can be a multidimensional array
1152
-     *                                   where keys are always subsection names and values are either
1153
-     *                                   the input's normalized value, or an array like the top-level array
1154
-     * @throws EE_Error
1155
-     */
1156
-    public function submitted_values($include_subforms = false)
1157
-    {
1158
-        $submitted_values = array();
1159
-        foreach ($this->subsections() as $subsection) {
1160
-            if ($subsection instanceof EE_Form_Input_Base) {
1161
-                // is this input part of an array of inputs?
1162
-                if (strpos($subsection->html_name(), '[') !== false) {
1163
-                    $full_input_name  = EEH_Array::convert_array_values_to_keys(
1164
-                        explode(
1165
-                            '[',
1166
-                            str_replace(']', '', $subsection->html_name())
1167
-                        ),
1168
-                        $subsection->raw_value()
1169
-                    );
1170
-                    $submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1171
-                } else {
1172
-                    $submitted_values[ $subsection->html_name() ] = $subsection->raw_value();
1173
-                }
1174
-            } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1175
-                $subform_input_values = $subsection->submitted_values($include_subforms);
1176
-                $submitted_values     = array_replace_recursive($submitted_values, $subform_input_values);
1177
-            }
1178
-        }
1179
-        return $submitted_values;
1180
-    }
1181
-
1182
-
1183
-    /**
1184
-     * Indicates whether or not this form has received a submission yet
1185
-     * (ie, had receive_form_submission called on it yet)
1186
-     *
1187
-     * @return boolean
1188
-     * @throws EE_Error
1189
-     */
1190
-    public function has_received_submission()
1191
-    {
1192
-        $this->ensure_construct_finalized_called();
1193
-        return $this->_received_submission;
1194
-    }
1195
-
1196
-
1197
-    /**
1198
-     * Equivalent to passing 'exclude' in the constructor's options array.
1199
-     * Removes the listed inputs from the form
1200
-     *
1201
-     * @param array $inputs_to_exclude values are the input names
1202
-     * @return void
1203
-     */
1204
-    public function exclude(array $inputs_to_exclude = array())
1205
-    {
1206
-        foreach ($inputs_to_exclude as $input_to_exclude_name) {
1207
-            unset($this->_subsections[ $input_to_exclude_name ]);
1208
-        }
1209
-    }
1210
-
1211
-
1212
-    /**
1213
-     * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy.
1214
-     * @param array $inputs_to_hide
1215
-     * @throws EE_Error
1216
-     */
1217
-    public function hide(array $inputs_to_hide = array())
1218
-    {
1219
-        foreach ($inputs_to_hide as $input_to_hide) {
1220
-            $input = $this->get_input($input_to_hide);
1221
-            $input->set_display_strategy(new EE_Hidden_Display_Strategy());
1222
-        }
1223
-    }
1224
-
1225
-
1226
-    /**
1227
-     * add_subsections
1228
-     * Adds the listed subsections to the form section.
1229
-     * If $subsection_name_to_target is provided,
1230
-     * then new subsections are added before or after that subsection,
1231
-     * otherwise to the start or end of the entire subsections array.
1232
-     *
1233
-     * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1234
-     *                                                          where keys are their names
1235
-     * @param string                 $subsection_name_to_target an existing for section that $new_subsections
1236
-     *                                                          should be added before or after
1237
-     *                                                          IF $subsection_name_to_target is null,
1238
-     *                                                          then $new_subsections will be added to
1239
-     *                                                          the beginning or end of the entire subsections array
1240
-     * @param boolean                $add_before                whether to add $new_subsections, before or after
1241
-     *                                                          $subsection_name_to_target,
1242
-     *                                                          or if $subsection_name_to_target is null,
1243
-     *                                                          before or after entire subsections array
1244
-     * @return void
1245
-     * @throws EE_Error
1246
-     */
1247
-    public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true)
1248
-    {
1249
-        foreach ($new_subsections as $subsection_name => $subsection) {
1250
-            if (! $subsection instanceof EE_Form_Section_Base) {
1251
-                EE_Error::add_error(
1252
-                    sprintf(
1253
-                        esc_html__(
1254
-                            "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1255
-                            'event_espresso'
1256
-                        ),
1257
-                        get_class($subsection),
1258
-                        $subsection_name,
1259
-                        $this->name()
1260
-                    )
1261
-                );
1262
-                unset($new_subsections[ $subsection_name ]);
1263
-            }
1264
-        }
1265
-        $this->_subsections = EEH_Array::insert_into_array(
1266
-            $this->_subsections,
1267
-            $new_subsections,
1268
-            $subsection_name_to_target,
1269
-            $add_before
1270
-        );
1271
-        if ($this->_construction_finalized) {
1272
-            foreach ($this->_subsections as $name => $subsection) {
1273
-                $subsection->_construct_finalize($this, $name);
1274
-            }
1275
-        }
1276
-    }
1277
-
1278
-
1279
-    /**
1280
-     * @param string $subsection_name
1281
-     * @param bool   $recursive
1282
-     * @return bool
1283
-     */
1284
-    public function has_subsection($subsection_name, $recursive = false)
1285
-    {
1286
-        foreach ($this->_subsections as $name => $subsection) {
1287
-            if (
1288
-                $name === $subsection_name
1289
-                || (
1290
-                    $recursive
1291
-                    && $subsection instanceof EE_Form_Section_Proper
1292
-                    && $subsection->has_subsection($subsection_name, $recursive)
1293
-                )
1294
-            ) {
1295
-                return true;
1296
-            }
1297
-        }
1298
-        return false;
1299
-    }
1300
-
1301
-
1302
-
1303
-    /**
1304
-     * Just gets all validatable subsections to clean their sensitive data
1305
-     *
1306
-     * @throws EE_Error
1307
-     */
1308
-    public function clean_sensitive_data()
1309
-    {
1310
-        foreach ($this->get_validatable_subsections() as $subsection) {
1311
-            $subsection->clean_sensitive_data();
1312
-        }
1313
-    }
1314
-
1315
-
1316
-    /**
1317
-     * Sets the submission error message (aka validation error message for this form section and all sub-sections)
1318
-     * @param string                           $form_submission_error_message
1319
-     * @param EE_Form_Section_Validatable $form_section unused
1320
-     * @throws EE_Error
1321
-     */
1322
-    public function set_submission_error_message(
1323
-        $form_submission_error_message = ''
1324
-    ) {
1325
-        $this->_form_submission_error_message = ! empty($form_submission_error_message)
1326
-            ? $form_submission_error_message
1327
-            : $this->getAllValidationErrorsString();
1328
-    }
1329
-
1330
-
1331
-    /**
1332
-     * Returns the cached error message. A default value is set for this during _validate(),
1333
-     * (called during receive_form_submission) but it can be explicitly set using
1334
-     * set_submission_error_message
1335
-     *
1336
-     * @return string
1337
-     */
1338
-    public function submission_error_message()
1339
-    {
1340
-        return $this->_form_submission_error_message;
1341
-    }
1342
-
1343
-
1344
-    /**
1345
-     * Sets a message to display if the data submitted to the form was valid.
1346
-     * @param string $form_submission_success_message
1347
-     */
1348
-    public function set_submission_success_message($form_submission_success_message = '')
1349
-    {
1350
-        $this->_form_submission_success_message = ! empty($form_submission_success_message)
1351
-            ? $form_submission_success_message
1352
-            : esc_html__('Form submitted successfully', 'event_espresso');
1353
-    }
1354
-
1355
-
1356
-    /**
1357
-     * Gets a message appropriate for display when the form is correctly submitted
1358
-     * @return string
1359
-     */
1360
-    public function submission_success_message()
1361
-    {
1362
-        return $this->_form_submission_success_message;
1363
-    }
1364
-
1365
-
1366
-    /**
1367
-     * Returns the prefix that should be used on child of this form section for
1368
-     * their html names. If this form section itself has a parent, prepends ITS
1369
-     * prefix onto this form section's prefix. Used primarily by
1370
-     * EE_Form_Input_Base::_set_default_html_name_if_empty
1371
-     *
1372
-     * @return string
1373
-     * @throws EE_Error
1374
-     */
1375
-    public function html_name_prefix()
1376
-    {
1377
-        if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1378
-            return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1379
-        }
1380
-        return $this->name();
1381
-    }
1382
-
1383
-
1384
-    /**
1385
-     * Gets the name, but first checks _construct_finalize has been called. If not,
1386
-     * calls it (assumes there is no parent and that we want the name to be whatever
1387
-     * was set, which is probably nothing, or the classname)
1388
-     *
1389
-     * @return string
1390
-     * @throws EE_Error
1391
-     */
1392
-    public function name()
1393
-    {
1394
-        $this->ensure_construct_finalized_called();
1395
-        return parent::name();
1396
-    }
1397
-
1398
-
1399
-    /**
1400
-     * @return EE_Form_Section_Proper
1401
-     * @throws EE_Error
1402
-     */
1403
-    public function parent_section()
1404
-    {
1405
-        $this->ensure_construct_finalized_called();
1406
-        return parent::parent_section();
1407
-    }
1408
-
1409
-
1410
-    /**
1411
-     * make sure construction finalized was called, otherwise children might not be ready
1412
-     *
1413
-     * @return void
1414
-     * @throws EE_Error
1415
-     */
1416
-    public function ensure_construct_finalized_called()
1417
-    {
1418
-        if (! $this->_construction_finalized) {
1419
-            $this->_construct_finalize($this->_parent_section, $this->_name);
1420
-        }
1421
-    }
1422
-
1423
-
1424
-    /**
1425
-     * Checks if any of this form section's inputs, or any of its children's inputs,
1426
-     * are in teh form data. If any are found, returns true. Else false
1427
-     *
1428
-     * @param array $req_data
1429
-     * @return boolean
1430
-     * @throws EE_Error
1431
-     */
1432
-    public function form_data_present_in($req_data = null)
1433
-    {
1434
-        $req_data = $this->getCachedRequest($req_data);
1435
-        foreach ($this->subsections() as $subsection) {
1436
-            if ($subsection instanceof EE_Form_Input_Base) {
1437
-                if ($subsection->form_data_present_in($req_data)) {
1438
-                    return true;
1439
-                }
1440
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
1441
-                if ($subsection->form_data_present_in($req_data)) {
1442
-                    return true;
1443
-                }
1444
-            }
1445
-        }
1446
-        return false;
1447
-    }
1448
-
1449
-
1450
-    /**
1451
-     * Gets validation errors for this form section and subsections
1452
-     * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1453
-     * gets the validation errors for ALL subsection
1454
-     *
1455
-     * @return EE_Validation_Error[]
1456
-     * @throws EE_Error
1457
-     */
1458
-    public function get_validation_errors_accumulated()
1459
-    {
1460
-        $validation_errors = $this->get_validation_errors();
1461
-        foreach ($this->get_validatable_subsections() as $subsection) {
1462
-            if ($subsection instanceof EE_Form_Section_Proper) {
1463
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1464
-            } else {
1465
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors();
1466
-            }
1467
-            if ($validation_errors_on_this_subsection) {
1468
-                $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1469
-            }
1470
-        }
1471
-        return $validation_errors;
1472
-    }
1473
-
1474
-    /**
1475
-     * Fetch validation errors from children and grandchildren and puts them in a single string.
1476
-     * This traverses the form section tree to generate this, but you probably want to instead use
1477
-     * get_form_submission_error_message() which is usually this message cached (or a custom validation error message)
1478
-     *
1479
-     * @return string
1480
-     * @since 4.9.59.p
1481
-     */
1482
-    protected function getAllValidationErrorsString()
1483
-    {
1484
-        $submission_error_messages = array();
1485
-        // bad, bad, bad registrant
1486
-        foreach ($this->get_validation_errors_accumulated() as $validation_error) {
1487
-            if ($validation_error instanceof EE_Validation_Error) {
1488
-                $form_section = $validation_error->get_form_section();
1489
-                if ($form_section instanceof EE_Form_Input_Base) {
1490
-                    $label = $validation_error->get_form_section()->html_label_text();
1491
-                } elseif ($form_section instanceof EE_Form_Section_Validatable) {
1492
-                    $label = $validation_error->get_form_section()->name();
1493
-                } else {
1494
-                    $label = esc_html__('Unknown', 'event_espresso');
1495
-                }
1496
-                $submission_error_messages[] = sprintf(
1497
-                    __('%s : %s', 'event_espresso'),
1498
-                    $label,
1499
-                    $validation_error->getMessage()
1500
-                );
1501
-            }
1502
-        }
1503
-        return implode('<br>', $submission_error_messages);
1504
-    }
1505
-
1506
-
1507
-    /**
1508
-     * This isn't just the name of an input, it's a path pointing to an input. The
1509
-     * path is similar to a folder path: slash (/) means to descend into a subsection,
1510
-     * dot-dot-slash (../) means to ascend into the parent section.
1511
-     * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1512
-     * which will be returned.
1513
-     * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1514
-     * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1515
-     * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1516
-     * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1517
-     * Etc
1518
-     *
1519
-     * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1520
-     * @return EE_Form_Section_Base
1521
-     * @throws EE_Error
1522
-     */
1523
-    public function find_section_from_path($form_section_path)
1524
-    {
1525
-        // check if we can find the input from purely going straight up the tree
1526
-        $input = parent::find_section_from_path($form_section_path);
1527
-        if ($input instanceof EE_Form_Section_Base) {
1528
-            return $input;
1529
-        }
1530
-        $next_slash_pos = strpos($form_section_path, '/');
1531
-        if ($next_slash_pos !== false) {
1532
-            $child_section_name = substr($form_section_path, 0, $next_slash_pos);
1533
-            $subpath            = substr($form_section_path, $next_slash_pos + 1);
1534
-        } else {
1535
-            $child_section_name = $form_section_path;
1536
-            $subpath            = '';
1537
-        }
1538
-        $child_section = $this->get_subsection($child_section_name);
1539
-        if ($child_section instanceof EE_Form_Section_Base) {
1540
-            return $child_section->find_section_from_path($subpath);
1541
-        }
1542
-        return null;
1543
-    }
18
+	const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
19
+
20
+	/**
21
+	 * Subsections
22
+	 *
23
+	 * @var EE_Form_Section_Validatable[]
24
+	 */
25
+	protected $_subsections = array();
26
+
27
+	/**
28
+	 * Strategy for laying out the form
29
+	 *
30
+	 * @var EE_Form_Section_Layout_Base
31
+	 */
32
+	protected $_layout_strategy;
33
+
34
+	/**
35
+	 * Whether or not this form has received and validated a form submission yet
36
+	 *
37
+	 * @var boolean
38
+	 */
39
+	protected $_received_submission = false;
40
+
41
+	/**
42
+	 * message displayed to users upon successful form submission
43
+	 *
44
+	 * @var string
45
+	 */
46
+	protected $_form_submission_success_message = '';
47
+
48
+	/**
49
+	 * message displayed to users upon unsuccessful form submission
50
+	 *
51
+	 * @var string
52
+	 */
53
+	protected $_form_submission_error_message = '';
54
+
55
+	/**
56
+	 * @var array like $_REQUEST
57
+	 */
58
+	protected $cached_request_data;
59
+
60
+	/**
61
+	 * Stores whether this form (and its sub-sections) were found to be valid or not.
62
+	 * Starts off as null, but once the form is validated, it set to either true or false
63
+	 * @var boolean|null
64
+	 */
65
+	protected $is_valid;
66
+
67
+	/**
68
+	 * Stores all the data that will localized for form validation
69
+	 *
70
+	 * @var array
71
+	 */
72
+	protected static $_js_localization = array();
73
+
74
+	/**
75
+	 * whether or not the form's localized validation JS vars have been set
76
+	 *
77
+	 * @type boolean
78
+	 */
79
+	protected static $_scripts_localized = false;
80
+
81
+
82
+	/**
83
+	 * when constructing a proper form section, calls _construct_finalize on children
84
+	 * so that they know who their parent is, and what name they've been given.
85
+	 *
86
+	 * @param array[] $options_array   {
87
+	 * @type          $subsections     EE_Form_Section_Validatable[] where keys are the section's name
88
+	 * @type          $include         string[] numerically-indexed where values are section names to be included,
89
+	 *                                 and in that order. This is handy if you want
90
+	 *                                 the subsections to be ordered differently than the default, and if you override
91
+	 *                                 which fields are shown
92
+	 * @type          $exclude         string[] values are subsections to be excluded. This is handy if you want
93
+	 *                                 to remove certain default subsections (note: if you specify BOTH 'include' AND
94
+	 *                                 'exclude', the inclusions will be applied first, and the exclusions will exclude
95
+	 *                                 items from that list of inclusions)
96
+	 * @type          $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
97
+	 *                                 } @see EE_Form_Section_Validatable::__construct()
98
+	 * @throws EE_Error
99
+	 */
100
+	public function __construct($options_array = array())
101
+	{
102
+		$options_array = (array) apply_filters(
103
+			'FHEE__EE_Form_Section_Proper___construct__options_array',
104
+			$options_array,
105
+			$this
106
+		);
107
+		// call parent first, as it may be setting the name
108
+		parent::__construct($options_array);
109
+		// if they've included subsections in the constructor, add them now
110
+		if (isset($options_array['include'])) {
111
+			// we are going to make sure we ONLY have those subsections to include
112
+			// AND we are going to make sure they're in that specified order
113
+			$reordered_subsections = array();
114
+			foreach ($options_array['include'] as $input_name) {
115
+				if (isset($this->_subsections[ $input_name ])) {
116
+					$reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ];
117
+				}
118
+			}
119
+			$this->_subsections = $reordered_subsections;
120
+		}
121
+		if (isset($options_array['exclude'])) {
122
+			$exclude            = $options_array['exclude'];
123
+			$this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
124
+		}
125
+		if (isset($options_array['layout_strategy'])) {
126
+			$this->_layout_strategy = $options_array['layout_strategy'];
127
+		}
128
+		if (! $this->_layout_strategy) {
129
+			$this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
130
+		}
131
+		$this->_layout_strategy->_construct_finalize($this);
132
+		// ok so we are definitely going to want the forms JS,
133
+		// so enqueue it or remember to enqueue it during wp_enqueue_scripts
134
+		if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) {
135
+			// ok so they've constructed this object after when they should have.
136
+			// just enqueue the generic form scripts and initialize the form immediately in the JS
137
+			EE_Form_Section_Proper::wp_enqueue_scripts(true);
138
+		} else {
139
+			add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
140
+			add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
141
+		}
142
+		add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
143
+		/**
144
+		 * Gives other plugins a chance to hook in before construct finalize is called.
145
+		 * The form probably doesn't yet have a parent form section.
146
+		 * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form,
147
+		 * assuming you don't care what the form section's name, HTML ID, or HTML name etc are.
148
+		 * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end
149
+		 *
150
+		 * @since 4.9.32
151
+		 * @param EE_Form_Section_Proper $this          before __construct is done, but all of its logic,
152
+		 *                                              except maybe calling _construct_finalize has been done
153
+		 * @param array                  $options_array options passed into the constructor
154
+		 */
155
+		do_action(
156
+			'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called',
157
+			$this,
158
+			$options_array
159
+		);
160
+		if (isset($options_array['name'])) {
161
+			$this->_construct_finalize(null, $options_array['name']);
162
+		}
163
+	}
164
+
165
+
166
+	/**
167
+	 * Finishes construction given the parent form section and this form section's name
168
+	 *
169
+	 * @param EE_Form_Section_Proper $parent_form_section
170
+	 * @param string                 $name
171
+	 * @throws EE_Error
172
+	 */
173
+	public function _construct_finalize($parent_form_section, $name)
174
+	{
175
+		parent::_construct_finalize($parent_form_section, $name);
176
+		$this->_set_default_name_if_empty();
177
+		$this->_set_default_html_id_if_empty();
178
+		foreach ($this->_subsections as $subsection_name => $subsection) {
179
+			if ($subsection instanceof EE_Form_Section_Base) {
180
+				$subsection->_construct_finalize($this, $subsection_name);
181
+			} else {
182
+				throw new EE_Error(
183
+					sprintf(
184
+						esc_html__(
185
+							'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
186
+							'event_espresso'
187
+						),
188
+						$subsection_name,
189
+						get_class($this),
190
+						$subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
191
+					)
192
+				);
193
+			}
194
+		}
195
+		/**
196
+		 * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed.
197
+		 * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID
198
+		 * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done.
199
+		 * This might only happen just before displaying the form, or just before it receives form submission data.
200
+		 * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've
201
+		 * ensured it has a name, HTML IDs, etc
202
+		 *
203
+		 * @param EE_Form_Section_Proper      $this
204
+		 * @param EE_Form_Section_Proper|null $parent_form_section
205
+		 * @param string                      $name
206
+		 */
207
+		do_action(
208
+			'AHEE__EE_Form_Section_Proper___construct_finalize__end',
209
+			$this,
210
+			$parent_form_section,
211
+			$name
212
+		);
213
+	}
214
+
215
+
216
+	/**
217
+	 * Gets the layout strategy for this form section
218
+	 *
219
+	 * @return EE_Form_Section_Layout_Base
220
+	 */
221
+	public function get_layout_strategy()
222
+	{
223
+		return $this->_layout_strategy;
224
+	}
225
+
226
+
227
+	/**
228
+	 * Gets the HTML for a single input for this form section according
229
+	 * to the layout strategy
230
+	 *
231
+	 * @param EE_Form_Input_Base $input
232
+	 * @return string
233
+	 */
234
+	public function get_html_for_input($input)
235
+	{
236
+		return $this->_layout_strategy->layout_input($input);
237
+	}
238
+
239
+
240
+	/**
241
+	 * was_submitted - checks if form inputs are present in request data
242
+	 * Basically an alias for form_data_present_in() (which is used by both
243
+	 * proper form sections and form inputs)
244
+	 *
245
+	 * @param null $form_data
246
+	 * @return boolean
247
+	 * @throws EE_Error
248
+	 */
249
+	public function was_submitted($form_data = null)
250
+	{
251
+		return $this->form_data_present_in($form_data);
252
+	}
253
+
254
+	/**
255
+	 * Gets the cached request data; but if there is none, or $req_data was set with
256
+	 * something different, refresh the cache, and then return it
257
+	 * @param null $req_data
258
+	 * @return array
259
+	 */
260
+	protected function getCachedRequest($req_data = null)
261
+	{
262
+		if (
263
+			$this->cached_request_data === null
264
+			|| (
265
+				$req_data !== null
266
+				&& $req_data !== $this->cached_request_data
267
+			)
268
+		) {
269
+			$req_data = apply_filters(
270
+				'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data',
271
+				$req_data,
272
+				$this
273
+			);
274
+			if ($req_data === null) {
275
+				$req_data = array_merge($_GET, $_POST);
276
+			}
277
+			$req_data = apply_filters(
278
+				'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data',
279
+				$req_data,
280
+				$this
281
+			);
282
+			$this->cached_request_data = (array) $req_data;
283
+		}
284
+		return $this->cached_request_data;
285
+	}
286
+
287
+
288
+	/**
289
+	 * After the form section is initially created, call this to sanitize the data in the submission
290
+	 * which relates to this form section, validate it, and set it as properties on the form.
291
+	 *
292
+	 * @param array|null $req_data should usually be $_POST (the default).
293
+	 *                             However, you CAN supply a different array.
294
+	 *                             Consider using set_defaults() instead however.
295
+	 *                             (If you rendered the form in the page using echo $form_x->get_html()
296
+	 *                             the inputs will have the correct name in the request data for this function
297
+	 *                             to find them and populate the form with them.
298
+	 *                             If you have a flat form (with only input subsections),
299
+	 *                             you can supply a flat array where keys
300
+	 *                             are the form input names and values are their values)
301
+	 * @param boolean    $validate whether or not to perform validation on this data. Default is,
302
+	 *                             of course, to validate that data, and set errors on the invalid values.
303
+	 *                             But if the data has already been validated
304
+	 *                             (eg you validated the data then stored it in the DB)
305
+	 *                             you may want to skip this step.
306
+	 * @throws InvalidArgumentException
307
+	 * @throws InvalidInterfaceException
308
+	 * @throws InvalidDataTypeException
309
+	 * @throws EE_Error
310
+	 */
311
+	public function receive_form_submission($req_data = null, $validate = true)
312
+	{
313
+		$req_data = $this->getCachedRequest($req_data);
314
+		$this->_normalize($req_data);
315
+		if ($validate) {
316
+			$this->_validate();
317
+			// if it's invalid, we're going to want to re-display so remember what they submitted
318
+			if (! $this->is_valid()) {
319
+				$this->store_submitted_form_data_in_session();
320
+			}
321
+		}
322
+		if ($this->submission_error_message() === '' && ! $this->is_valid()) {
323
+			$this->set_submission_error_message();
324
+		}
325
+		do_action(
326
+			'AHEE__EE_Form_Section_Proper__receive_form_submission__end',
327
+			$req_data,
328
+			$this,
329
+			$validate
330
+		);
331
+	}
332
+
333
+
334
+	/**
335
+	 * caches the originally submitted input values in the session
336
+	 * so that they can be used to repopulate the form if it failed validation
337
+	 *
338
+	 * @return boolean whether or not the data was successfully stored in the session
339
+	 * @throws InvalidArgumentException
340
+	 * @throws InvalidInterfaceException
341
+	 * @throws InvalidDataTypeException
342
+	 * @throws EE_Error
343
+	 */
344
+	protected function store_submitted_form_data_in_session()
345
+	{
346
+		return EE_Registry::instance()->SSN->set_session_data(
347
+			array(
348
+				EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
349
+			)
350
+		);
351
+	}
352
+
353
+
354
+	/**
355
+	 * retrieves the originally submitted input values in the session
356
+	 * so that they can be used to repopulate the form if it failed validation
357
+	 *
358
+	 * @return array
359
+	 * @throws InvalidArgumentException
360
+	 * @throws InvalidInterfaceException
361
+	 * @throws InvalidDataTypeException
362
+	 */
363
+	protected function get_submitted_form_data_from_session()
364
+	{
365
+		$session = EE_Registry::instance()->SSN;
366
+		if ($session instanceof EE_Session) {
367
+			return $session->get_session_data(
368
+				EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
369
+			);
370
+		}
371
+		return array();
372
+	}
373
+
374
+
375
+	/**
376
+	 * flushed the originally submitted input values from the session
377
+	 *
378
+	 * @return boolean whether or not the data was successfully removed from the session
379
+	 * @throws InvalidArgumentException
380
+	 * @throws InvalidInterfaceException
381
+	 * @throws InvalidDataTypeException
382
+	 */
383
+	public static function flush_submitted_form_data_from_session()
384
+	{
385
+		return EE_Registry::instance()->SSN->reset_data(
386
+			array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY)
387
+		);
388
+	}
389
+
390
+
391
+	/**
392
+	 * Populates this form and its subsections with data from the session.
393
+	 * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
394
+	 * validation errors when displaying too)
395
+	 * Returns true if the form was populated from the session, false otherwise
396
+	 *
397
+	 * @return boolean
398
+	 * @throws InvalidArgumentException
399
+	 * @throws InvalidInterfaceException
400
+	 * @throws InvalidDataTypeException
401
+	 * @throws EE_Error
402
+	 */
403
+	public function populate_from_session()
404
+	{
405
+		$form_data_in_session = $this->get_submitted_form_data_from_session();
406
+		if (empty($form_data_in_session)) {
407
+			return false;
408
+		}
409
+		$this->receive_form_submission($form_data_in_session);
410
+		add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session'));
411
+		if ($this->form_data_present_in($form_data_in_session)) {
412
+			return true;
413
+		}
414
+		return false;
415
+	}
416
+
417
+
418
+	/**
419
+	 * Populates the default data for the form, given an array where keys are
420
+	 * the input names, and values are their values (preferably normalized to be their
421
+	 * proper PHP types, not all strings... although that should be ok too).
422
+	 * Proper subsections are sub-arrays, the key being the subsection's name, and
423
+	 * the value being an array formatted in teh same way
424
+	 *
425
+	 * @param array $default_data
426
+	 * @throws EE_Error
427
+	 */
428
+	public function populate_defaults($default_data)
429
+	{
430
+		foreach ($this->subsections(false) as $subsection_name => $subsection) {
431
+			if (isset($default_data[ $subsection_name ])) {
432
+				if ($subsection instanceof EE_Form_Input_Base) {
433
+					$subsection->set_default($default_data[ $subsection_name ]);
434
+				} elseif ($subsection instanceof EE_Form_Section_Proper) {
435
+					$subsection->populate_defaults($default_data[ $subsection_name ]);
436
+				}
437
+			}
438
+		}
439
+	}
440
+
441
+
442
+	/**
443
+	 * returns true if subsection exists
444
+	 *
445
+	 * @param string $name
446
+	 * @return boolean
447
+	 */
448
+	public function subsection_exists($name)
449
+	{
450
+		return isset($this->_subsections[ $name ]) ? true : false;
451
+	}
452
+
453
+
454
+	/**
455
+	 * Gets the subsection specified by its name
456
+	 *
457
+	 * @param string  $name
458
+	 * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
459
+	 *                                                      so that the inputs will be properly configured.
460
+	 *                                                      However, some client code may be ok
461
+	 *                                                      with construction finalize being called later
462
+	 *                                                      (realizing that the subsections' html names
463
+	 *                                                      might not be set yet, etc.)
464
+	 * @return EE_Form_Section_Base
465
+	 * @throws EE_Error
466
+	 */
467
+	public function get_subsection($name, $require_construction_to_be_finalized = true)
468
+	{
469
+		if ($require_construction_to_be_finalized) {
470
+			$this->ensure_construct_finalized_called();
471
+		}
472
+		return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null;
473
+	}
474
+
475
+
476
+	/**
477
+	 * Gets all the validatable subsections of this form section
478
+	 *
479
+	 * @return EE_Form_Section_Validatable[]
480
+	 * @throws EE_Error
481
+	 */
482
+	public function get_validatable_subsections()
483
+	{
484
+		$validatable_subsections = array();
485
+		foreach ($this->subsections() as $name => $obj) {
486
+			if ($obj instanceof EE_Form_Section_Validatable) {
487
+				$validatable_subsections[ $name ] = $obj;
488
+			}
489
+		}
490
+		return $validatable_subsections;
491
+	}
492
+
493
+
494
+	/**
495
+	 * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child,
496
+	 * throw an EE_Error.
497
+	 *
498
+	 * @param string  $name
499
+	 * @param boolean $require_construction_to_be_finalized most client code should
500
+	 *                                                      leave this as TRUE so that the inputs will be properly
501
+	 *                                                      configured. However, some client code may be ok with
502
+	 *                                                      construction finalize being called later
503
+	 *                                                      (realizing that the subsections' html names might not be
504
+	 *                                                      set yet, etc.)
505
+	 * @return EE_Form_Input_Base
506
+	 * @throws EE_Error
507
+	 */
508
+	public function get_input($name, $require_construction_to_be_finalized = true)
509
+	{
510
+		$subsection = $this->get_subsection(
511
+			$name,
512
+			$require_construction_to_be_finalized
513
+		);
514
+		if (! $subsection instanceof EE_Form_Input_Base) {
515
+			throw new EE_Error(
516
+				sprintf(
517
+					esc_html__(
518
+						"Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
519
+						'event_espresso'
520
+					),
521
+					$name,
522
+					get_class($this),
523
+					$subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
524
+				)
525
+			);
526
+		}
527
+		return $subsection;
528
+	}
529
+
530
+
531
+	/**
532
+	 * Like get_input(), gets the proper subsection of the form given the name,
533
+	 * otherwise throws an EE_Error
534
+	 *
535
+	 * @param string  $name
536
+	 * @param boolean $require_construction_to_be_finalized most client code should
537
+	 *                                                      leave this as TRUE so that the inputs will be properly
538
+	 *                                                      configured. However, some client code may be ok with
539
+	 *                                                      construction finalize being called later
540
+	 *                                                      (realizing that the subsections' html names might not be
541
+	 *                                                      set yet, etc.)
542
+	 * @return EE_Form_Section_Proper
543
+	 * @throws EE_Error
544
+	 */
545
+	public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
546
+	{
547
+		$subsection = $this->get_subsection(
548
+			$name,
549
+			$require_construction_to_be_finalized
550
+		);
551
+		if (! $subsection instanceof EE_Form_Section_Proper) {
552
+			throw new EE_Error(
553
+				sprintf(
554
+					esc_html__(
555
+						"Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'",
556
+						'event_espresso'
557
+					),
558
+					$name,
559
+					get_class($this)
560
+				)
561
+			);
562
+		}
563
+		return $subsection;
564
+	}
565
+
566
+
567
+	/**
568
+	 * Gets the value of the specified input. Should be called after receive_form_submission()
569
+	 * or populate_defaults() on the form, where the normalized value on the input is set.
570
+	 *
571
+	 * @param string $name
572
+	 * @return mixed depending on the input's type and its normalization strategy
573
+	 * @throws EE_Error
574
+	 */
575
+	public function get_input_value($name)
576
+	{
577
+		$input = $this->get_input($name);
578
+		return $input->normalized_value();
579
+	}
580
+
581
+
582
+	/**
583
+	 * Checks if this form section itself is valid, and then checks its subsections
584
+	 *
585
+	 * @throws EE_Error
586
+	 * @return boolean
587
+	 */
588
+	public function is_valid()
589
+	{
590
+		if ($this->is_valid === null) {
591
+			if (! $this->has_received_submission()) {
592
+				throw new EE_Error(
593
+					sprintf(
594
+						esc_html__(
595
+							'You cannot check if a form is valid before receiving the form submission using receive_form_submission',
596
+							'event_espresso'
597
+						)
598
+					)
599
+				);
600
+			}
601
+			if (! parent::is_valid()) {
602
+				$this->is_valid = false;
603
+			} else {
604
+				// ok so no general errors to this entire form section.
605
+				// so let's check the subsections, but only set errors if that hasn't been done yet
606
+				$this->is_valid = true;
607
+				foreach ($this->get_validatable_subsections() as $subsection) {
608
+					if (! $subsection->is_valid()) {
609
+						$this->is_valid = false;
610
+					}
611
+				}
612
+			}
613
+		}
614
+		return $this->is_valid;
615
+	}
616
+
617
+
618
+	/**
619
+	 * gets the default name of this form section if none is specified
620
+	 *
621
+	 * @return void
622
+	 */
623
+	protected function _set_default_name_if_empty()
624
+	{
625
+		if (! $this->_name) {
626
+			$classname    = get_class($this);
627
+			$default_name = str_replace('EE_', '', $classname);
628
+			$this->_name  = $default_name;
629
+		}
630
+	}
631
+
632
+
633
+	/**
634
+	 * Returns the HTML for the form, except for the form opening and closing tags
635
+	 * (as the form section doesn't know where you necessarily want to send the information to),
636
+	 * and except for a submit button. Enqueues JS and CSS; if called early enough we will
637
+	 * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
638
+	 * Not doing_it_wrong because theoretically this CAN be used properly,
639
+	 * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
640
+	 * any CSS.
641
+	 *
642
+	 * @throws InvalidArgumentException
643
+	 * @throws InvalidInterfaceException
644
+	 * @throws InvalidDataTypeException
645
+	 * @throws EE_Error
646
+	 */
647
+	public function get_html_and_js()
648
+	{
649
+		$this->enqueue_js();
650
+		return $this->get_html();
651
+	}
652
+
653
+
654
+	/**
655
+	 * returns HTML for displaying this form section. recursively calls display_section() on all subsections
656
+	 *
657
+	 * @param bool $display_previously_submitted_data
658
+	 * @return string
659
+	 * @throws InvalidArgumentException
660
+	 * @throws InvalidInterfaceException
661
+	 * @throws InvalidDataTypeException
662
+	 * @throws EE_Error
663
+	 * @throws EE_Error
664
+	 * @throws EE_Error
665
+	 */
666
+	public function get_html($display_previously_submitted_data = true)
667
+	{
668
+		$this->ensure_construct_finalized_called();
669
+		if ($display_previously_submitted_data) {
670
+			$this->populate_from_session();
671
+		}
672
+		return $this->_form_html_filter
673
+			? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this)
674
+			: $this->_layout_strategy->layout_form();
675
+	}
676
+
677
+
678
+	/**
679
+	 * enqueues JS and CSS for the form.
680
+	 * It is preferred to call this before wp_enqueue_scripts so the
681
+	 * scripts and styles can be put in the header, but if called later
682
+	 * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
683
+	 * only be in the header; but in HTML5 its ok in the body.
684
+	 * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
685
+	 * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
686
+	 *
687
+	 * @return void
688
+	 * @throws EE_Error
689
+	 */
690
+	public function enqueue_js()
691
+	{
692
+		$this->_enqueue_and_localize_form_js();
693
+		foreach ($this->subsections() as $subsection) {
694
+			$subsection->enqueue_js();
695
+		}
696
+	}
697
+
698
+
699
+	/**
700
+	 * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
701
+	 * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
702
+	 * the wp_enqueue_scripts hook.
703
+	 * However, registering the form js and localizing it can happen when we
704
+	 * actually output the form (which is preferred, seeing how teh form's fields
705
+	 * could change until it's actually outputted)
706
+	 *
707
+	 * @param boolean $init_form_validation_automatically whether or not we want the form validation
708
+	 *                                                    to be triggered automatically or not
709
+	 * @return void
710
+	 */
711
+	public static function wp_enqueue_scripts($init_form_validation_automatically = true)
712
+	{
713
+		wp_register_script(
714
+			'ee_form_section_validation',
715
+			EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js',
716
+			array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'),
717
+			EVENT_ESPRESSO_VERSION,
718
+			true
719
+		);
720
+		wp_localize_script(
721
+			'ee_form_section_validation',
722
+			'ee_form_section_validation_init',
723
+			array('init' => $init_form_validation_automatically ? '1' : '0')
724
+		);
725
+	}
726
+
727
+
728
+	/**
729
+	 * gets the variables used by form_section_validation.js.
730
+	 * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
731
+	 * but before the wordpress hook wp_loaded
732
+	 *
733
+	 * @throws EE_Error
734
+	 */
735
+	public function _enqueue_and_localize_form_js()
736
+	{
737
+		$this->ensure_construct_finalized_called();
738
+		// actually, we don't want to localize just yet. There may be other forms on the page.
739
+		// so we need to add our form section data to a static variable accessible by all form sections
740
+		// and localize it just before the footer
741
+		$this->localize_validation_rules();
742
+		add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
743
+		add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
744
+	}
745
+
746
+
747
+	/**
748
+	 * add our form section data to a static variable accessible by all form sections
749
+	 *
750
+	 * @param bool $return_for_subsection
751
+	 * @return void
752
+	 * @throws EE_Error
753
+	 */
754
+	public function localize_validation_rules($return_for_subsection = false)
755
+	{
756
+		// we only want to localize vars ONCE for the entire form,
757
+		// so if the form section doesn't have a parent, then it must be the top dog
758
+		if ($return_for_subsection || ! $this->parent_section()) {
759
+			EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array(
760
+				'form_section_id'  => $this->html_id(true),
761
+				'validation_rules' => $this->get_jquery_validation_rules(),
762
+				'other_data'       => $this->get_other_js_data(),
763
+				'errors'           => $this->subsection_validation_errors_by_html_name(),
764
+			);
765
+			EE_Form_Section_Proper::$_scripts_localized                                = true;
766
+		}
767
+	}
768
+
769
+
770
+	/**
771
+	 * Gets an array of extra data that will be useful for client-side javascript.
772
+	 * This is primarily data added by inputs and forms in addition to any
773
+	 * scripts they might enqueue
774
+	 *
775
+	 * @param array $form_other_js_data
776
+	 * @return array
777
+	 * @throws EE_Error
778
+	 */
779
+	public function get_other_js_data($form_other_js_data = array())
780
+	{
781
+		foreach ($this->subsections() as $subsection) {
782
+			$form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
783
+		}
784
+		return $form_other_js_data;
785
+	}
786
+
787
+
788
+	/**
789
+	 * Gets a flat array of inputs for this form section and its subsections.
790
+	 * Keys are their form names, and values are the inputs themselves
791
+	 *
792
+	 * @return EE_Form_Input_Base
793
+	 * @throws EE_Error
794
+	 */
795
+	public function inputs_in_subsections()
796
+	{
797
+		$inputs = array();
798
+		foreach ($this->subsections() as $subsection) {
799
+			if ($subsection instanceof EE_Form_Input_Base) {
800
+				$inputs[ $subsection->html_name() ] = $subsection;
801
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
802
+				$inputs += $subsection->inputs_in_subsections();
803
+			}
804
+		}
805
+		return $inputs;
806
+	}
807
+
808
+
809
+	/**
810
+	 * Gets a flat array of all the validation errors.
811
+	 * Keys are html names (because those should be unique)
812
+	 * and values are a string of all their validation errors
813
+	 *
814
+	 * @return string[]
815
+	 * @throws EE_Error
816
+	 */
817
+	public function subsection_validation_errors_by_html_name()
818
+	{
819
+		$inputs = $this->inputs();
820
+		$errors = array();
821
+		foreach ($inputs as $form_input) {
822
+			if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
823
+				$errors[ $form_input->html_name() ] = $form_input->get_validation_error_string();
824
+			}
825
+		}
826
+		return $errors;
827
+	}
828
+
829
+
830
+	/**
831
+	 * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
832
+	 * Should be setup by each form during the _enqueues_and_localize_form_js
833
+	 *
834
+	 * @throws InvalidArgumentException
835
+	 * @throws InvalidInterfaceException
836
+	 * @throws InvalidDataTypeException
837
+	 */
838
+	public static function localize_script_for_all_forms()
839
+	{
840
+		// allow inputs and stuff to hook in their JS and stuff here
841
+		do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
842
+		EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
843
+		$email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
844
+			? EE_Registry::instance()->CFG->registration->email_validation_level
845
+			: 'wp_default';
846
+		EE_Form_Section_Proper::$_js_localization['email_validation_level']   = $email_validation_level;
847
+		wp_enqueue_script('ee_form_section_validation');
848
+		wp_localize_script(
849
+			'ee_form_section_validation',
850
+			'ee_form_section_vars',
851
+			EE_Form_Section_Proper::$_js_localization
852
+		);
853
+	}
854
+
855
+
856
+	/**
857
+	 * ensure_scripts_localized
858
+	 *
859
+	 * @throws EE_Error
860
+	 */
861
+	public function ensure_scripts_localized()
862
+	{
863
+		if (! EE_Form_Section_Proper::$_scripts_localized) {
864
+			$this->_enqueue_and_localize_form_js();
865
+		}
866
+	}
867
+
868
+
869
+	/**
870
+	 * Gets the hard-coded validation error messages to be used in the JS. The convention
871
+	 * is that the key here should be the same as the custom validation rule put in the JS file
872
+	 *
873
+	 * @return array keys are custom validation rules, and values are internationalized strings
874
+	 */
875
+	private static function _get_localized_error_messages()
876
+	{
877
+		return array(
878
+			'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'),
879
+			'regex'    => esc_html__('Please check your input', 'event_espresso'),
880
+		);
881
+	}
882
+
883
+
884
+	/**
885
+	 * @return array
886
+	 */
887
+	public static function js_localization()
888
+	{
889
+		return self::$_js_localization;
890
+	}
891
+
892
+
893
+	/**
894
+	 * @return void
895
+	 */
896
+	public static function reset_js_localization()
897
+	{
898
+		self::$_js_localization = array();
899
+	}
900
+
901
+
902
+	/**
903
+	 * Gets the JS to put inside the jquery validation rules for subsection of this form section.
904
+	 * See parent function for more...
905
+	 *
906
+	 * @return array
907
+	 * @throws EE_Error
908
+	 */
909
+	public function get_jquery_validation_rules()
910
+	{
911
+		$jquery_validation_rules = array();
912
+		foreach ($this->get_validatable_subsections() as $subsection) {
913
+			$jquery_validation_rules = array_merge(
914
+				$jquery_validation_rules,
915
+				$subsection->get_jquery_validation_rules()
916
+			);
917
+		}
918
+		return $jquery_validation_rules;
919
+	}
920
+
921
+
922
+	/**
923
+	 * Sanitizes all the data and sets the sanitized value of each field
924
+	 *
925
+	 * @param array $req_data like $_POST
926
+	 * @return void
927
+	 * @throws EE_Error
928
+	 */
929
+	protected function _normalize($req_data)
930
+	{
931
+		$this->_received_submission = true;
932
+		$this->_validation_errors   = array();
933
+		foreach ($this->get_validatable_subsections() as $subsection) {
934
+			try {
935
+				$subsection->_normalize($req_data);
936
+			} catch (EE_Validation_Error $e) {
937
+				$subsection->add_validation_error($e);
938
+			}
939
+		}
940
+	}
941
+
942
+
943
+	/**
944
+	 * Performs validation on this form section and its subsections.
945
+	 * For each subsection,
946
+	 * calls _validate_{subsection_name} on THIS form (if the function exists)
947
+	 * and passes it the subsection, then calls _validate on that subsection.
948
+	 * If you need to perform validation on the form as a whole (considering multiple)
949
+	 * you would be best to override this _validate method,
950
+	 * calling parent::_validate() first.
951
+	 *
952
+	 * @throws EE_Error
953
+	 */
954
+	protected function _validate()
955
+	{
956
+		// reset the cache of whether this form is valid or not- we're re-validating it now
957
+		$this->is_valid = null;
958
+		foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
959
+			if (method_exists($this, '_validate_' . $subsection_name)) {
960
+				call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
961
+			}
962
+			$subsection->_validate();
963
+		}
964
+	}
965
+
966
+
967
+	/**
968
+	 * Gets all the validated inputs for the form section
969
+	 *
970
+	 * @return array
971
+	 * @throws EE_Error
972
+	 */
973
+	public function valid_data()
974
+	{
975
+		$inputs = array();
976
+		foreach ($this->subsections() as $subsection_name => $subsection) {
977
+			if ($subsection instanceof EE_Form_Section_Proper) {
978
+				$inputs[ $subsection_name ] = $subsection->valid_data();
979
+			} elseif ($subsection instanceof EE_Form_Input_Base) {
980
+				$inputs[ $subsection_name ] = $subsection->normalized_value();
981
+			}
982
+		}
983
+		return $inputs;
984
+	}
985
+
986
+
987
+	/**
988
+	 * Gets all the inputs on this form section
989
+	 *
990
+	 * @return EE_Form_Input_Base[]
991
+	 * @throws EE_Error
992
+	 */
993
+	public function inputs()
994
+	{
995
+		$inputs = array();
996
+		foreach ($this->subsections() as $subsection_name => $subsection) {
997
+			if ($subsection instanceof EE_Form_Input_Base) {
998
+				$inputs[ $subsection_name ] = $subsection;
999
+			}
1000
+		}
1001
+		return $inputs;
1002
+	}
1003
+
1004
+
1005
+	/**
1006
+	 * Gets all the subsections which are a proper form
1007
+	 *
1008
+	 * @return EE_Form_Section_Proper[]
1009
+	 * @throws EE_Error
1010
+	 */
1011
+	public function subforms()
1012
+	{
1013
+		$form_sections = array();
1014
+		foreach ($this->subsections() as $name => $obj) {
1015
+			if ($obj instanceof EE_Form_Section_Proper) {
1016
+				$form_sections[ $name ] = $obj;
1017
+			}
1018
+		}
1019
+		return $form_sections;
1020
+	}
1021
+
1022
+
1023
+	/**
1024
+	 * Gets all the subsections (inputs, proper subsections, or html-only sections).
1025
+	 * Consider using inputs() or subforms()
1026
+	 * if you only want form inputs or proper form sections.
1027
+	 *
1028
+	 * @param boolean $require_construction_to_be_finalized most client code should
1029
+	 *                                                      leave this as TRUE so that the inputs will be properly
1030
+	 *                                                      configured. However, some client code may be ok with
1031
+	 *                                                      construction finalize being called later
1032
+	 *                                                      (realizing that the subsections' html names might not be
1033
+	 *                                                      set yet, etc.)
1034
+	 * @return EE_Form_Section_Proper[]
1035
+	 * @throws EE_Error
1036
+	 */
1037
+	public function subsections($require_construction_to_be_finalized = true)
1038
+	{
1039
+		if ($require_construction_to_be_finalized) {
1040
+			$this->ensure_construct_finalized_called();
1041
+		}
1042
+		return $this->_subsections;
1043
+	}
1044
+
1045
+
1046
+	/**
1047
+	 * Returns whether this form has any subforms or inputs
1048
+	 * @return bool
1049
+	 */
1050
+	public function hasSubsections()
1051
+	{
1052
+		return ! empty($this->_subsections);
1053
+	}
1054
+
1055
+
1056
+	/**
1057
+	 * Returns a simple array where keys are input names, and values are their normalized
1058
+	 * values. (Similar to calling get_input_value on inputs)
1059
+	 *
1060
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1061
+	 *                                        or just this forms' direct children inputs
1062
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1063
+	 *                                        or allow multidimensional array
1064
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
1065
+	 *                                        with array keys being input names
1066
+	 *                                        (regardless of whether they are from a subsection or not),
1067
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1068
+	 *                                        where keys are always subsection names and values are either
1069
+	 *                                        the input's normalized value, or an array like the top-level array
1070
+	 * @throws EE_Error
1071
+	 */
1072
+	public function input_values($include_subform_inputs = false, $flatten = false)
1073
+	{
1074
+		return $this->_input_values(false, $include_subform_inputs, $flatten);
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
1080
+	 * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
1081
+	 * is not necessarily the value we want to display to users. This creates an array
1082
+	 * where keys are the input names, and values are their display values
1083
+	 *
1084
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1085
+	 *                                        or just this forms' direct children inputs
1086
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1087
+	 *                                        or allow multidimensional array
1088
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
1089
+	 *                                        with array keys being input names
1090
+	 *                                        (regardless of whether they are from a subsection or not),
1091
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1092
+	 *                                        where keys are always subsection names and values are either
1093
+	 *                                        the input's normalized value, or an array like the top-level array
1094
+	 * @throws EE_Error
1095
+	 */
1096
+	public function input_pretty_values($include_subform_inputs = false, $flatten = false)
1097
+	{
1098
+		return $this->_input_values(true, $include_subform_inputs, $flatten);
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * Gets the input values from the form
1104
+	 *
1105
+	 * @param boolean $pretty                 Whether to retrieve the pretty value,
1106
+	 *                                        or just the normalized value
1107
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1108
+	 *                                        or just this forms' direct children inputs
1109
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1110
+	 *                                        or allow multidimensional array
1111
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
1112
+	 *                                        input names (regardless of whether they are from a subsection or not),
1113
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1114
+	 *                                        where keys are always subsection names and values are either
1115
+	 *                                        the input's normalized value, or an array like the top-level array
1116
+	 * @throws EE_Error
1117
+	 */
1118
+	public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
1119
+	{
1120
+		$input_values = array();
1121
+		foreach ($this->subsections() as $subsection_name => $subsection) {
1122
+			if ($subsection instanceof EE_Form_Input_Base) {
1123
+				$input_values[ $subsection_name ] = $pretty
1124
+					? $subsection->pretty_value()
1125
+					: $subsection->normalized_value();
1126
+			} elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1127
+				$subform_input_values = $subsection->_input_values(
1128
+					$pretty,
1129
+					$include_subform_inputs,
1130
+					$flatten
1131
+				);
1132
+				if ($flatten) {
1133
+					$input_values = array_merge($input_values, $subform_input_values);
1134
+				} else {
1135
+					$input_values[ $subsection_name ] = $subform_input_values;
1136
+				}
1137
+			}
1138
+		}
1139
+		return $input_values;
1140
+	}
1141
+
1142
+
1143
+	/**
1144
+	 * Gets the originally submitted input values from the form
1145
+	 *
1146
+	 * @param boolean $include_subforms  Whether to include inputs from subforms,
1147
+	 *                                   or just this forms' direct children inputs
1148
+	 * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1149
+	 *                                   with array keys being input names
1150
+	 *                                   (regardless of whether they are from a subsection or not),
1151
+	 *                                   and if $flatten is FALSE it can be a multidimensional array
1152
+	 *                                   where keys are always subsection names and values are either
1153
+	 *                                   the input's normalized value, or an array like the top-level array
1154
+	 * @throws EE_Error
1155
+	 */
1156
+	public function submitted_values($include_subforms = false)
1157
+	{
1158
+		$submitted_values = array();
1159
+		foreach ($this->subsections() as $subsection) {
1160
+			if ($subsection instanceof EE_Form_Input_Base) {
1161
+				// is this input part of an array of inputs?
1162
+				if (strpos($subsection->html_name(), '[') !== false) {
1163
+					$full_input_name  = EEH_Array::convert_array_values_to_keys(
1164
+						explode(
1165
+							'[',
1166
+							str_replace(']', '', $subsection->html_name())
1167
+						),
1168
+						$subsection->raw_value()
1169
+					);
1170
+					$submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1171
+				} else {
1172
+					$submitted_values[ $subsection->html_name() ] = $subsection->raw_value();
1173
+				}
1174
+			} elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1175
+				$subform_input_values = $subsection->submitted_values($include_subforms);
1176
+				$submitted_values     = array_replace_recursive($submitted_values, $subform_input_values);
1177
+			}
1178
+		}
1179
+		return $submitted_values;
1180
+	}
1181
+
1182
+
1183
+	/**
1184
+	 * Indicates whether or not this form has received a submission yet
1185
+	 * (ie, had receive_form_submission called on it yet)
1186
+	 *
1187
+	 * @return boolean
1188
+	 * @throws EE_Error
1189
+	 */
1190
+	public function has_received_submission()
1191
+	{
1192
+		$this->ensure_construct_finalized_called();
1193
+		return $this->_received_submission;
1194
+	}
1195
+
1196
+
1197
+	/**
1198
+	 * Equivalent to passing 'exclude' in the constructor's options array.
1199
+	 * Removes the listed inputs from the form
1200
+	 *
1201
+	 * @param array $inputs_to_exclude values are the input names
1202
+	 * @return void
1203
+	 */
1204
+	public function exclude(array $inputs_to_exclude = array())
1205
+	{
1206
+		foreach ($inputs_to_exclude as $input_to_exclude_name) {
1207
+			unset($this->_subsections[ $input_to_exclude_name ]);
1208
+		}
1209
+	}
1210
+
1211
+
1212
+	/**
1213
+	 * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy.
1214
+	 * @param array $inputs_to_hide
1215
+	 * @throws EE_Error
1216
+	 */
1217
+	public function hide(array $inputs_to_hide = array())
1218
+	{
1219
+		foreach ($inputs_to_hide as $input_to_hide) {
1220
+			$input = $this->get_input($input_to_hide);
1221
+			$input->set_display_strategy(new EE_Hidden_Display_Strategy());
1222
+		}
1223
+	}
1224
+
1225
+
1226
+	/**
1227
+	 * add_subsections
1228
+	 * Adds the listed subsections to the form section.
1229
+	 * If $subsection_name_to_target is provided,
1230
+	 * then new subsections are added before or after that subsection,
1231
+	 * otherwise to the start or end of the entire subsections array.
1232
+	 *
1233
+	 * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1234
+	 *                                                          where keys are their names
1235
+	 * @param string                 $subsection_name_to_target an existing for section that $new_subsections
1236
+	 *                                                          should be added before or after
1237
+	 *                                                          IF $subsection_name_to_target is null,
1238
+	 *                                                          then $new_subsections will be added to
1239
+	 *                                                          the beginning or end of the entire subsections array
1240
+	 * @param boolean                $add_before                whether to add $new_subsections, before or after
1241
+	 *                                                          $subsection_name_to_target,
1242
+	 *                                                          or if $subsection_name_to_target is null,
1243
+	 *                                                          before or after entire subsections array
1244
+	 * @return void
1245
+	 * @throws EE_Error
1246
+	 */
1247
+	public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true)
1248
+	{
1249
+		foreach ($new_subsections as $subsection_name => $subsection) {
1250
+			if (! $subsection instanceof EE_Form_Section_Base) {
1251
+				EE_Error::add_error(
1252
+					sprintf(
1253
+						esc_html__(
1254
+							"Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1255
+							'event_espresso'
1256
+						),
1257
+						get_class($subsection),
1258
+						$subsection_name,
1259
+						$this->name()
1260
+					)
1261
+				);
1262
+				unset($new_subsections[ $subsection_name ]);
1263
+			}
1264
+		}
1265
+		$this->_subsections = EEH_Array::insert_into_array(
1266
+			$this->_subsections,
1267
+			$new_subsections,
1268
+			$subsection_name_to_target,
1269
+			$add_before
1270
+		);
1271
+		if ($this->_construction_finalized) {
1272
+			foreach ($this->_subsections as $name => $subsection) {
1273
+				$subsection->_construct_finalize($this, $name);
1274
+			}
1275
+		}
1276
+	}
1277
+
1278
+
1279
+	/**
1280
+	 * @param string $subsection_name
1281
+	 * @param bool   $recursive
1282
+	 * @return bool
1283
+	 */
1284
+	public function has_subsection($subsection_name, $recursive = false)
1285
+	{
1286
+		foreach ($this->_subsections as $name => $subsection) {
1287
+			if (
1288
+				$name === $subsection_name
1289
+				|| (
1290
+					$recursive
1291
+					&& $subsection instanceof EE_Form_Section_Proper
1292
+					&& $subsection->has_subsection($subsection_name, $recursive)
1293
+				)
1294
+			) {
1295
+				return true;
1296
+			}
1297
+		}
1298
+		return false;
1299
+	}
1300
+
1301
+
1302
+
1303
+	/**
1304
+	 * Just gets all validatable subsections to clean their sensitive data
1305
+	 *
1306
+	 * @throws EE_Error
1307
+	 */
1308
+	public function clean_sensitive_data()
1309
+	{
1310
+		foreach ($this->get_validatable_subsections() as $subsection) {
1311
+			$subsection->clean_sensitive_data();
1312
+		}
1313
+	}
1314
+
1315
+
1316
+	/**
1317
+	 * Sets the submission error message (aka validation error message for this form section and all sub-sections)
1318
+	 * @param string                           $form_submission_error_message
1319
+	 * @param EE_Form_Section_Validatable $form_section unused
1320
+	 * @throws EE_Error
1321
+	 */
1322
+	public function set_submission_error_message(
1323
+		$form_submission_error_message = ''
1324
+	) {
1325
+		$this->_form_submission_error_message = ! empty($form_submission_error_message)
1326
+			? $form_submission_error_message
1327
+			: $this->getAllValidationErrorsString();
1328
+	}
1329
+
1330
+
1331
+	/**
1332
+	 * Returns the cached error message. A default value is set for this during _validate(),
1333
+	 * (called during receive_form_submission) but it can be explicitly set using
1334
+	 * set_submission_error_message
1335
+	 *
1336
+	 * @return string
1337
+	 */
1338
+	public function submission_error_message()
1339
+	{
1340
+		return $this->_form_submission_error_message;
1341
+	}
1342
+
1343
+
1344
+	/**
1345
+	 * Sets a message to display if the data submitted to the form was valid.
1346
+	 * @param string $form_submission_success_message
1347
+	 */
1348
+	public function set_submission_success_message($form_submission_success_message = '')
1349
+	{
1350
+		$this->_form_submission_success_message = ! empty($form_submission_success_message)
1351
+			? $form_submission_success_message
1352
+			: esc_html__('Form submitted successfully', 'event_espresso');
1353
+	}
1354
+
1355
+
1356
+	/**
1357
+	 * Gets a message appropriate for display when the form is correctly submitted
1358
+	 * @return string
1359
+	 */
1360
+	public function submission_success_message()
1361
+	{
1362
+		return $this->_form_submission_success_message;
1363
+	}
1364
+
1365
+
1366
+	/**
1367
+	 * Returns the prefix that should be used on child of this form section for
1368
+	 * their html names. If this form section itself has a parent, prepends ITS
1369
+	 * prefix onto this form section's prefix. Used primarily by
1370
+	 * EE_Form_Input_Base::_set_default_html_name_if_empty
1371
+	 *
1372
+	 * @return string
1373
+	 * @throws EE_Error
1374
+	 */
1375
+	public function html_name_prefix()
1376
+	{
1377
+		if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1378
+			return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1379
+		}
1380
+		return $this->name();
1381
+	}
1382
+
1383
+
1384
+	/**
1385
+	 * Gets the name, but first checks _construct_finalize has been called. If not,
1386
+	 * calls it (assumes there is no parent and that we want the name to be whatever
1387
+	 * was set, which is probably nothing, or the classname)
1388
+	 *
1389
+	 * @return string
1390
+	 * @throws EE_Error
1391
+	 */
1392
+	public function name()
1393
+	{
1394
+		$this->ensure_construct_finalized_called();
1395
+		return parent::name();
1396
+	}
1397
+
1398
+
1399
+	/**
1400
+	 * @return EE_Form_Section_Proper
1401
+	 * @throws EE_Error
1402
+	 */
1403
+	public function parent_section()
1404
+	{
1405
+		$this->ensure_construct_finalized_called();
1406
+		return parent::parent_section();
1407
+	}
1408
+
1409
+
1410
+	/**
1411
+	 * make sure construction finalized was called, otherwise children might not be ready
1412
+	 *
1413
+	 * @return void
1414
+	 * @throws EE_Error
1415
+	 */
1416
+	public function ensure_construct_finalized_called()
1417
+	{
1418
+		if (! $this->_construction_finalized) {
1419
+			$this->_construct_finalize($this->_parent_section, $this->_name);
1420
+		}
1421
+	}
1422
+
1423
+
1424
+	/**
1425
+	 * Checks if any of this form section's inputs, or any of its children's inputs,
1426
+	 * are in teh form data. If any are found, returns true. Else false
1427
+	 *
1428
+	 * @param array $req_data
1429
+	 * @return boolean
1430
+	 * @throws EE_Error
1431
+	 */
1432
+	public function form_data_present_in($req_data = null)
1433
+	{
1434
+		$req_data = $this->getCachedRequest($req_data);
1435
+		foreach ($this->subsections() as $subsection) {
1436
+			if ($subsection instanceof EE_Form_Input_Base) {
1437
+				if ($subsection->form_data_present_in($req_data)) {
1438
+					return true;
1439
+				}
1440
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
1441
+				if ($subsection->form_data_present_in($req_data)) {
1442
+					return true;
1443
+				}
1444
+			}
1445
+		}
1446
+		return false;
1447
+	}
1448
+
1449
+
1450
+	/**
1451
+	 * Gets validation errors for this form section and subsections
1452
+	 * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1453
+	 * gets the validation errors for ALL subsection
1454
+	 *
1455
+	 * @return EE_Validation_Error[]
1456
+	 * @throws EE_Error
1457
+	 */
1458
+	public function get_validation_errors_accumulated()
1459
+	{
1460
+		$validation_errors = $this->get_validation_errors();
1461
+		foreach ($this->get_validatable_subsections() as $subsection) {
1462
+			if ($subsection instanceof EE_Form_Section_Proper) {
1463
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1464
+			} else {
1465
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors();
1466
+			}
1467
+			if ($validation_errors_on_this_subsection) {
1468
+				$validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1469
+			}
1470
+		}
1471
+		return $validation_errors;
1472
+	}
1473
+
1474
+	/**
1475
+	 * Fetch validation errors from children and grandchildren and puts them in a single string.
1476
+	 * This traverses the form section tree to generate this, but you probably want to instead use
1477
+	 * get_form_submission_error_message() which is usually this message cached (or a custom validation error message)
1478
+	 *
1479
+	 * @return string
1480
+	 * @since 4.9.59.p
1481
+	 */
1482
+	protected function getAllValidationErrorsString()
1483
+	{
1484
+		$submission_error_messages = array();
1485
+		// bad, bad, bad registrant
1486
+		foreach ($this->get_validation_errors_accumulated() as $validation_error) {
1487
+			if ($validation_error instanceof EE_Validation_Error) {
1488
+				$form_section = $validation_error->get_form_section();
1489
+				if ($form_section instanceof EE_Form_Input_Base) {
1490
+					$label = $validation_error->get_form_section()->html_label_text();
1491
+				} elseif ($form_section instanceof EE_Form_Section_Validatable) {
1492
+					$label = $validation_error->get_form_section()->name();
1493
+				} else {
1494
+					$label = esc_html__('Unknown', 'event_espresso');
1495
+				}
1496
+				$submission_error_messages[] = sprintf(
1497
+					__('%s : %s', 'event_espresso'),
1498
+					$label,
1499
+					$validation_error->getMessage()
1500
+				);
1501
+			}
1502
+		}
1503
+		return implode('<br>', $submission_error_messages);
1504
+	}
1505
+
1506
+
1507
+	/**
1508
+	 * This isn't just the name of an input, it's a path pointing to an input. The
1509
+	 * path is similar to a folder path: slash (/) means to descend into a subsection,
1510
+	 * dot-dot-slash (../) means to ascend into the parent section.
1511
+	 * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1512
+	 * which will be returned.
1513
+	 * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1514
+	 * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1515
+	 * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1516
+	 * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1517
+	 * Etc
1518
+	 *
1519
+	 * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1520
+	 * @return EE_Form_Section_Base
1521
+	 * @throws EE_Error
1522
+	 */
1523
+	public function find_section_from_path($form_section_path)
1524
+	{
1525
+		// check if we can find the input from purely going straight up the tree
1526
+		$input = parent::find_section_from_path($form_section_path);
1527
+		if ($input instanceof EE_Form_Section_Base) {
1528
+			return $input;
1529
+		}
1530
+		$next_slash_pos = strpos($form_section_path, '/');
1531
+		if ($next_slash_pos !== false) {
1532
+			$child_section_name = substr($form_section_path, 0, $next_slash_pos);
1533
+			$subpath            = substr($form_section_path, $next_slash_pos + 1);
1534
+		} else {
1535
+			$child_section_name = $form_section_path;
1536
+			$subpath            = '';
1537
+		}
1538
+		$child_section = $this->get_subsection($child_section_name);
1539
+		if ($child_section instanceof EE_Form_Section_Base) {
1540
+			return $child_section->find_section_from_path($subpath);
1541
+		}
1542
+		return null;
1543
+	}
1544 1544
 }
Please login to merge, or discard this patch.