Completed
Branch master (8de7dd)
by
unknown
06:29
created
form_sections/strategies/display/EE_Display_Strategy_Base.strategy.php 1 patch
Indentation   +242 added lines, -242 removed lines patch added patch discarded remove patch
@@ -10,246 +10,246 @@
 block discarded – undo
10 10
  */
11 11
 abstract class EE_Display_Strategy_Base extends EE_Form_Input_Strategy_Base
12 12
 {
13
-    /**
14
-     * @var string $_tag
15
-     */
16
-    protected string $_tag = '';
17
-
18
-
19
-    /**
20
-     * returns HTML and javascript related to the displaying of this input
21
-     *
22
-     * @return string
23
-     */
24
-    abstract public function display(): string;
25
-
26
-
27
-    /**
28
-     * _remove_chars - takes an incoming string, and removes the string $chars from the end of it, but only if $chars
29
-     * is already there
30
-     *
31
-     * @param string $string - the string being processed
32
-     * @param string $chars  - exact string of characters to remove
33
-     * @return string
34
-     */
35
-    protected function _remove_chars(string $string = '', string $chars = '-'): string
36
-    {
37
-        $char_length = strlen($chars) * -1;
38
-        // if last three characters of string is  " - ", then remove it
39
-        return substr($string, $char_length) === $chars
40
-            ? substr($string, 0, $char_length)
41
-            : $string;
42
-    }
43
-
44
-
45
-    /**
46
-     * _append_chars - takes an incoming string, and adds the string $chars to the end of it, but only if $chars is not
47
-     * already there
48
-     *
49
-     * @param string $string - the string being processed
50
-     * @param string $chars  - exact string of characters to be added to end of string
51
-     * @return string
52
-     */
53
-    protected function _append_chars(string $string = '', string $chars = '-'): string
54
-    {
55
-        return $this->_remove_chars($string, $chars) . $chars;
56
-    }
57
-
58
-
59
-    /**
60
-     * Gets the HTML IDs of all the inputs
61
-     *
62
-     * @param bool $add_pound_sign
63
-     * @return array
64
-     * @throws EE_Error
65
-     */
66
-    public function get_html_input_ids(bool $add_pound_sign = false): array
67
-    {
68
-        return [$this->get_input()->html_id($add_pound_sign)];
69
-    }
70
-
71
-
72
-    /**
73
-     * Adds js variables for localization to the $other_js_data. These should be put
74
-     * in each form's "other_data" javascript object.
75
-     *
76
-     * @param array $other_js_data
77
-     * @return array
78
-     */
79
-    public function get_other_js_data(array $other_js_data = []): array
80
-    {
81
-        return $other_js_data;
82
-    }
83
-
84
-
85
-    /**
86
-     * Opportunity for this display strategy to call wp_enqueue_script and wp_enqueue_style.
87
-     * This should be called during wp_enqueue_scripts
88
-     */
89
-    public function enqueue_js()
90
-    {
91
-    }
92
-
93
-
94
-    /**
95
-     * returns string like: '<tag'
96
-     *
97
-     * @param string $tag
98
-     * @return string
99
-     */
100
-    protected function _opening_tag(string $tag): string
101
-    {
102
-        $this->_tag = $tag;
103
-        return "<$this->_tag";
104
-    }
105
-
106
-
107
-    /**
108
-     * returns string like: '</tag>
109
-     *
110
-     * @return string
111
-     */
112
-    protected function _closing_tag(): string
113
-    {
114
-        return "</$this->_tag>";
115
-    }
116
-
117
-
118
-    /**
119
-     * returns string like: '/>'
120
-     *
121
-     * @return string
122
-     */
123
-    protected function _close_tag(): string
124
-    {
125
-        return '/>';
126
-    }
127
-
128
-
129
-    /**
130
-     * returns an array of standard HTML attributes that get added to nearly all inputs,
131
-     * where string keys represent named attributes like id, class, etc
132
-     * and numeric keys represent single attributes like 'required'.
133
-     * Note: this does not include "value" because many inputs (like dropdowns, textareas, and checkboxes) don't use
134
-     * it.
135
-     *
136
-     * @return array
137
-     * @throws EE_Error
138
-     */
139
-    protected function _standard_attributes_array(): array
140
-    {
141
-        $attributes = [
142
-            'name'  => $this->_input->html_name(),
143
-            'id'    => $this->_input->html_id(),
144
-            'class' => $this->_input->html_class(true),
145
-            0       => ['required', $this->_input->required()],
146
-            1       => $this->_input->other_html_attributes(),
147
-            'style' => $this->_input->html_style(),
148
-        ];
149
-        if ($this->_input->hasLabel()) {
150
-            $attributes['aria-labelledby'] = $this->_input->html_label_id();
151
-        }
152
-        return $attributes;
153
-    }
154
-
155
-
156
-    /**
157
-     * sets the attributes using the incoming array
158
-     * and returns a string of all attributes rendered as valid HTML
159
-     *
160
-     * @param array $attributes
161
-     * @return string
162
-     */
163
-    protected function _attributes_string(array $attributes = []): string
164
-    {
165
-        $attributes        = apply_filters(
166
-            'FHEE__EE_Display_Strategy_Base__attributes_string__attributes',
167
-            $attributes,
168
-            $this,
169
-            $this->_input
170
-        );
171
-        $attributes_string = '';
172
-        foreach ($attributes as $attribute => $value) {
173
-            if ($attribute !== 'value' && empty($value)) {
174
-                continue;
175
-            }
176
-            if (is_numeric($attribute)) {
177
-                $add = true;
178
-                if (is_array($value)) {
179
-                    $attribute = $value[0] ?? '';
180
-                    $add       = $value[1] ?? false;
181
-                } else {
182
-                    $attribute = $value;
183
-                }
184
-                $attributes_string .= $this->_single_attribute($attribute, $add);
185
-            } else {
186
-                $attributes_string .= $this->_attribute($attribute, $value);
187
-            }
188
-        }
189
-        return $attributes_string;
190
-    }
191
-
192
-
193
-    /**
194
-     * returns string like: ' attribute="value"'
195
-     * returns an empty string if $value is null
196
-     *
197
-     * @param string $attribute
198
-     * @param string $value
199
-     * @return string
200
-     */
201
-    protected function _attribute(string $attribute, string $value = ''): string
202
-    {
203
-        if ($value === null) {
204
-            return '';
205
-        }
206
-        $value = esc_attr(trim($value));
207
-        // don't add the attribute if the value is empty, unless the attribute is 'value'
208
-        return $value || $attribute === 'value' ? " $attribute=\"$value\"" : '';
209
-    }
210
-
211
-
212
-    /**
213
-     * returns string like: ' data-attribute-one="value-one" data-attribute-two="value-two"'
214
-     *
215
-     * @param array $data
216
-     * @return string
217
-     */
218
-    protected function dataAttributesString(array $data): string
219
-    {
220
-        $data_attributes = '';
221
-        foreach ($data as $attribute => $value) {
222
-            $data_attributes .= $this->_data_attribute($attribute, $value);
223
-        }
224
-        return $data_attributes;
225
-    }
226
-
227
-
228
-    /**
229
-     * returns string like: ' data-attribute="value"'
230
-     * returns an empty string if $value is null
231
-     *
232
-     * @param string $attribute
233
-     * @param string $value
234
-     * @return string
235
-     */
236
-    protected function _data_attribute(string $attribute, string $value = ''): string
237
-    {
238
-        $attribute = strpos($attribute, 'data-') !== 0 ? "data-$attribute" : $attribute;
239
-        return $this->_attribute($attribute, $value);
240
-    }
241
-
242
-
243
-    /**
244
-     * returns string like: ' attribute' if $add is true
245
-     *
246
-     * @param string  $attribute
247
-     * @param boolean $add
248
-     * @return string
249
-     */
250
-    protected function _single_attribute(string $attribute, bool $add = true): string
251
-    {
252
-        $attribute = trim($attribute);
253
-        return $attribute && $add ? " $attribute" : '';
254
-    }
13
+	/**
14
+	 * @var string $_tag
15
+	 */
16
+	protected string $_tag = '';
17
+
18
+
19
+	/**
20
+	 * returns HTML and javascript related to the displaying of this input
21
+	 *
22
+	 * @return string
23
+	 */
24
+	abstract public function display(): string;
25
+
26
+
27
+	/**
28
+	 * _remove_chars - takes an incoming string, and removes the string $chars from the end of it, but only if $chars
29
+	 * is already there
30
+	 *
31
+	 * @param string $string - the string being processed
32
+	 * @param string $chars  - exact string of characters to remove
33
+	 * @return string
34
+	 */
35
+	protected function _remove_chars(string $string = '', string $chars = '-'): string
36
+	{
37
+		$char_length = strlen($chars) * -1;
38
+		// if last three characters of string is  " - ", then remove it
39
+		return substr($string, $char_length) === $chars
40
+			? substr($string, 0, $char_length)
41
+			: $string;
42
+	}
43
+
44
+
45
+	/**
46
+	 * _append_chars - takes an incoming string, and adds the string $chars to the end of it, but only if $chars is not
47
+	 * already there
48
+	 *
49
+	 * @param string $string - the string being processed
50
+	 * @param string $chars  - exact string of characters to be added to end of string
51
+	 * @return string
52
+	 */
53
+	protected function _append_chars(string $string = '', string $chars = '-'): string
54
+	{
55
+		return $this->_remove_chars($string, $chars) . $chars;
56
+	}
57
+
58
+
59
+	/**
60
+	 * Gets the HTML IDs of all the inputs
61
+	 *
62
+	 * @param bool $add_pound_sign
63
+	 * @return array
64
+	 * @throws EE_Error
65
+	 */
66
+	public function get_html_input_ids(bool $add_pound_sign = false): array
67
+	{
68
+		return [$this->get_input()->html_id($add_pound_sign)];
69
+	}
70
+
71
+
72
+	/**
73
+	 * Adds js variables for localization to the $other_js_data. These should be put
74
+	 * in each form's "other_data" javascript object.
75
+	 *
76
+	 * @param array $other_js_data
77
+	 * @return array
78
+	 */
79
+	public function get_other_js_data(array $other_js_data = []): array
80
+	{
81
+		return $other_js_data;
82
+	}
83
+
84
+
85
+	/**
86
+	 * Opportunity for this display strategy to call wp_enqueue_script and wp_enqueue_style.
87
+	 * This should be called during wp_enqueue_scripts
88
+	 */
89
+	public function enqueue_js()
90
+	{
91
+	}
92
+
93
+
94
+	/**
95
+	 * returns string like: '<tag'
96
+	 *
97
+	 * @param string $tag
98
+	 * @return string
99
+	 */
100
+	protected function _opening_tag(string $tag): string
101
+	{
102
+		$this->_tag = $tag;
103
+		return "<$this->_tag";
104
+	}
105
+
106
+
107
+	/**
108
+	 * returns string like: '</tag>
109
+	 *
110
+	 * @return string
111
+	 */
112
+	protected function _closing_tag(): string
113
+	{
114
+		return "</$this->_tag>";
115
+	}
116
+
117
+
118
+	/**
119
+	 * returns string like: '/>'
120
+	 *
121
+	 * @return string
122
+	 */
123
+	protected function _close_tag(): string
124
+	{
125
+		return '/>';
126
+	}
127
+
128
+
129
+	/**
130
+	 * returns an array of standard HTML attributes that get added to nearly all inputs,
131
+	 * where string keys represent named attributes like id, class, etc
132
+	 * and numeric keys represent single attributes like 'required'.
133
+	 * Note: this does not include "value" because many inputs (like dropdowns, textareas, and checkboxes) don't use
134
+	 * it.
135
+	 *
136
+	 * @return array
137
+	 * @throws EE_Error
138
+	 */
139
+	protected function _standard_attributes_array(): array
140
+	{
141
+		$attributes = [
142
+			'name'  => $this->_input->html_name(),
143
+			'id'    => $this->_input->html_id(),
144
+			'class' => $this->_input->html_class(true),
145
+			0       => ['required', $this->_input->required()],
146
+			1       => $this->_input->other_html_attributes(),
147
+			'style' => $this->_input->html_style(),
148
+		];
149
+		if ($this->_input->hasLabel()) {
150
+			$attributes['aria-labelledby'] = $this->_input->html_label_id();
151
+		}
152
+		return $attributes;
153
+	}
154
+
155
+
156
+	/**
157
+	 * sets the attributes using the incoming array
158
+	 * and returns a string of all attributes rendered as valid HTML
159
+	 *
160
+	 * @param array $attributes
161
+	 * @return string
162
+	 */
163
+	protected function _attributes_string(array $attributes = []): string
164
+	{
165
+		$attributes        = apply_filters(
166
+			'FHEE__EE_Display_Strategy_Base__attributes_string__attributes',
167
+			$attributes,
168
+			$this,
169
+			$this->_input
170
+		);
171
+		$attributes_string = '';
172
+		foreach ($attributes as $attribute => $value) {
173
+			if ($attribute !== 'value' && empty($value)) {
174
+				continue;
175
+			}
176
+			if (is_numeric($attribute)) {
177
+				$add = true;
178
+				if (is_array($value)) {
179
+					$attribute = $value[0] ?? '';
180
+					$add       = $value[1] ?? false;
181
+				} else {
182
+					$attribute = $value;
183
+				}
184
+				$attributes_string .= $this->_single_attribute($attribute, $add);
185
+			} else {
186
+				$attributes_string .= $this->_attribute($attribute, $value);
187
+			}
188
+		}
189
+		return $attributes_string;
190
+	}
191
+
192
+
193
+	/**
194
+	 * returns string like: ' attribute="value"'
195
+	 * returns an empty string if $value is null
196
+	 *
197
+	 * @param string $attribute
198
+	 * @param string $value
199
+	 * @return string
200
+	 */
201
+	protected function _attribute(string $attribute, string $value = ''): string
202
+	{
203
+		if ($value === null) {
204
+			return '';
205
+		}
206
+		$value = esc_attr(trim($value));
207
+		// don't add the attribute if the value is empty, unless the attribute is 'value'
208
+		return $value || $attribute === 'value' ? " $attribute=\"$value\"" : '';
209
+	}
210
+
211
+
212
+	/**
213
+	 * returns string like: ' data-attribute-one="value-one" data-attribute-two="value-two"'
214
+	 *
215
+	 * @param array $data
216
+	 * @return string
217
+	 */
218
+	protected function dataAttributesString(array $data): string
219
+	{
220
+		$data_attributes = '';
221
+		foreach ($data as $attribute => $value) {
222
+			$data_attributes .= $this->_data_attribute($attribute, $value);
223
+		}
224
+		return $data_attributes;
225
+	}
226
+
227
+
228
+	/**
229
+	 * returns string like: ' data-attribute="value"'
230
+	 * returns an empty string if $value is null
231
+	 *
232
+	 * @param string $attribute
233
+	 * @param string $value
234
+	 * @return string
235
+	 */
236
+	protected function _data_attribute(string $attribute, string $value = ''): string
237
+	{
238
+		$attribute = strpos($attribute, 'data-') !== 0 ? "data-$attribute" : $attribute;
239
+		return $this->_attribute($attribute, $value);
240
+	}
241
+
242
+
243
+	/**
244
+	 * returns string like: ' attribute' if $add is true
245
+	 *
246
+	 * @param string  $attribute
247
+	 * @param boolean $add
248
+	 * @return string
249
+	 */
250
+	protected function _single_attribute(string $attribute, bool $add = true): string
251
+	{
252
+		$attribute = trim($attribute);
253
+		return $attribute && $add ? " $attribute" : '';
254
+	}
255 255
 }
Please login to merge, or discard this patch.
strategies/display/EE_Admin_File_Uploader_Display_Strategy.strategy.php 2 patches
Indentation   +92 added lines, -92 removed lines patch added patch discarded remove patch
@@ -10,103 +10,103 @@
 block discarded – undo
10 10
  */
11 11
 class EE_Admin_File_Uploader_Display_Strategy extends EE_Display_Strategy_Base
12 12
 {
13
-    /**
14
-     * Its important this media only get enqueued AFTER init, but before the footer... where the
15
-     * rest of our forms JS gets enqueued. Otherwise the JS gets enqueued fine, and loaded on the page fine,
16
-     * but when you upload an image it gets uploaded fine to the server, but it doesn't display and reports an error
17
-     * (also it doesn't show any of the currently existing media in the modal window that pops up when you click the
18
-     * button to select media). Besides that, no special consideration should be required to make the media uploader
19
-     * appear, besides having this input displayed.
20
-     *
21
-     * @deprecated enqueue_js should be called automatically now
22
-     */
23
-    public static function enqueue_scripts()
24
-    {
25
-        EE_Error::doing_it_wrong(
26
-            __FUNCTION__,
27
-            esc_html__(
28
-                'EE_Admin_File_Uploader_Display_Strategy::enqueue_scripts() no longer needs to be called in order to display the admin uploader input correctly. This is handled now by EE_Admin_File_Uploader_Display_Strategy::enqueue_js() which is called automatically when enqueueing JS and CSS for the form',
29
-                'event_espresso'
30
-            ),
31
-            '4.9.8.rc.015'
32
-        );
33
-        wp_enqueue_media();
34
-        wp_enqueue_script('media-upload');
35
-        wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL . 'scripts/ee-media-uploader.js');
36
-    }
13
+	/**
14
+	 * Its important this media only get enqueued AFTER init, but before the footer... where the
15
+	 * rest of our forms JS gets enqueued. Otherwise the JS gets enqueued fine, and loaded on the page fine,
16
+	 * but when you upload an image it gets uploaded fine to the server, but it doesn't display and reports an error
17
+	 * (also it doesn't show any of the currently existing media in the modal window that pops up when you click the
18
+	 * button to select media). Besides that, no special consideration should be required to make the media uploader
19
+	 * appear, besides having this input displayed.
20
+	 *
21
+	 * @deprecated enqueue_js should be called automatically now
22
+	 */
23
+	public static function enqueue_scripts()
24
+	{
25
+		EE_Error::doing_it_wrong(
26
+			__FUNCTION__,
27
+			esc_html__(
28
+				'EE_Admin_File_Uploader_Display_Strategy::enqueue_scripts() no longer needs to be called in order to display the admin uploader input correctly. This is handled now by EE_Admin_File_Uploader_Display_Strategy::enqueue_js() which is called automatically when enqueueing JS and CSS for the form',
29
+				'event_espresso'
30
+			),
31
+			'4.9.8.rc.015'
32
+		);
33
+		wp_enqueue_media();
34
+		wp_enqueue_script('media-upload');
35
+		wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL . 'scripts/ee-media-uploader.js');
36
+	}
37 37
 
38 38
 
39
-    /**
40
-     * Enqueues the JS and CSS needed to display this input
41
-     */
42
-    public function enqueue_js()
43
-    {
44
-        wp_enqueue_media();
45
-        wp_enqueue_script('media-upload');
46
-        wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL . 'scripts/ee-media-uploader.js');
47
-        parent::enqueue_js();
48
-    }
39
+	/**
40
+	 * Enqueues the JS and CSS needed to display this input
41
+	 */
42
+	public function enqueue_js()
43
+	{
44
+		wp_enqueue_media();
45
+		wp_enqueue_script('media-upload');
46
+		wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL . 'scripts/ee-media-uploader.js');
47
+		parent::enqueue_js();
48
+	}
49 49
 
50 50
 
51
-    /**
52
-     * @return string of html to display the field
53
-     * @throws EE_Error
54
-     */
51
+	/**
52
+	 * @return string of html to display the field
53
+	 * @throws EE_Error
54
+	 */
55 55
 
56
-    public function display(): string
57
-    {
58
-        // the actual input
59
-        $input = '<input type="text" size="34" ';
60
-        $input .= 'name="' . $this->_input->html_name() . '" ';
61
-        $input .= $this->_input->html_class() !== ''
62
-            ? 'class="large-text ee_media_url ' . $this->_input->html_class() . '" '
63
-            : 'class="large-text ee_media_url" ';
64
-        if ($this->_input->hasLabel()) {
65
-            $input .= ' aria-labelledby="' . $this->_input->html_label_id() . '"';
66
-        }
67
-        $input .= 'value="' . $this->_input->raw_value_in_form() . '" ';
68
-        $input .= $this->_input->other_html_attributes();
69
-        $input .= $this->dataAttributesString($this->_input->dataAttributes());
70
-        $input .= '>';
71
-        // image uploader
72
-        $uploader = EEH_HTML::link(
73
-            '#',
74
-            '<span class="dashicons dashicons-format-image"></span>',
75
-            esc_html__('click to add an image', 'event_espresso'),
76
-            '',
77
-            'ee_media_upload button button--secondary button--icon-only'
78
-        );
79
-        // only attempt to show the image if it at least exists
80
-        $image = $this->_input->raw_value() && $this->src_exists($this->_input->raw_value())
81
-            ? EEH_HTML::br() . EEH_HTML::img(
82
-                $this->_input->raw_value(),
83
-                esc_html__('logo', 'event_espresso'),
84
-                '',
85
-                'ee_media_image'
86
-            )
87
-            : '';
88
-        // html string
89
-        return EEH_HTML::div(
90
-            $input . $uploader,
91
-            '',
92
-            'ee_media_uploader_area'
93
-        ) . $image;
94
-    }
56
+	public function display(): string
57
+	{
58
+		// the actual input
59
+		$input = '<input type="text" size="34" ';
60
+		$input .= 'name="' . $this->_input->html_name() . '" ';
61
+		$input .= $this->_input->html_class() !== ''
62
+			? 'class="large-text ee_media_url ' . $this->_input->html_class() . '" '
63
+			: 'class="large-text ee_media_url" ';
64
+		if ($this->_input->hasLabel()) {
65
+			$input .= ' aria-labelledby="' . $this->_input->html_label_id() . '"';
66
+		}
67
+		$input .= 'value="' . $this->_input->raw_value_in_form() . '" ';
68
+		$input .= $this->_input->other_html_attributes();
69
+		$input .= $this->dataAttributesString($this->_input->dataAttributes());
70
+		$input .= '>';
71
+		// image uploader
72
+		$uploader = EEH_HTML::link(
73
+			'#',
74
+			'<span class="dashicons dashicons-format-image"></span>',
75
+			esc_html__('click to add an image', 'event_espresso'),
76
+			'',
77
+			'ee_media_upload button button--secondary button--icon-only'
78
+		);
79
+		// only attempt to show the image if it at least exists
80
+		$image = $this->_input->raw_value() && $this->src_exists($this->_input->raw_value())
81
+			? EEH_HTML::br() . EEH_HTML::img(
82
+				$this->_input->raw_value(),
83
+				esc_html__('logo', 'event_espresso'),
84
+				'',
85
+				'ee_media_image'
86
+			)
87
+			: '';
88
+		// html string
89
+		return EEH_HTML::div(
90
+			$input . $uploader,
91
+			'',
92
+			'ee_media_uploader_area'
93
+		) . $image;
94
+	}
95 95
 
96 96
 
97
-    /**
98
-     * Asserts an image actually exists as quickly as possible by sending a HEAD
99
-     * request
100
-     *
101
-     * @param string $src
102
-     * @return boolean
103
-     */
104
-    protected function src_exists(string $src): bool
105
-    {
106
-        $results = wp_remote_head($src);
107
-        if (is_array($results) && ! $results instanceof WP_Error) {
108
-            return strpos($results['headers']['content-type'], "image") !== false;
109
-        }
110
-        return false;
111
-    }
97
+	/**
98
+	 * Asserts an image actually exists as quickly as possible by sending a HEAD
99
+	 * request
100
+	 *
101
+	 * @param string $src
102
+	 * @return boolean
103
+	 */
104
+	protected function src_exists(string $src): bool
105
+	{
106
+		$results = wp_remote_head($src);
107
+		if (is_array($results) && ! $results instanceof WP_Error) {
108
+			return strpos($results['headers']['content-type'], "image") !== false;
109
+		}
110
+		return false;
111
+	}
112 112
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
         );
33 33
         wp_enqueue_media();
34 34
         wp_enqueue_script('media-upload');
35
-        wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL . 'scripts/ee-media-uploader.js');
35
+        wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL.'scripts/ee-media-uploader.js');
36 36
     }
37 37
 
38 38
 
@@ -43,7 +43,7 @@  discard block
 block discarded – undo
43 43
     {
44 44
         wp_enqueue_media();
45 45
         wp_enqueue_script('media-upload');
46
-        wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL . 'scripts/ee-media-uploader.js');
46
+        wp_enqueue_script('ee-payments', EE_GLOBAL_ASSETS_URL.'scripts/ee-media-uploader.js');
47 47
         parent::enqueue_js();
48 48
     }
49 49
 
@@ -57,14 +57,14 @@  discard block
 block discarded – undo
57 57
     {
58 58
         // the actual input
59 59
         $input = '<input type="text" size="34" ';
60
-        $input .= 'name="' . $this->_input->html_name() . '" ';
60
+        $input .= 'name="'.$this->_input->html_name().'" ';
61 61
         $input .= $this->_input->html_class() !== ''
62
-            ? 'class="large-text ee_media_url ' . $this->_input->html_class() . '" '
62
+            ? 'class="large-text ee_media_url '.$this->_input->html_class().'" '
63 63
             : 'class="large-text ee_media_url" ';
64 64
         if ($this->_input->hasLabel()) {
65
-            $input .= ' aria-labelledby="' . $this->_input->html_label_id() . '"';
65
+            $input .= ' aria-labelledby="'.$this->_input->html_label_id().'"';
66 66
         }
67
-        $input .= 'value="' . $this->_input->raw_value_in_form() . '" ';
67
+        $input .= 'value="'.$this->_input->raw_value_in_form().'" ';
68 68
         $input .= $this->_input->other_html_attributes();
69 69
         $input .= $this->dataAttributesString($this->_input->dataAttributes());
70 70
         $input .= '>';
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
         );
79 79
         // only attempt to show the image if it at least exists
80 80
         $image = $this->_input->raw_value() && $this->src_exists($this->_input->raw_value())
81
-            ? EEH_HTML::br() . EEH_HTML::img(
81
+            ? EEH_HTML::br().EEH_HTML::img(
82 82
                 $this->_input->raw_value(),
83 83
                 esc_html__('logo', 'event_espresso'),
84 84
                 '',
@@ -87,10 +87,10 @@  discard block
 block discarded – undo
87 87
             : '';
88 88
         // html string
89 89
         return EEH_HTML::div(
90
-            $input . $uploader,
90
+            $input.$uploader,
91 91
             '',
92 92
             'ee_media_uploader_area'
93
-        ) . $image;
93
+        ).$image;
94 94
     }
95 95
 
96 96
 
Please login to merge, or discard this patch.
strategies/display/EE_Submit_Input_Display_Strategy.strategy.php 2 patches
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -9,32 +9,32 @@
 block discarded – undo
9 9
  */
10 10
 class EE_Submit_Input_Display_Strategy extends EE_Display_Strategy_Base
11 11
 {
12
-    /**
13
-     * @return string of html to display the input
14
-     * @throws EE_Error
15
-     */
16
-    public function display(): string
17
-    {
18
-        $this->_input->set_html_id($this->_input->html_id() . '-submit');
19
-        $default_value = $this->_input->get_default();
20
-        if ($this->_input->get_normalization_strategy() instanceof EE_Normalization_Strategy_Base) {
21
-            $default_value = $this->_input->get_normalization_strategy()->unnormalize($default_value);
22
-        }
23
-        $html = $this->_opening_tag('input');
24
-        $html .= $this->_attributes_string(
25
-            array_merge(
26
-                $this->_standard_attributes_array(),
27
-                [
28
-                    'type'  => 'submit',
29
-                    'value' => $default_value,
30
-                    // overwrite the standard id with the backwards compatible one
31
-                    'id'    => $this->_input->html_id(),
32
-                    'class' => $this->_input->html_class() . ' ' . $this->_input->button_css_attributes(),
33
-                ]
34
-            )
35
-        );
36
-        $html .= $this->dataAttributesString($this->_input->dataAttributes());
37
-        $html .= $this->_close_tag();
38
-        return $html;
39
-    }
12
+	/**
13
+	 * @return string of html to display the input
14
+	 * @throws EE_Error
15
+	 */
16
+	public function display(): string
17
+	{
18
+		$this->_input->set_html_id($this->_input->html_id() . '-submit');
19
+		$default_value = $this->_input->get_default();
20
+		if ($this->_input->get_normalization_strategy() instanceof EE_Normalization_Strategy_Base) {
21
+			$default_value = $this->_input->get_normalization_strategy()->unnormalize($default_value);
22
+		}
23
+		$html = $this->_opening_tag('input');
24
+		$html .= $this->_attributes_string(
25
+			array_merge(
26
+				$this->_standard_attributes_array(),
27
+				[
28
+					'type'  => 'submit',
29
+					'value' => $default_value,
30
+					// overwrite the standard id with the backwards compatible one
31
+					'id'    => $this->_input->html_id(),
32
+					'class' => $this->_input->html_class() . ' ' . $this->_input->button_css_attributes(),
33
+				]
34
+			)
35
+		);
36
+		$html .= $this->dataAttributesString($this->_input->dataAttributes());
37
+		$html .= $this->_close_tag();
38
+		return $html;
39
+	}
40 40
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -15,7 +15,7 @@  discard block
 block discarded – undo
15 15
      */
16 16
     public function display(): string
17 17
     {
18
-        $this->_input->set_html_id($this->_input->html_id() . '-submit');
18
+        $this->_input->set_html_id($this->_input->html_id().'-submit');
19 19
         $default_value = $this->_input->get_default();
20 20
         if ($this->_input->get_normalization_strategy() instanceof EE_Normalization_Strategy_Base) {
21 21
             $default_value = $this->_input->get_normalization_strategy()->unnormalize($default_value);
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
                     'value' => $default_value,
30 30
                     // overwrite the standard id with the backwards compatible one
31 31
                     'id'    => $this->_input->html_id(),
32
-                    'class' => $this->_input->html_class() . ' ' . $this->_input->button_css_attributes(),
32
+                    'class' => $this->_input->html_class().' '.$this->_input->button_css_attributes(),
33 33
                 ]
34 34
             )
35 35
         );
Please login to merge, or discard this patch.
strategies/validation/EE_Enum_Validation_Strategy.strategy.php 2 patches
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -11,55 +11,55 @@
 block discarded – undo
11 11
  */
12 12
 class EE_Enum_Validation_Strategy extends EE_Validation_Strategy_Base
13 13
 {
14
-    /**
15
-     * Check that the value is in the allowed list
16
-     * @param $normalized_value
17
-     * @throws EE_Error
18
-     * @throws EE_Validation_Error
19
-     * @return boolean
20
-     */
21
-    public function validate($normalized_value)
22
-    {
23
-        parent::validate($normalized_value);
24
-        if (! $this->_input instanceof EE_Form_Input_With_Options_Base) {
25
-            throw new EE_Error(
26
-                esc_html__(
27
-                    "Cannot use Enum Validation Strategy with an input that doesn't have options",
28
-                    "event_espresso"
29
-                )
30
-            );
31
-        }
32
-        $enum_options = $this->_input->flat_options();
33
-        if ($normalized_value === true) {
34
-            $normalized_value = 1;
35
-        } elseif ($normalized_value === false) {
36
-            $normalized_value = 0;
37
-        }
38
-        if ($normalized_value !== null && ! array_key_exists($normalized_value, $enum_options)) {
39
-            throw new EE_Validation_Error(
40
-                $this->get_validation_error_message(),
41
-                'invalid_enum_value'
42
-            );
43
-        }
44
-        return true;
45
-    }
14
+	/**
15
+	 * Check that the value is in the allowed list
16
+	 * @param $normalized_value
17
+	 * @throws EE_Error
18
+	 * @throws EE_Validation_Error
19
+	 * @return boolean
20
+	 */
21
+	public function validate($normalized_value)
22
+	{
23
+		parent::validate($normalized_value);
24
+		if (! $this->_input instanceof EE_Form_Input_With_Options_Base) {
25
+			throw new EE_Error(
26
+				esc_html__(
27
+					"Cannot use Enum Validation Strategy with an input that doesn't have options",
28
+					"event_espresso"
29
+				)
30
+			);
31
+		}
32
+		$enum_options = $this->_input->flat_options();
33
+		if ($normalized_value === true) {
34
+			$normalized_value = 1;
35
+		} elseif ($normalized_value === false) {
36
+			$normalized_value = 0;
37
+		}
38
+		if ($normalized_value !== null && ! array_key_exists($normalized_value, $enum_options)) {
39
+			throw new EE_Validation_Error(
40
+				$this->get_validation_error_message(),
41
+				'invalid_enum_value'
42
+			);
43
+		}
44
+		return true;
45
+	}
46 46
 
47
-    /**
48
-     * If we are using the default validation error message, make it dynamic based
49
-     * on the allowed options.
50
-     * @return string
51
-     */
52
-    public function get_validation_error_message()
53
-    {
54
-        $parent_validation_error_message = parent::get_validation_error_message();
55
-        if (! $parent_validation_error_message) {
56
-            $enum_options = $this->_input instanceof EE_Form_Input_With_Options_Base ? $this->_input->flat_options() : '';
57
-            return sprintf(
58
-                esc_html__("This is not allowed option. Allowed options are %s.", "event_espresso"),
59
-                implode(', ', $enum_options)
60
-            );
61
-        } else {
62
-            return $parent_validation_error_message;
63
-        }
64
-    }
47
+	/**
48
+	 * If we are using the default validation error message, make it dynamic based
49
+	 * on the allowed options.
50
+	 * @return string
51
+	 */
52
+	public function get_validation_error_message()
53
+	{
54
+		$parent_validation_error_message = parent::get_validation_error_message();
55
+		if (! $parent_validation_error_message) {
56
+			$enum_options = $this->_input instanceof EE_Form_Input_With_Options_Base ? $this->_input->flat_options() : '';
57
+			return sprintf(
58
+				esc_html__("This is not allowed option. Allowed options are %s.", "event_espresso"),
59
+				implode(', ', $enum_options)
60
+			);
61
+		} else {
62
+			return $parent_validation_error_message;
63
+		}
64
+	}
65 65
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
     public function validate($normalized_value)
22 22
     {
23 23
         parent::validate($normalized_value);
24
-        if (! $this->_input instanceof EE_Form_Input_With_Options_Base) {
24
+        if ( ! $this->_input instanceof EE_Form_Input_With_Options_Base) {
25 25
             throw new EE_Error(
26 26
                 esc_html__(
27 27
                     "Cannot use Enum Validation Strategy with an input that doesn't have options",
@@ -52,7 +52,7 @@  discard block
 block discarded – undo
52 52
     public function get_validation_error_message()
53 53
     {
54 54
         $parent_validation_error_message = parent::get_validation_error_message();
55
-        if (! $parent_validation_error_message) {
55
+        if ( ! $parent_validation_error_message) {
56 56
             $enum_options = $this->_input instanceof EE_Form_Input_With_Options_Base ? $this->_input->flat_options() : '';
57 57
             return sprintf(
58 58
                 esc_html__("This is not allowed option. Allowed options are %s.", "event_espresso"),
Please login to merge, or discard this patch.
core/libraries/form_sections/base/EE_Form_Section_HTML.form.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -10,47 +10,47 @@
 block discarded – undo
10 10
  */
11 11
 class EE_Form_Section_HTML extends EE_Form_Section_Base
12 12
 {
13
-    protected string $_html = '';
14
-
15
-    protected bool $add_wrapper = true;
16
-
17
-
18
-    /**
19
-     * @param string $html
20
-     * @param array  $options_array
21
-     */
22
-    public function __construct($html = '', array $options_array = [])
23
-    {
24
-        $this->_html = $html;
25
-        if (isset($options_array['add_wrapper'])) {
26
-            $this->setAddWrapper($options_array['add_wrapper']);
27
-            unset($options_array['add_wrapper']);
28
-        }
29
-        parent::__construct($options_array);
30
-    }
31
-
32
-
33
-    /**
34
-     * Returns the HTML
35
-     *
36
-     * @return string
37
-     */
38
-    public function get_html()
39
-    {
40
-        return $this->_html;
41
-    }
42
-
43
-
44
-    public function addWrapper(): bool
45
-    {
46
-        return $this->add_wrapper;
47
-    }
48
-
49
-
50
-    public function setAddWrapper($add_wrapper): void
51
-    {
52
-        $this->add_wrapper = filter_var($add_wrapper, FILTER_VALIDATE_BOOLEAN);
53
-    }
13
+	protected string $_html = '';
14
+
15
+	protected bool $add_wrapper = true;
16
+
17
+
18
+	/**
19
+	 * @param string $html
20
+	 * @param array  $options_array
21
+	 */
22
+	public function __construct($html = '', array $options_array = [])
23
+	{
24
+		$this->_html = $html;
25
+		if (isset($options_array['add_wrapper'])) {
26
+			$this->setAddWrapper($options_array['add_wrapper']);
27
+			unset($options_array['add_wrapper']);
28
+		}
29
+		parent::__construct($options_array);
30
+	}
31
+
32
+
33
+	/**
34
+	 * Returns the HTML
35
+	 *
36
+	 * @return string
37
+	 */
38
+	public function get_html()
39
+	{
40
+		return $this->_html;
41
+	}
42
+
43
+
44
+	public function addWrapper(): bool
45
+	{
46
+		return $this->add_wrapper;
47
+	}
48
+
49
+
50
+	public function setAddWrapper($add_wrapper): void
51
+	{
52
+		$this->add_wrapper = filter_var($add_wrapper, FILTER_VALIDATE_BOOLEAN);
53
+	}
54 54
 
55 55
 
56 56
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/base/EE_Form_Section_Proper.form.php 2 patches
Indentation   +1602 added lines, -1602 removed lines patch added patch discarded remove patch
@@ -16,1606 +16,1606 @@
 block discarded – undo
16 16
  */
17 17
 class EE_Form_Section_Proper extends EE_Form_Section_Validatable
18 18
 {
19
-    const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
20
-
21
-    /**
22
-     * Subsections
23
-     *
24
-     * @var EE_Form_Section_Validatable[]
25
-     */
26
-    protected $_subsections = array();
27
-
28
-    /**
29
-     * Strategy for laying out the form
30
-     *
31
-     * @var EE_Form_Section_Layout_Base
32
-     */
33
-    protected $_layout_strategy;
34
-
35
-    /**
36
-     * Whether or not this form has received and validated a form submission yet
37
-     *
38
-     * @var boolean
39
-     */
40
-    protected $_received_submission = false;
41
-
42
-    /**
43
-     * message displayed to users upon successful form submission
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_form_submission_success_message = '';
48
-
49
-    /**
50
-     * message displayed to users upon unsuccessful form submission
51
-     *
52
-     * @var string
53
-     */
54
-    protected $_form_submission_error_message = '';
55
-
56
-    /**
57
-     * @var array like post / request
58
-     */
59
-    protected $cached_request_data;
60
-
61
-    /**
62
-     * Stores whether this form (and its sub-sections) were found to be valid or not.
63
-     * Starts off as null, but once the form is validated, it set to either true or false
64
-     * @var boolean|null
65
-     */
66
-    protected $is_valid;
67
-
68
-    /**
69
-     * Stores all the data that will localized for form validation
70
-     *
71
-     * @var array
72
-     */
73
-    protected static $_js_localization = array();
74
-
75
-    /**
76
-     * whether or not the form's localized validation JS vars have been set
77
-     *
78
-     * @type boolean
79
-     */
80
-    protected static $_scripts_localized = false;
81
-
82
-
83
-    /**
84
-     * when constructing a proper form section, calls _construct_finalize on children
85
-     * so that they know who their parent is, and what name they've been given.
86
-     *
87
-     * @param array[] $options_array   {
88
-     * @type          $subsections     EE_Form_Section_Validatable[] where keys are the section's name
89
-     * @type          $include         string[] numerically-indexed where values are section names to be included,
90
-     *                                 and in that order. This is handy if you want
91
-     *                                 the subsections to be ordered differently than the default, and if you override
92
-     *                                 which fields are shown
93
-     * @type          $exclude         string[] values are subsections to be excluded. This is handy if you want
94
-     *                                 to remove certain default subsections (note: if you specify BOTH 'include' AND
95
-     *                                 'exclude', the inclusions will be applied first, and the exclusions will exclude
96
-     *                                 items from that list of inclusions)
97
-     * @type          $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
98
-     *                                 } @see EE_Form_Section_Validatable::__construct()
99
-     * @throws EE_Error
100
-     */
101
-    public function __construct($options_array = array())
102
-    {
103
-        $options_array = (array) apply_filters(
104
-            'FHEE__EE_Form_Section_Proper___construct__options_array',
105
-            $options_array,
106
-            $this
107
-        );
108
-        // call parent first, as it may be setting the name
109
-        parent::__construct($options_array);
110
-        // if they've included subsections in the constructor, add them now
111
-        if (isset($options_array['include'])) {
112
-            // we are going to make sure we ONLY have those subsections to include
113
-            // AND we are going to make sure they're in that specified order
114
-            $reordered_subsections = array();
115
-            foreach ($options_array['include'] as $input_name) {
116
-                if (isset($this->_subsections[ $input_name ])) {
117
-                    $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ];
118
-                }
119
-            }
120
-            $this->_subsections = $reordered_subsections;
121
-        }
122
-        if (isset($options_array['exclude'])) {
123
-            $exclude            = $options_array['exclude'];
124
-            $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
125
-        }
126
-        if (isset($options_array['layout_strategy'])) {
127
-            $this->_layout_strategy = $options_array['layout_strategy'];
128
-        }
129
-        if (! $this->_layout_strategy) {
130
-            $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
131
-        }
132
-        $this->_layout_strategy->_construct_finalize($this);
133
-        // ok so we are definitely going to want the forms JS,
134
-        // so enqueue it or remember to enqueue it during wp_enqueue_scripts
135
-        if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) {
136
-            // ok so they've constructed this object after when they should have.
137
-            // just enqueue the generic form scripts and initialize the form immediately in the JS
138
-            EE_Form_Section_Proper::wp_enqueue_scripts(true);
139
-        } else {
140
-            add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
141
-            add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
142
-        }
143
-        add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
144
-        /**
145
-         * Gives other plugins a chance to hook in before construct finalize is called.
146
-         * The form probably doesn't yet have a parent form section.
147
-         * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form,
148
-         * assuming you don't care what the form section's name, HTML ID, or HTML name etc are.
149
-         * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end
150
-         *
151
-         * @since 4.9.32
152
-         * @param EE_Form_Section_Proper $this          before __construct is done, but all of its logic,
153
-         *                                              except maybe calling _construct_finalize has been done
154
-         * @param array                  $options_array options passed into the constructor
155
-         */
156
-        do_action(
157
-            'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called',
158
-            $this,
159
-            $options_array
160
-        );
161
-        if (isset($options_array['name'])) {
162
-            $this->_construct_finalize(null, $options_array['name']);
163
-        }
164
-    }
165
-
166
-
167
-    /**
168
-     * Finishes construction given the parent form section and this form section's name
169
-     *
170
-     * @param EE_Form_Section_Proper|null $parent_form_section
171
-     * @param string                 $name
172
-     * @throws EE_Error
173
-     */
174
-    public function _construct_finalize($parent_form_section, $name)
175
-    {
176
-        parent::_construct_finalize($parent_form_section, $name);
177
-        $this->_set_default_name_if_empty();
178
-        $this->_set_default_html_id_if_empty();
179
-        foreach ($this->_subsections as $subsection_name => $subsection) {
180
-            if ($subsection instanceof EE_Form_Section_Base) {
181
-                $subsection->_construct_finalize($this, $subsection_name);
182
-            } else {
183
-                throw new EE_Error(
184
-                    sprintf(
185
-                        esc_html__(
186
-                            'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
187
-                            'event_espresso'
188
-                        ),
189
-                        $subsection_name,
190
-                        get_class($this),
191
-                        $subsection && is_object($subsection)
192
-                            ? get_class($subsection)
193
-                            : gettype($subsection)
194
-                    )
195
-                );
196
-            }
197
-        }
198
-        /**
199
-         * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed.
200
-         * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID
201
-         * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done.
202
-         * This might only happen just before displaying the form, or just before it receives form submission data.
203
-         * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've
204
-         * ensured it has a name, HTML IDs, etc
205
-         *
206
-         * @param EE_Form_Section_Proper      $this
207
-         * @param EE_Form_Section_Proper|null $parent_form_section
208
-         * @param string                      $name
209
-         */
210
-        do_action(
211
-            'AHEE__EE_Form_Section_Proper___construct_finalize__end',
212
-            $this,
213
-            $parent_form_section,
214
-            $name
215
-        );
216
-    }
217
-
218
-
219
-    /**
220
-     * Gets the layout strategy for this form section
221
-     *
222
-     * @return EE_Form_Section_Layout_Base
223
-     */
224
-    public function get_layout_strategy()
225
-    {
226
-        return $this->_layout_strategy;
227
-    }
228
-
229
-
230
-    /**
231
-     * Gets the HTML for a single input for this form section according
232
-     * to the layout strategy
233
-     *
234
-     * @param EE_Form_Input_Base $input
235
-     * @return string
236
-     */
237
-    public function get_html_for_input($input)
238
-    {
239
-        return $this->_layout_strategy->layout_input($input);
240
-    }
241
-
242
-
243
-    /**
244
-     * was_submitted - checks if form inputs are present in request data
245
-     * Basically an alias for form_data_present_in() (which is used by both
246
-     * proper form sections and form inputs)
247
-     *
248
-     * @param null $form_data
249
-     * @return boolean
250
-     * @throws EE_Error
251
-     */
252
-    public function was_submitted($form_data = null)
253
-    {
254
-        return $this->form_data_present_in($form_data);
255
-    }
256
-
257
-    /**
258
-     * Gets the cached request data; but if there is none, or $req_data was set with
259
-     * something different, refresh the cache, and then return it
260
-     * @param null $req_data
261
-     * @return array
262
-     */
263
-    protected function getCachedRequest($req_data = null)
264
-    {
265
-        if (
266
-            $this->cached_request_data === null
267
-            || (
268
-                $req_data !== null
269
-                && $req_data !== $this->cached_request_data
270
-            )
271
-        ) {
272
-            $req_data = apply_filters(
273
-                'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data',
274
-                $req_data,
275
-                $this
276
-            );
277
-            if ($req_data === null) {
278
-                /** @var RequestInterface $request */
279
-                $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
280
-                $req_data = $request->requestParams();
281
-            }
282
-            $req_data = apply_filters(
283
-                'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data',
284
-                $req_data,
285
-                $this
286
-            );
287
-            $this->cached_request_data = (array) $req_data;
288
-        }
289
-        return $this->cached_request_data;
290
-    }
291
-
292
-
293
-    /**
294
-     * After the form section is initially created, call this to sanitize the data in the submission
295
-     * which relates to this form section, validate it, and set it as properties on the form.
296
-     *
297
-     * @param array|null $req_data should usually be post data (the default).
298
-     *                             However, you CAN supply a different array.
299
-     *                             Consider using set_defaults() instead however.
300
-     *                             (If you rendered the form in the page using $form_x->get_html()
301
-     *                             the inputs will have the correct name in the request data for this function
302
-     *                             to find them and populate the form with them.
303
-     *                             If you have a flat form (with only input subsections),
304
-     *                             you can supply a flat array where keys
305
-     *                             are the form input names and values are their values)
306
-     * @param boolean    $validate whether or not to perform validation on this data. Default is,
307
-     *                             of course, to validate that data, and set errors on the invalid values.
308
-     *                             But if the data has already been validated
309
-     *                             (eg you validated the data then stored it in the DB)
310
-     *                             you may want to skip this step.
311
-     * @throws InvalidArgumentException
312
-     * @throws InvalidInterfaceException
313
-     * @throws InvalidDataTypeException
314
-     * @throws EE_Error
315
-     */
316
-    public function receive_form_submission($req_data = null, $validate = true)
317
-    {
318
-        $req_data = $this->getCachedRequest($req_data);
319
-        $this->_normalize($req_data);
320
-        if ($validate) {
321
-            $this->_validate();
322
-            // if it's invalid, we're going to want to re-display so remember what they submitted
323
-            if (! $this->is_valid()) {
324
-                $this->store_submitted_form_data_in_session();
325
-            }
326
-        }
327
-        if ($this->submission_error_message() === '' && ! $this->is_valid()) {
328
-            $this->set_submission_error_message();
329
-        }
330
-        do_action(
331
-            'AHEE__EE_Form_Section_Proper__receive_form_submission__end',
332
-            $req_data,
333
-            $this,
334
-            $validate
335
-        );
336
-    }
337
-
338
-
339
-    /**
340
-     * caches the originally submitted input values in the session
341
-     * so that they can be used to repopulate the form if it failed validation
342
-     *
343
-     * @return boolean whether or not the data was successfully stored in the session
344
-     * @throws InvalidArgumentException
345
-     * @throws InvalidInterfaceException
346
-     * @throws InvalidDataTypeException
347
-     * @throws EE_Error
348
-     */
349
-    protected function store_submitted_form_data_in_session()
350
-    {
351
-        $session = EE_Registry::instance()->SSN;
352
-        if ($session instanceof EE_Session) {
353
-            return EE_Registry::instance()->SSN->set_session_data(
354
-                [
355
-                    EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
356
-                ]
357
-            );
358
-        }
359
-        return false;
360
-    }
361
-
362
-
363
-    /**
364
-     * retrieves the originally submitted input values in the session
365
-     * so that they can be used to repopulate the form if it failed validation
366
-     *
367
-     * @return array
368
-     * @throws InvalidArgumentException
369
-     * @throws InvalidInterfaceException
370
-     * @throws InvalidDataTypeException
371
-     */
372
-    protected function get_submitted_form_data_from_session()
373
-    {
374
-        $session = EE_Registry::instance()->SSN;
375
-        if ($session instanceof EE_Session) {
376
-            return $session->get_session_data(
377
-                EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
378
-            );
379
-        }
380
-        return array();
381
-    }
382
-
383
-
384
-    /**
385
-     * flushed the originally submitted input values from the session
386
-     *
387
-     * @return boolean whether or not the data was successfully removed from the session
388
-     * @throws InvalidArgumentException
389
-     * @throws InvalidInterfaceException
390
-     * @throws InvalidDataTypeException
391
-     */
392
-    public static function flush_submitted_form_data_from_session()
393
-    {
394
-        return EE_Registry::instance()->SSN->reset_data(
395
-            [EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY]
396
-        );
397
-    }
398
-
399
-
400
-    /**
401
-     * Populates this form and its subsections with data from the session.
402
-     * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
403
-     * validation errors when displaying too)
404
-     * Returns true if the form was populated from the session, false otherwise
405
-     *
406
-     * @return boolean
407
-     * @throws InvalidArgumentException
408
-     * @throws InvalidInterfaceException
409
-     * @throws InvalidDataTypeException
410
-     * @throws EE_Error
411
-     */
412
-    public function populate_from_session()
413
-    {
414
-        $form_data_in_session = $this->get_submitted_form_data_from_session();
415
-        if (empty($form_data_in_session)) {
416
-            return false;
417
-        }
418
-        $this->receive_form_submission($form_data_in_session);
419
-        add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session'));
420
-        if ($this->form_data_present_in($form_data_in_session)) {
421
-            return true;
422
-        }
423
-        return false;
424
-    }
425
-
426
-
427
-    /**
428
-     * Populates the default data for the form, given an array where keys are
429
-     * the input names, and values are their values (preferably normalized to be their
430
-     * proper PHP types, not all strings... although that should be ok too).
431
-     * Proper subsections are sub-arrays, the key being the subsection's name, and
432
-     * the value being an array formatted in teh same way
433
-     *
434
-     * @param array $default_data
435
-     * @throws EE_Error
436
-     */
437
-    public function populate_defaults($default_data)
438
-    {
439
-        foreach ($this->subsections(false) as $subsection_name => $subsection) {
440
-            if (isset($default_data[ $subsection_name ])) {
441
-                if ($subsection instanceof EE_Form_Input_Base) {
442
-                    $subsection->set_default($default_data[ $subsection_name ]);
443
-                } elseif ($subsection instanceof EE_Form_Section_Proper) {
444
-                    $subsection->populate_defaults($default_data[ $subsection_name ]);
445
-                }
446
-            }
447
-        }
448
-    }
449
-
450
-
451
-    /**
452
-     * returns true if subsection exists
453
-     *
454
-     * @param string $name
455
-     * @return boolean
456
-     */
457
-    public function subsection_exists(string $name): bool
458
-    {
459
-        return isset($this->_subsections[ $name ]);
460
-    }
461
-
462
-
463
-    /**
464
-     * Gets the subsection specified by its name
465
-     *
466
-     * @param string  $name
467
-     * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
468
-     *                                                      so that the inputs will be properly configured.
469
-     *                                                      However, some client code may be ok
470
-     *                                                      with construction finalize being called later
471
-     *                                                      (realizing that the subsections' html names
472
-     *                                                      might not be set yet, etc.)
473
-     * @return EE_Form_Section_Base
474
-     * @throws EE_Error
475
-     */
476
-    public function get_subsection($name, $require_construction_to_be_finalized = true)
477
-    {
478
-        if ($require_construction_to_be_finalized) {
479
-            $this->ensure_construct_finalized_called();
480
-        }
481
-        return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null;
482
-    }
483
-
484
-
485
-    /**
486
-     * Gets all the validatable subsections of this form section
487
-     *
488
-     * @return EE_Form_Section_Validatable[]
489
-     * @throws EE_Error
490
-     */
491
-    public function get_validatable_subsections()
492
-    {
493
-        $validatable_subsections = array();
494
-        foreach ($this->subsections() as $name => $obj) {
495
-            if ($obj instanceof EE_Form_Section_Validatable) {
496
-                $validatable_subsections[ $name ] = $obj;
497
-            }
498
-        }
499
-        return $validatable_subsections;
500
-    }
501
-
502
-
503
-    /**
504
-     * Gets an input by the given name. If not found, or if it's not an EE_Form_Input_Base child,
505
-     * throw an EE_Error.
506
-     *
507
-     * @param string  $name
508
-     * @param boolean $require_construction_to_be_finalized most client code should
509
-     *                                                      leave this as TRUE so that the inputs will be properly
510
-     *                                                      configured. However, some client code may be ok with
511
-     *                                                      construction finalize being called later
512
-     *                                                      (realizing that the subsections' html names might not be
513
-     *                                                      set yet, etc.)
514
-     * @return EE_Form_Input_Base
515
-     * @throws EE_Error
516
-     */
517
-    public function get_input($name, $require_construction_to_be_finalized = true)
518
-    {
519
-        $subsection = $this->get_subsection(
520
-            $name,
521
-            $require_construction_to_be_finalized
522
-        );
523
-        if (! $subsection instanceof EE_Form_Input_Base) {
524
-            throw new EE_Error(
525
-                sprintf(
526
-                    esc_html__(
527
-                        "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
528
-                        'event_espresso'
529
-                    ),
530
-                    $name,
531
-                    get_class($this),
532
-                    $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
533
-                )
534
-            );
535
-        }
536
-        return $subsection;
537
-    }
538
-
539
-
540
-    /**
541
-     * drills down recursively through form subsections and finds the input with the given html name
542
-     *
543
-     * @param string $html_name
544
-     * @return EE_Form_Input_Base|null
545
-     * @throws EE_Error
546
-     * @since 5.0.30.p
547
-     */
548
-    public function findInput(string $html_name): ?EE_Form_Input_Base
549
-    {
550
-        // breadth first search
551
-        if ($this->subsection_exists($html_name)) {
552
-            return $this->_subsections[ $html_name ];
553
-        }
554
-        $input = null;
555
-        foreach ($this->subsections() as $subsection) {
556
-            if ($subsection instanceof EE_Form_Section_Proper) {
557
-                $input = $subsection->findInput($html_name);
558
-                if ($input !== null) {
559
-                    return $input;
560
-                }
561
-            } else if (
562
-                $subsection instanceof EE_Form_Input_Base
563
-                && $subsection->html_name() === $html_name
564
-            ) {
565
-                return $subsection;
566
-            }
567
-        }
568
-        return $input;
569
-    }
570
-
571
-
572
-    /**
573
-     * Like get_input(), gets the proper subsection of the form given the name,
574
-     * otherwise throws an EE_Error
575
-     *
576
-     * @param string  $name
577
-     * @param boolean $require_construction_to_be_finalized most client code should
578
-     *                                                      leave this as TRUE so that the inputs will be properly
579
-     *                                                      configured. However, some client code may be ok with
580
-     *                                                      construction finalize being called later
581
-     *                                                      (realizing that the subsections' html names might not be
582
-     *                                                      set yet, etc.)
583
-     * @return EE_Form_Section_Proper
584
-     * @throws EE_Error
585
-     */
586
-    public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
587
-    {
588
-        $subsection = $this->get_subsection(
589
-            $name,
590
-            $require_construction_to_be_finalized
591
-        );
592
-        if (! $subsection instanceof EE_Form_Section_Proper) {
593
-            throw new EE_Error(
594
-                sprintf(
595
-                    esc_html__(
596
-                        "Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'",
597
-                        'event_espresso'
598
-                    ),
599
-                    $name,
600
-                    get_class($this)
601
-                )
602
-            );
603
-        }
604
-        return $subsection;
605
-    }
606
-
607
-
608
-    /**
609
-     * Gets the value of the specified input. Should be called after receive_form_submission()
610
-     * or populate_defaults() on the form, where the normalized value on the input is set.
611
-     *
612
-     * @param string $name
613
-     * @return mixed depending on the input's type and its normalization strategy
614
-     * @throws EE_Error
615
-     */
616
-    public function get_input_value($name)
617
-    {
618
-        $input = $this->get_input($name);
619
-        return $input->normalized_value();
620
-    }
621
-
622
-
623
-    /**
624
-     * Checks if this form section itself is valid, and then checks its subsections
625
-     *
626
-     * @throws EE_Error
627
-     * @return boolean
628
-     */
629
-    public function is_valid()
630
-    {
631
-        if ($this->is_valid === null) {
632
-            if (! $this->has_received_submission()) {
633
-                throw new EE_Error(
634
-                    sprintf(
635
-                        esc_html__(
636
-                            'You cannot check if a form is valid before receiving the form submission using receive_form_submission',
637
-                            'event_espresso'
638
-                        )
639
-                    )
640
-                );
641
-            }
642
-            if (! parent::is_valid()) {
643
-                $this->is_valid = false;
644
-            } else {
645
-                // ok so no general errors to this entire form section.
646
-                // so let's check the subsections, but only set errors if that hasn't been done yet
647
-                $this->is_valid = true;
648
-                foreach ($this->get_validatable_subsections() as $subsection) {
649
-                    if (! $subsection->is_valid()) {
650
-                        $this->is_valid = false;
651
-                    }
652
-                }
653
-            }
654
-        }
655
-        return $this->is_valid;
656
-    }
657
-
658
-
659
-    /**
660
-     * gets the default name of this form section if none is specified
661
-     *
662
-     * @return void
663
-     */
664
-    protected function _set_default_name_if_empty()
665
-    {
666
-        if (! $this->_name) {
667
-            $classname    = get_class($this);
668
-            $default_name = str_replace('EE_', '', $classname);
669
-            $this->_name  = $default_name;
670
-        }
671
-    }
672
-
673
-
674
-    /**
675
-     * Returns the HTML for the form, except for the form opening and closing tags
676
-     * (as the form section doesn't know where you necessarily want to send the information to),
677
-     * and except for a submit button. Enqueues JS and CSS; if called early enough we will
678
-     * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
679
-     * Not doing_it_wrong because theoretically this CAN be used properly,
680
-     * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
681
-     * any CSS.
682
-     *
683
-     * @throws InvalidArgumentException
684
-     * @throws InvalidInterfaceException
685
-     * @throws InvalidDataTypeException
686
-     * @throws EE_Error
687
-     */
688
-    public function get_html_and_js()
689
-    {
690
-        $this->enqueue_js();
691
-        return $this->get_html();
692
-    }
693
-
694
-
695
-    /**
696
-     * returns HTML for displaying this form section. recursively calls display_section() on all subsections
697
-     *
698
-     * @param bool $display_previously_submitted_data
699
-     * @return string
700
-     * @throws InvalidArgumentException
701
-     * @throws InvalidInterfaceException
702
-     * @throws InvalidDataTypeException
703
-     * @throws EE_Error
704
-     * @throws EE_Error
705
-     * @throws EE_Error
706
-     */
707
-    public function get_html($display_previously_submitted_data = true)
708
-    {
709
-        $this->ensure_construct_finalized_called();
710
-        if ($display_previously_submitted_data) {
711
-            $this->populate_from_session();
712
-        }
713
-        return $this->_form_html_filter
714
-            ? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this)
715
-            : $this->_layout_strategy->layout_form();
716
-    }
717
-
718
-
719
-    /**
720
-     * enqueues JS and CSS for the form.
721
-     * It is preferred to call this before wp_enqueue_scripts so the
722
-     * scripts and styles can be put in the header, but if called later
723
-     * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
724
-     * only be in the header; but in HTML5 its ok in the body.
725
-     * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
726
-     * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
727
-     *
728
-     * @return void
729
-     * @throws EE_Error
730
-     */
731
-    public function enqueue_js()
732
-    {
733
-        $this->_enqueue_and_localize_form_js();
734
-        foreach ($this->subsections() as $subsection) {
735
-            $subsection->enqueue_js();
736
-        }
737
-    }
738
-
739
-
740
-    /**
741
-     * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
742
-     * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
743
-     * the wp_enqueue_scripts hook.
744
-     * However, registering the form js and localizing it can happen when we
745
-     * actually output the form (which is preferred, seeing how teh form's fields
746
-     * could change until it's actually outputted)
747
-     *
748
-     * @param boolean $init_form_validation_automatically whether or not we want the form validation
749
-     *                                                    to be triggered automatically or not
750
-     * @return void
751
-     */
752
-    public static function wp_enqueue_scripts($init_form_validation_automatically = true)
753
-    {
754
-        wp_register_script(
755
-            'ee_form_section_validation',
756
-            EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js',
757
-            [
758
-                JqueryAssetManager::JS_HANDLE_JQUERY_VALIDATE,
759
-                JqueryAssetManager::JS_HANDLE_JQUERY_UI_DATEPICKER,
760
-                JqueryAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA
761
-            ],
762
-            EVENT_ESPRESSO_VERSION,
763
-            true
764
-        );
765
-        wp_localize_script(
766
-            'ee_form_section_validation',
767
-            'ee_form_section_validation_init',
768
-            array('init' => $init_form_validation_automatically ? '1' : '0')
769
-        );
770
-    }
771
-
772
-
773
-    /**
774
-     * gets the variables used by form_section_validation.js.
775
-     * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
776
-     * but before the wordpress hook wp_loaded
777
-     *
778
-     * @throws EE_Error
779
-     */
780
-    public function _enqueue_and_localize_form_js()
781
-    {
782
-        $this->ensure_construct_finalized_called();
783
-        // actually, we don't want to localize just yet. There may be other forms on the page.
784
-        // so we need to add our form section data to a static variable accessible by all form sections
785
-        // and localize it just before the footer
786
-        $this->localize_validation_rules();
787
-        add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
788
-        add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
789
-    }
790
-
791
-
792
-    /**
793
-     * add our form section data to a static variable accessible by all form sections
794
-     *
795
-     * @param bool $return_for_subsection
796
-     * @return void
797
-     * @throws EE_Error
798
-     */
799
-    public function localize_validation_rules($return_for_subsection = false)
800
-    {
801
-        // we only want to localize vars ONCE for the entire form,
802
-        // so if the form section doesn't have a parent, then it must be the top dog
803
-        if ($return_for_subsection || ! $this->parent_section()) {
804
-            EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array(
805
-                'form_section_id'  => $this->html_id(true),
806
-                'validation_rules' => $this->get_jquery_validation_rules(),
807
-                'other_data'       => $this->get_other_js_data(),
808
-                'errors'           => $this->subsection_validation_errors_by_html_name(),
809
-            );
810
-            EE_Form_Section_Proper::$_scripts_localized                                = true;
811
-        }
812
-    }
813
-
814
-
815
-    /**
816
-     * Gets an array of extra data that will be useful for client-side javascript.
817
-     * This is primarily data added by inputs and forms in addition to any
818
-     * scripts they might enqueue
819
-     *
820
-     * @param array $form_other_js_data
821
-     * @return array
822
-     * @throws EE_Error
823
-     */
824
-    public function get_other_js_data($form_other_js_data = array())
825
-    {
826
-        foreach ($this->subsections() as $subsection) {
827
-            $form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
828
-        }
829
-        return $form_other_js_data;
830
-    }
831
-
832
-
833
-    /**
834
-     * Gets a flat array of inputs for this form section and its subsections.
835
-     * Keys are their form names, and values are the inputs themselves
836
-     *
837
-     * @return EE_Form_Input_Base
838
-     * @throws EE_Error
839
-     */
840
-    public function inputs_in_subsections()
841
-    {
842
-        $inputs = array();
843
-        foreach ($this->subsections() as $subsection) {
844
-            if ($subsection instanceof EE_Form_Input_Base) {
845
-                $inputs[ $subsection->html_name() ] = $subsection;
846
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
847
-                $inputs += $subsection->inputs_in_subsections();
848
-            }
849
-        }
850
-        return $inputs;
851
-    }
852
-
853
-
854
-    /**
855
-     * Gets a flat array of all the validation errors.
856
-     * Keys are html names (because those should be unique)
857
-     * and values are a string of all their validation errors
858
-     *
859
-     * @return string[]
860
-     * @throws EE_Error
861
-     */
862
-    public function subsection_validation_errors_by_html_name()
863
-    {
864
-        $inputs = $this->inputs();
865
-        $errors = array();
866
-        foreach ($inputs as $form_input) {
867
-            if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
868
-                $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string();
869
-            }
870
-        }
871
-        return $errors;
872
-    }
873
-
874
-
875
-    /**
876
-     * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
877
-     * Should be setup by each form during the _enqueues_and_localize_form_js
878
-     *
879
-     * @throws InvalidArgumentException
880
-     * @throws InvalidInterfaceException
881
-     * @throws InvalidDataTypeException
882
-     */
883
-    public static function localize_script_for_all_forms()
884
-    {
885
-        // allow inputs and stuff to hook in their JS and stuff here
886
-        do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
887
-        EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
888
-        $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
889
-            ? EE_Registry::instance()->CFG->registration->email_validation_level
890
-            : 'wp_default';
891
-        EE_Form_Section_Proper::$_js_localization['email_validation_level']   = $email_validation_level;
892
-        wp_enqueue_script('ee_form_section_validation');
893
-        wp_localize_script(
894
-            'ee_form_section_validation',
895
-            'ee_form_section_vars',
896
-            EE_Form_Section_Proper::$_js_localization
897
-        );
898
-    }
899
-
900
-
901
-    /**
902
-     * ensure_scripts_localized
903
-     *
904
-     * @throws EE_Error
905
-     */
906
-    public function ensure_scripts_localized()
907
-    {
908
-        if (! EE_Form_Section_Proper::$_scripts_localized) {
909
-            $this->_enqueue_and_localize_form_js();
910
-        }
911
-    }
912
-
913
-
914
-    /**
915
-     * Gets the hard-coded validation error messages to be used in the JS. The convention
916
-     * is that the key here should be the same as the custom validation rule put in the JS file
917
-     *
918
-     * @return array keys are custom validation rules, and values are internationalized strings
919
-     */
920
-    private static function _get_localized_error_messages()
921
-    {
922
-        return array(
923
-            'validUrl' => wp_strip_all_tags(__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso')),
924
-            'regex'    => wp_strip_all_tags(__('Please check your input', 'event_espresso'))
925
-        );
926
-    }
927
-
928
-
929
-    /**
930
-     * @return array
931
-     */
932
-    public static function js_localization()
933
-    {
934
-        return self::$_js_localization;
935
-    }
936
-
937
-
938
-    /**
939
-     * @return void
940
-     */
941
-    public static function reset_js_localization()
942
-    {
943
-        self::$_js_localization = array();
944
-    }
945
-
946
-
947
-    /**
948
-     * Gets the JS to put inside the jquery validation rules for subsection of this form section.
949
-     * See parent function for more...
950
-     *
951
-     * @return array
952
-     * @throws EE_Error
953
-     */
954
-    public function get_jquery_validation_rules()
955
-    {
956
-        $jquery_validation_rules = array();
957
-        foreach ($this->get_validatable_subsections() as $subsection) {
958
-            $jquery_validation_rules = array_merge(
959
-                $jquery_validation_rules,
960
-                $subsection->get_jquery_validation_rules()
961
-            );
962
-        }
963
-        return $jquery_validation_rules;
964
-    }
965
-
966
-
967
-    /**
968
-     * Sanitizes all the data and sets the sanitized value of each field
969
-     *
970
-     * @param array $req_data
971
-     * @return void
972
-     * @throws EE_Error
973
-     */
974
-    protected function _normalize($req_data)
975
-    {
976
-        $this->_received_submission = true;
977
-        $this->_validation_errors   = array();
978
-        foreach ($this->get_validatable_subsections() as $subsection) {
979
-            try {
980
-                $subsection->_normalize($req_data);
981
-            } catch (EE_Validation_Error $e) {
982
-                $subsection->add_validation_error($e);
983
-            }
984
-        }
985
-    }
986
-
987
-
988
-    /**
989
-     * Performs validation on this form section and its subsections.
990
-     * For each subsection,
991
-     * calls _validate_{subsection_name} on THIS form (if the function exists)
992
-     * and passes it the subsection, then calls _validate on that subsection.
993
-     * If you need to perform validation on the form as a whole (considering multiple)
994
-     * you would be best to override this _validate method,
995
-     * calling parent::_validate() first.
996
-     *
997
-     * @throws EE_Error
998
-     */
999
-    protected function _validate()
1000
-    {
1001
-        // reset the cache of whether this form is valid or not - we're re-validating it now
1002
-        $this->is_valid = null;
1003
-        foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
1004
-            if (method_exists($this, '_validate_' . $subsection_name)) {
1005
-                call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
1006
-            }
1007
-            $subsection->_validate();
1008
-        }
1009
-    }
1010
-
1011
-
1012
-    /**
1013
-     * Gets all the validated inputs for the form section
1014
-     *
1015
-     * @return array
1016
-     * @throws EE_Error
1017
-     */
1018
-    public function valid_data()
1019
-    {
1020
-        $inputs = array();
1021
-        foreach ($this->subsections() as $subsection_name => $subsection) {
1022
-            if ($subsection instanceof EE_Form_Section_Proper) {
1023
-                $inputs[ $subsection_name ] = $subsection->valid_data();
1024
-            } elseif ($subsection instanceof EE_Form_Input_Base) {
1025
-                $inputs[ $subsection_name ] = $subsection->normalized_value();
1026
-            }
1027
-        }
1028
-        return $inputs;
1029
-    }
1030
-
1031
-
1032
-    /**
1033
-     * Gets all the inputs on this form section
1034
-     *
1035
-     * @return EE_Form_Input_Base[]
1036
-     * @throws EE_Error
1037
-     */
1038
-    public function inputs()
1039
-    {
1040
-        $inputs = array();
1041
-        foreach ($this->subsections() as $subsection_name => $subsection) {
1042
-            if ($subsection instanceof EE_Form_Input_Base) {
1043
-                $inputs[ $subsection_name ] = $subsection;
1044
-            }
1045
-        }
1046
-        return $inputs;
1047
-    }
1048
-
1049
-
1050
-    /**
1051
-     * Gets all the subsections which are a proper form
1052
-     *
1053
-     * @return EE_Form_Section_Proper[]
1054
-     * @throws EE_Error
1055
-     */
1056
-    public function subforms()
1057
-    {
1058
-        $form_sections = array();
1059
-        foreach ($this->subsections() as $name => $obj) {
1060
-            if ($obj instanceof EE_Form_Section_Proper) {
1061
-                $form_sections[ $name ] = $obj;
1062
-            }
1063
-        }
1064
-        return $form_sections;
1065
-    }
1066
-
1067
-
1068
-    /**
1069
-     * Gets all the subsections (inputs, proper subsections, or html-only sections).
1070
-     * Consider using inputs() or subforms()
1071
-     * if you only want form inputs or proper form sections.
1072
-     *
1073
-     * @param boolean $require_construction_to_be_finalized most client code should
1074
-     *                                                      leave this as TRUE so that the inputs will be properly
1075
-     *                                                      configured. However, some client code may be ok with
1076
-     *                                                      construction finalize being called later
1077
-     *                                                      (realizing that the subsections' html names might not be
1078
-     *                                                      set yet, etc.)
1079
-     * @return EE_Form_Section_Proper[]
1080
-     * @throws EE_Error
1081
-     */
1082
-    public function subsections($require_construction_to_be_finalized = true)
1083
-    {
1084
-        if ($require_construction_to_be_finalized) {
1085
-            $this->ensure_construct_finalized_called();
1086
-        }
1087
-        return $this->_subsections;
1088
-    }
1089
-
1090
-
1091
-    /**
1092
-     * Returns whether this form has any subforms or inputs
1093
-     * @return bool
1094
-     */
1095
-    public function hasSubsections()
1096
-    {
1097
-        return ! empty($this->_subsections);
1098
-    }
1099
-
1100
-
1101
-    /**
1102
-     * Returns a simple array where keys are input names, and values are their normalized
1103
-     * values. (Similar to calling get_input_value on inputs)
1104
-     *
1105
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1106
-     *                                        or just this forms' direct children inputs
1107
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1108
-     *                                        or allow multidimensional array
1109
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
1110
-     *                                        with array keys being input names
1111
-     *                                        (regardless of whether they are from a subsection or not),
1112
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1113
-     *                                        where keys are always subsection names and values are either
1114
-     *                                        the input's normalized value, or an array like the top-level array
1115
-     * @throws EE_Error
1116
-     */
1117
-    public function input_values($include_subform_inputs = false, $flatten = false)
1118
-    {
1119
-        return $this->_input_values(false, $include_subform_inputs, $flatten);
1120
-    }
1121
-
1122
-
1123
-    /**
1124
-     * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
1125
-     * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
1126
-     * is not necessarily the value we want to display to users. This creates an array
1127
-     * where keys are the input names, and values are their display values
1128
-     *
1129
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1130
-     *                                        or just this forms' direct children inputs
1131
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1132
-     *                                        or allow multidimensional array
1133
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
1134
-     *                                        with array keys being input names
1135
-     *                                        (regardless of whether they are from a subsection or not),
1136
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1137
-     *                                        where keys are always subsection names and values are either
1138
-     *                                        the input's normalized value, or an array like the top-level array
1139
-     * @throws EE_Error
1140
-     */
1141
-    public function input_pretty_values($include_subform_inputs = false, $flatten = false)
1142
-    {
1143
-        return $this->_input_values(true, $include_subform_inputs, $flatten);
1144
-    }
1145
-
1146
-
1147
-    /**
1148
-     * Gets the input values from the form
1149
-     *
1150
-     * @param boolean $pretty                 Whether to retrieve the pretty value,
1151
-     *                                        or just the normalized value
1152
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1153
-     *                                        or just this forms' direct children inputs
1154
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1155
-     *                                        or allow multidimensional array
1156
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
1157
-     *                                        input names (regardless of whether they are from a subsection or not),
1158
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1159
-     *                                        where keys are always subsection names and values are either
1160
-     *                                        the input's normalized value, or an array like the top-level array
1161
-     * @throws EE_Error
1162
-     */
1163
-    public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
1164
-    {
1165
-        $input_values = array();
1166
-        foreach ($this->subsections() as $subsection_name => $subsection) {
1167
-            if ($subsection instanceof EE_Form_Input_Base) {
1168
-                $input_values[ $subsection_name ] = $pretty
1169
-                    ? $subsection->pretty_value()
1170
-                    : $subsection->normalized_value();
1171
-            } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1172
-                $subform_input_values = $subsection->_input_values(
1173
-                    $pretty,
1174
-                    $include_subform_inputs,
1175
-                    $flatten
1176
-                );
1177
-                if ($flatten) {
1178
-                    $input_values = array_merge($input_values, $subform_input_values);
1179
-                } else {
1180
-                    $input_values[ $subsection_name ] = $subform_input_values;
1181
-                }
1182
-            }
1183
-        }
1184
-        return $input_values;
1185
-    }
1186
-
1187
-
1188
-    /**
1189
-     * Gets the originally submitted input values from the form
1190
-     *
1191
-     * @param boolean $include_subforms  Whether to include inputs from subforms,
1192
-     *                                   or just this forms' direct children inputs
1193
-     * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1194
-     *                                   with array keys being input names
1195
-     *                                   (regardless of whether they are from a subsection or not),
1196
-     *                                   and if $flatten is FALSE it can be a multidimensional array
1197
-     *                                   where keys are always subsection names and values are either
1198
-     *                                   the input's normalized value, or an array like the top-level array
1199
-     * @throws EE_Error
1200
-     */
1201
-    public function submitted_values($include_subforms = false)
1202
-    {
1203
-        $submitted_values = array();
1204
-        foreach ($this->subsections() as $subsection) {
1205
-            if ($subsection instanceof EE_Form_Input_Base) {
1206
-                // is this input part of an array of inputs?
1207
-                if (strpos($subsection->html_name(), '[') !== false) {
1208
-                    $full_input_name  = EEH_Array::convert_array_values_to_keys(
1209
-                        explode(
1210
-                            '[',
1211
-                            str_replace(']', '', $subsection->html_name())
1212
-                        ),
1213
-                        $subsection->raw_value()
1214
-                    );
1215
-                    $submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1216
-                } else {
1217
-                    $submitted_values[ $subsection->html_name() ] = $subsection->raw_value();
1218
-                }
1219
-            } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1220
-                $subform_input_values = $subsection->submitted_values($include_subforms);
1221
-                $submitted_values     = array_replace_recursive($submitted_values, $subform_input_values);
1222
-            }
1223
-        }
1224
-        return $submitted_values;
1225
-    }
1226
-
1227
-
1228
-    /**
1229
-     * Indicates whether or not this form has received a submission yet
1230
-     * (ie, had receive_form_submission called on it yet)
1231
-     *
1232
-     * @return boolean
1233
-     * @throws EE_Error
1234
-     */
1235
-    public function has_received_submission()
1236
-    {
1237
-        $this->ensure_construct_finalized_called();
1238
-        return $this->_received_submission;
1239
-    }
1240
-
1241
-
1242
-    /**
1243
-     * Equivalent to passing 'exclude' in the constructor's options array.
1244
-     * Removes the listed inputs from the form
1245
-     *
1246
-     * @param array $inputs_to_exclude values are the input names
1247
-     * @return void
1248
-     */
1249
-    public function exclude(array $inputs_to_exclude = array())
1250
-    {
1251
-        foreach ($inputs_to_exclude as $input_to_exclude_name) {
1252
-            unset($this->_subsections[ $input_to_exclude_name ]);
1253
-        }
1254
-    }
1255
-
1256
-
1257
-    /**
1258
-     * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy.
1259
-     * @param array $inputs_to_hide
1260
-     * @throws EE_Error
1261
-     */
1262
-    public function hide(array $inputs_to_hide = array())
1263
-    {
1264
-        foreach ($inputs_to_hide as $input_to_hide) {
1265
-            $input = $this->get_input($input_to_hide);
1266
-            $input->set_display_strategy(new EE_Hidden_Display_Strategy());
1267
-        }
1268
-    }
1269
-
1270
-
1271
-    /**
1272
-     * add_subsections
1273
-     * Adds the listed subsections to the form section.
1274
-     * If $subsection_name_to_target is provided,
1275
-     * then new subsections are added before or after that subsection,
1276
-     * otherwise to the start or end of the entire subsections array.
1277
-     *
1278
-     * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1279
-     *                                                          where keys are their names
1280
-     * @param string|null            $subsection_name_to_target an existing form section that $new_subsections
1281
-     *                                                          should be added before or after
1282
-     *                                                          IF $subsection_name_to_target is null,
1283
-     *                                                          then $new_subsections will be added to
1284
-     *                                                          the beginning or end of the entire subsections array
1285
-     * @param boolean                $add_before                whether to add $new_subsections, before or after
1286
-     *                                                          $subsection_name_to_target,
1287
-     *                                                          or if $subsection_name_to_target is null,
1288
-     *                                                          before or after entire subsections array
1289
-     * @return void
1290
-     * @throws EE_Error
1291
-     */
1292
-    public function add_subsections(
1293
-        array $new_subsections,
1294
-        ?string $subsection_name_to_target = null,
1295
-        bool $add_before = true
1296
-    ) {
1297
-        foreach ($new_subsections as $subsection_name => $subsection) {
1298
-            if (! $subsection instanceof EE_Form_Section_Base) {
1299
-                EE_Error::add_error(
1300
-                    sprintf(
1301
-                        esc_html__(
1302
-                            "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1303
-                            'event_espresso'
1304
-                        ),
1305
-                        get_class($subsection),
1306
-                        $subsection_name,
1307
-                        $this->name()
1308
-                    ),
1309
-                    __FILE__,
1310
-                    __FUNCTION__,
1311
-                    __LINE__
1312
-                );
1313
-                unset($new_subsections[ $subsection_name ]);
1314
-            }
1315
-        }
1316
-        $this->_subsections = EEH_Array::insert_into_array(
1317
-            $this->_subsections,
1318
-            $new_subsections,
1319
-            $subsection_name_to_target,
1320
-            $add_before
1321
-        );
1322
-        if ($this->_construction_finalized) {
1323
-            foreach ($this->_subsections as $name => $subsection) {
1324
-                $subsection->_construct_finalize($this, $name);
1325
-            }
1326
-        }
1327
-    }
1328
-
1329
-
1330
-    /**
1331
-     * @param string $subsection_name
1332
-     * @param bool   $recursive
1333
-     * @return bool
1334
-     */
1335
-    public function has_subsection($subsection_name, $recursive = false)
1336
-    {
1337
-        foreach ($this->_subsections as $name => $subsection) {
1338
-            if (
1339
-                $name === $subsection_name
1340
-                || (
1341
-                    $recursive
1342
-                    && $subsection instanceof EE_Form_Section_Proper
1343
-                    && $subsection->has_subsection($subsection_name, $recursive)
1344
-                )
1345
-            ) {
1346
-                return true;
1347
-            }
1348
-        }
1349
-        return false;
1350
-    }
1351
-
1352
-
1353
-
1354
-    /**
1355
-     * Just gets all validatable subsections to clean their sensitive data
1356
-     *
1357
-     * @throws EE_Error
1358
-     */
1359
-    public function clean_sensitive_data()
1360
-    {
1361
-        foreach ($this->get_validatable_subsections() as $subsection) {
1362
-            $subsection->clean_sensitive_data();
1363
-        }
1364
-    }
1365
-
1366
-
1367
-    /**
1368
-     * Sets the submission error message (aka validation error message for this form section and all sub-sections)
1369
-     * @param string                           $form_submission_error_message
1370
-     * @param EE_Form_Section_Validatable $form_section unused
1371
-     * @throws EE_Error
1372
-     */
1373
-    public function set_submission_error_message(
1374
-        $form_submission_error_message = ''
1375
-    ) {
1376
-        $this->_form_submission_error_message = ! empty($form_submission_error_message)
1377
-            ? $form_submission_error_message
1378
-            : $this->getAllValidationErrorsString();
1379
-    }
1380
-
1381
-
1382
-    /**
1383
-     * Returns the cached error message. A default value is set for this during _validate(),
1384
-     * (called during receive_form_submission) but it can be explicitly set using
1385
-     * set_submission_error_message
1386
-     *
1387
-     * @return string
1388
-     */
1389
-    public function submission_error_message()
1390
-    {
1391
-        return $this->_form_submission_error_message;
1392
-    }
1393
-
1394
-
1395
-    /**
1396
-     * Sets a message to display if the data submitted to the form was valid.
1397
-     * @param string $form_submission_success_message
1398
-     */
1399
-    public function set_submission_success_message($form_submission_success_message = '')
1400
-    {
1401
-        $this->_form_submission_success_message = ! empty($form_submission_success_message)
1402
-            ? $form_submission_success_message
1403
-            : esc_html__('Form submitted successfully', 'event_espresso');
1404
-    }
1405
-
1406
-
1407
-    /**
1408
-     * Gets a message appropriate for display when the form is correctly submitted
1409
-     * @return string
1410
-     */
1411
-    public function submission_success_message()
1412
-    {
1413
-        return $this->_form_submission_success_message;
1414
-    }
1415
-
1416
-
1417
-    /**
1418
-     * Returns the prefix that should be used on child of this form section for
1419
-     * their html names. If this form section itself has a parent, prepends ITS
1420
-     * prefix onto this form section's prefix. Used primarily by
1421
-     * EE_Form_Input_Base::_set_default_html_name_if_empty
1422
-     *
1423
-     * @return string
1424
-     * @throws EE_Error
1425
-     */
1426
-    public function html_name_prefix()
1427
-    {
1428
-        if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1429
-            return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1430
-        }
1431
-        return $this->name();
1432
-    }
1433
-
1434
-
1435
-    /**
1436
-     * Gets the name, but first checks _construct_finalize has been called. If not,
1437
-     * calls it (assumes there is no parent and that we want the name to be whatever
1438
-     * was set, which is probably nothing, or the classname)
1439
-     *
1440
-     * @return string
1441
-     * @throws EE_Error
1442
-     */
1443
-    public function name()
1444
-    {
1445
-        $this->ensure_construct_finalized_called();
1446
-        return parent::name();
1447
-    }
1448
-
1449
-
1450
-    /**
1451
-     * @return EE_Form_Section_Proper
1452
-     * @throws EE_Error
1453
-     */
1454
-    public function parent_section()
1455
-    {
1456
-        $this->ensure_construct_finalized_called();
1457
-        return parent::parent_section();
1458
-    }
1459
-
1460
-
1461
-    /**
1462
-     * make sure construction finalized was called, otherwise children might not be ready
1463
-     *
1464
-     * @return void
1465
-     * @throws EE_Error
1466
-     */
1467
-    public function ensure_construct_finalized_called()
1468
-    {
1469
-        if (! $this->_construction_finalized) {
1470
-            $this->_construct_finalize($this->_parent_section, $this->_name);
1471
-        }
1472
-    }
1473
-
1474
-
1475
-    /**
1476
-     * Checks if any of this form section's inputs, or any of its children's inputs,
1477
-     * are in teh form data. If any are found, returns true. Else false
1478
-     *
1479
-     * @param array $req_data
1480
-     * @return boolean
1481
-     * @throws EE_Error
1482
-     */
1483
-    public function form_data_present_in($req_data = null)
1484
-    {
1485
-        $req_data = $this->getCachedRequest($req_data);
1486
-        foreach ($this->subsections() as $subsection) {
1487
-            if ($subsection instanceof EE_Form_Input_Base) {
1488
-                if ($subsection->form_data_present_in($req_data)) {
1489
-                    return true;
1490
-                }
1491
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
1492
-                if ($subsection->form_data_present_in($req_data)) {
1493
-                    return true;
1494
-                }
1495
-            }
1496
-        }
1497
-        return false;
1498
-    }
1499
-
1500
-
1501
-    /**
1502
-     * Gets validation errors for this form section and subsections
1503
-     * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1504
-     * gets the validation errors for ALL subsection
1505
-     *
1506
-     * @return EE_Validation_Error[]
1507
-     * @throws EE_Error
1508
-     */
1509
-    public function get_validation_errors_accumulated()
1510
-    {
1511
-        $validation_errors = $this->get_validation_errors();
1512
-        foreach ($this->get_validatable_subsections() as $subsection) {
1513
-            if ($subsection instanceof EE_Form_Section_Proper) {
1514
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1515
-            } else {
1516
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors();
1517
-            }
1518
-            if ($validation_errors_on_this_subsection) {
1519
-                $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1520
-            }
1521
-        }
1522
-        return $validation_errors;
1523
-    }
1524
-
1525
-    /**
1526
-     * Fetch validation errors from children and grandchildren and puts them in a single string.
1527
-     * This traverses the form section tree to generate this, but you probably want to instead use
1528
-     * get_form_submission_error_message() which is usually this message cached (or a custom validation error message)
1529
-     *
1530
-     * @return string
1531
-     * @since 4.9.59.p
1532
-     */
1533
-    protected function getAllValidationErrorsString()
1534
-    {
1535
-        $submission_error_messages = array();
1536
-        // bad, bad, bad registrant
1537
-        foreach ($this->get_validation_errors_accumulated() as $validation_error) {
1538
-            if ($validation_error instanceof EE_Validation_Error) {
1539
-                $form_section = $validation_error->get_form_section();
1540
-                if ($form_section instanceof EE_Form_Input_Base) {
1541
-                    $label = $validation_error->get_form_section()->html_label_text();
1542
-                } elseif ($form_section instanceof EE_Form_Section_Validatable) {
1543
-                    $label = $validation_error->get_form_section()->name();
1544
-                } else {
1545
-                    $label = esc_html__('Unknown', 'event_espresso');
1546
-                }
1547
-                $submission_error_messages[] = sprintf(
1548
-                    esc_html__('%s : %s', 'event_espresso'),
1549
-                    $label,
1550
-                    $validation_error->getMessage()
1551
-                );
1552
-            }
1553
-        }
1554
-        return implode('<br>', $submission_error_messages);
1555
-    }
1556
-
1557
-
1558
-    /**
1559
-     * This isn't just the name of an input, it's a path pointing to an input. The
1560
-     * path is similar to a folder path: slash (/) means to descend into a subsection,
1561
-     * dot-dot-slash (../) means to ascend into the parent section.
1562
-     * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1563
-     * which will be returned.
1564
-     * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1565
-     * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1566
-     * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1567
-     * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1568
-     * Etc
1569
-     *
1570
-     * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1571
-     * @return EE_Form_Section_Base
1572
-     * @throws EE_Error
1573
-     */
1574
-    public function find_section_from_path($form_section_path)
1575
-    {
1576
-        // check if we can find the input from purely going straight up the tree
1577
-        $input = parent::find_section_from_path($form_section_path);
1578
-        if ($input instanceof EE_Form_Section_Base) {
1579
-            return $input;
1580
-        }
1581
-        $next_slash_pos = strpos($form_section_path, '/');
1582
-        if ($next_slash_pos !== false) {
1583
-            $child_section_name = substr($form_section_path, 0, $next_slash_pos);
1584
-            $subpath            = substr($form_section_path, $next_slash_pos + 1);
1585
-        } else {
1586
-            $child_section_name = $form_section_path;
1587
-            $subpath            = '';
1588
-        }
1589
-        $child_section = $this->get_subsection($child_section_name);
1590
-        if ($child_section instanceof EE_Form_Section_Base) {
1591
-            return $child_section->find_section_from_path($subpath);
1592
-        }
1593
-        return null;
1594
-    }
1595
-
1596
-
1597
-    /**
1598
-     * @param EE_Form_Section_Base $form_section
1599
-     * @param int                  $depth
1600
-     * @return void
1601
-     * @throws EE_Error
1602
-     * @since 5.0.30.p
1603
-     */
1604
-    public static function visualize(EE_Form_Section_Base $form_section, int $depth = 0)
1605
-    {
1606
-        $indent = str_repeat(' .', $depth * 2);
1607
-        echo "$indent form_section: " . ($form_section->_name ?: get_class($form_section));
1608
-        $depth++;
1609
-        if ($form_section instanceof EE_Form_Section_Proper) {
1610
-            foreach ($form_section->_subsections as $subsection) {
1611
-                if ($subsection instanceof EE_Form_Section_Proper) {
1612
-                    self::visualize($subsection, $depth);
1613
-                } elseif ($subsection instanceof EE_Form_Input_Base) {
1614
-                    echo "$indent input: " . ($subsection->html_name() ?: get_class($subsection));
1615
-                } else {
1616
-                    echo "$indent input: " . ($subsection->_name ?: get_class($subsection));
1617
-                }
1618
-            }
1619
-        }
1620
-    }
19
+	const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
20
+
21
+	/**
22
+	 * Subsections
23
+	 *
24
+	 * @var EE_Form_Section_Validatable[]
25
+	 */
26
+	protected $_subsections = array();
27
+
28
+	/**
29
+	 * Strategy for laying out the form
30
+	 *
31
+	 * @var EE_Form_Section_Layout_Base
32
+	 */
33
+	protected $_layout_strategy;
34
+
35
+	/**
36
+	 * Whether or not this form has received and validated a form submission yet
37
+	 *
38
+	 * @var boolean
39
+	 */
40
+	protected $_received_submission = false;
41
+
42
+	/**
43
+	 * message displayed to users upon successful form submission
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_form_submission_success_message = '';
48
+
49
+	/**
50
+	 * message displayed to users upon unsuccessful form submission
51
+	 *
52
+	 * @var string
53
+	 */
54
+	protected $_form_submission_error_message = '';
55
+
56
+	/**
57
+	 * @var array like post / request
58
+	 */
59
+	protected $cached_request_data;
60
+
61
+	/**
62
+	 * Stores whether this form (and its sub-sections) were found to be valid or not.
63
+	 * Starts off as null, but once the form is validated, it set to either true or false
64
+	 * @var boolean|null
65
+	 */
66
+	protected $is_valid;
67
+
68
+	/**
69
+	 * Stores all the data that will localized for form validation
70
+	 *
71
+	 * @var array
72
+	 */
73
+	protected static $_js_localization = array();
74
+
75
+	/**
76
+	 * whether or not the form's localized validation JS vars have been set
77
+	 *
78
+	 * @type boolean
79
+	 */
80
+	protected static $_scripts_localized = false;
81
+
82
+
83
+	/**
84
+	 * when constructing a proper form section, calls _construct_finalize on children
85
+	 * so that they know who their parent is, and what name they've been given.
86
+	 *
87
+	 * @param array[] $options_array   {
88
+	 * @type          $subsections     EE_Form_Section_Validatable[] where keys are the section's name
89
+	 * @type          $include         string[] numerically-indexed where values are section names to be included,
90
+	 *                                 and in that order. This is handy if you want
91
+	 *                                 the subsections to be ordered differently than the default, and if you override
92
+	 *                                 which fields are shown
93
+	 * @type          $exclude         string[] values are subsections to be excluded. This is handy if you want
94
+	 *                                 to remove certain default subsections (note: if you specify BOTH 'include' AND
95
+	 *                                 'exclude', the inclusions will be applied first, and the exclusions will exclude
96
+	 *                                 items from that list of inclusions)
97
+	 * @type          $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
98
+	 *                                 } @see EE_Form_Section_Validatable::__construct()
99
+	 * @throws EE_Error
100
+	 */
101
+	public function __construct($options_array = array())
102
+	{
103
+		$options_array = (array) apply_filters(
104
+			'FHEE__EE_Form_Section_Proper___construct__options_array',
105
+			$options_array,
106
+			$this
107
+		);
108
+		// call parent first, as it may be setting the name
109
+		parent::__construct($options_array);
110
+		// if they've included subsections in the constructor, add them now
111
+		if (isset($options_array['include'])) {
112
+			// we are going to make sure we ONLY have those subsections to include
113
+			// AND we are going to make sure they're in that specified order
114
+			$reordered_subsections = array();
115
+			foreach ($options_array['include'] as $input_name) {
116
+				if (isset($this->_subsections[ $input_name ])) {
117
+					$reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ];
118
+				}
119
+			}
120
+			$this->_subsections = $reordered_subsections;
121
+		}
122
+		if (isset($options_array['exclude'])) {
123
+			$exclude            = $options_array['exclude'];
124
+			$this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
125
+		}
126
+		if (isset($options_array['layout_strategy'])) {
127
+			$this->_layout_strategy = $options_array['layout_strategy'];
128
+		}
129
+		if (! $this->_layout_strategy) {
130
+			$this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
131
+		}
132
+		$this->_layout_strategy->_construct_finalize($this);
133
+		// ok so we are definitely going to want the forms JS,
134
+		// so enqueue it or remember to enqueue it during wp_enqueue_scripts
135
+		if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) {
136
+			// ok so they've constructed this object after when they should have.
137
+			// just enqueue the generic form scripts and initialize the form immediately in the JS
138
+			EE_Form_Section_Proper::wp_enqueue_scripts(true);
139
+		} else {
140
+			add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
141
+			add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
142
+		}
143
+		add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
144
+		/**
145
+		 * Gives other plugins a chance to hook in before construct finalize is called.
146
+		 * The form probably doesn't yet have a parent form section.
147
+		 * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form,
148
+		 * assuming you don't care what the form section's name, HTML ID, or HTML name etc are.
149
+		 * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end
150
+		 *
151
+		 * @since 4.9.32
152
+		 * @param EE_Form_Section_Proper $this          before __construct is done, but all of its logic,
153
+		 *                                              except maybe calling _construct_finalize has been done
154
+		 * @param array                  $options_array options passed into the constructor
155
+		 */
156
+		do_action(
157
+			'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called',
158
+			$this,
159
+			$options_array
160
+		);
161
+		if (isset($options_array['name'])) {
162
+			$this->_construct_finalize(null, $options_array['name']);
163
+		}
164
+	}
165
+
166
+
167
+	/**
168
+	 * Finishes construction given the parent form section and this form section's name
169
+	 *
170
+	 * @param EE_Form_Section_Proper|null $parent_form_section
171
+	 * @param string                 $name
172
+	 * @throws EE_Error
173
+	 */
174
+	public function _construct_finalize($parent_form_section, $name)
175
+	{
176
+		parent::_construct_finalize($parent_form_section, $name);
177
+		$this->_set_default_name_if_empty();
178
+		$this->_set_default_html_id_if_empty();
179
+		foreach ($this->_subsections as $subsection_name => $subsection) {
180
+			if ($subsection instanceof EE_Form_Section_Base) {
181
+				$subsection->_construct_finalize($this, $subsection_name);
182
+			} else {
183
+				throw new EE_Error(
184
+					sprintf(
185
+						esc_html__(
186
+							'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
187
+							'event_espresso'
188
+						),
189
+						$subsection_name,
190
+						get_class($this),
191
+						$subsection && is_object($subsection)
192
+							? get_class($subsection)
193
+							: gettype($subsection)
194
+					)
195
+				);
196
+			}
197
+		}
198
+		/**
199
+		 * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed.
200
+		 * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID
201
+		 * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done.
202
+		 * This might only happen just before displaying the form, or just before it receives form submission data.
203
+		 * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've
204
+		 * ensured it has a name, HTML IDs, etc
205
+		 *
206
+		 * @param EE_Form_Section_Proper      $this
207
+		 * @param EE_Form_Section_Proper|null $parent_form_section
208
+		 * @param string                      $name
209
+		 */
210
+		do_action(
211
+			'AHEE__EE_Form_Section_Proper___construct_finalize__end',
212
+			$this,
213
+			$parent_form_section,
214
+			$name
215
+		);
216
+	}
217
+
218
+
219
+	/**
220
+	 * Gets the layout strategy for this form section
221
+	 *
222
+	 * @return EE_Form_Section_Layout_Base
223
+	 */
224
+	public function get_layout_strategy()
225
+	{
226
+		return $this->_layout_strategy;
227
+	}
228
+
229
+
230
+	/**
231
+	 * Gets the HTML for a single input for this form section according
232
+	 * to the layout strategy
233
+	 *
234
+	 * @param EE_Form_Input_Base $input
235
+	 * @return string
236
+	 */
237
+	public function get_html_for_input($input)
238
+	{
239
+		return $this->_layout_strategy->layout_input($input);
240
+	}
241
+
242
+
243
+	/**
244
+	 * was_submitted - checks if form inputs are present in request data
245
+	 * Basically an alias for form_data_present_in() (which is used by both
246
+	 * proper form sections and form inputs)
247
+	 *
248
+	 * @param null $form_data
249
+	 * @return boolean
250
+	 * @throws EE_Error
251
+	 */
252
+	public function was_submitted($form_data = null)
253
+	{
254
+		return $this->form_data_present_in($form_data);
255
+	}
256
+
257
+	/**
258
+	 * Gets the cached request data; but if there is none, or $req_data was set with
259
+	 * something different, refresh the cache, and then return it
260
+	 * @param null $req_data
261
+	 * @return array
262
+	 */
263
+	protected function getCachedRequest($req_data = null)
264
+	{
265
+		if (
266
+			$this->cached_request_data === null
267
+			|| (
268
+				$req_data !== null
269
+				&& $req_data !== $this->cached_request_data
270
+			)
271
+		) {
272
+			$req_data = apply_filters(
273
+				'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data',
274
+				$req_data,
275
+				$this
276
+			);
277
+			if ($req_data === null) {
278
+				/** @var RequestInterface $request */
279
+				$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
280
+				$req_data = $request->requestParams();
281
+			}
282
+			$req_data = apply_filters(
283
+				'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data',
284
+				$req_data,
285
+				$this
286
+			);
287
+			$this->cached_request_data = (array) $req_data;
288
+		}
289
+		return $this->cached_request_data;
290
+	}
291
+
292
+
293
+	/**
294
+	 * After the form section is initially created, call this to sanitize the data in the submission
295
+	 * which relates to this form section, validate it, and set it as properties on the form.
296
+	 *
297
+	 * @param array|null $req_data should usually be post data (the default).
298
+	 *                             However, you CAN supply a different array.
299
+	 *                             Consider using set_defaults() instead however.
300
+	 *                             (If you rendered the form in the page using $form_x->get_html()
301
+	 *                             the inputs will have the correct name in the request data for this function
302
+	 *                             to find them and populate the form with them.
303
+	 *                             If you have a flat form (with only input subsections),
304
+	 *                             you can supply a flat array where keys
305
+	 *                             are the form input names and values are their values)
306
+	 * @param boolean    $validate whether or not to perform validation on this data. Default is,
307
+	 *                             of course, to validate that data, and set errors on the invalid values.
308
+	 *                             But if the data has already been validated
309
+	 *                             (eg you validated the data then stored it in the DB)
310
+	 *                             you may want to skip this step.
311
+	 * @throws InvalidArgumentException
312
+	 * @throws InvalidInterfaceException
313
+	 * @throws InvalidDataTypeException
314
+	 * @throws EE_Error
315
+	 */
316
+	public function receive_form_submission($req_data = null, $validate = true)
317
+	{
318
+		$req_data = $this->getCachedRequest($req_data);
319
+		$this->_normalize($req_data);
320
+		if ($validate) {
321
+			$this->_validate();
322
+			// if it's invalid, we're going to want to re-display so remember what they submitted
323
+			if (! $this->is_valid()) {
324
+				$this->store_submitted_form_data_in_session();
325
+			}
326
+		}
327
+		if ($this->submission_error_message() === '' && ! $this->is_valid()) {
328
+			$this->set_submission_error_message();
329
+		}
330
+		do_action(
331
+			'AHEE__EE_Form_Section_Proper__receive_form_submission__end',
332
+			$req_data,
333
+			$this,
334
+			$validate
335
+		);
336
+	}
337
+
338
+
339
+	/**
340
+	 * caches the originally submitted input values in the session
341
+	 * so that they can be used to repopulate the form if it failed validation
342
+	 *
343
+	 * @return boolean whether or not the data was successfully stored in the session
344
+	 * @throws InvalidArgumentException
345
+	 * @throws InvalidInterfaceException
346
+	 * @throws InvalidDataTypeException
347
+	 * @throws EE_Error
348
+	 */
349
+	protected function store_submitted_form_data_in_session()
350
+	{
351
+		$session = EE_Registry::instance()->SSN;
352
+		if ($session instanceof EE_Session) {
353
+			return EE_Registry::instance()->SSN->set_session_data(
354
+				[
355
+					EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
356
+				]
357
+			);
358
+		}
359
+		return false;
360
+	}
361
+
362
+
363
+	/**
364
+	 * retrieves the originally submitted input values in the session
365
+	 * so that they can be used to repopulate the form if it failed validation
366
+	 *
367
+	 * @return array
368
+	 * @throws InvalidArgumentException
369
+	 * @throws InvalidInterfaceException
370
+	 * @throws InvalidDataTypeException
371
+	 */
372
+	protected function get_submitted_form_data_from_session()
373
+	{
374
+		$session = EE_Registry::instance()->SSN;
375
+		if ($session instanceof EE_Session) {
376
+			return $session->get_session_data(
377
+				EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
378
+			);
379
+		}
380
+		return array();
381
+	}
382
+
383
+
384
+	/**
385
+	 * flushed the originally submitted input values from the session
386
+	 *
387
+	 * @return boolean whether or not the data was successfully removed from the session
388
+	 * @throws InvalidArgumentException
389
+	 * @throws InvalidInterfaceException
390
+	 * @throws InvalidDataTypeException
391
+	 */
392
+	public static function flush_submitted_form_data_from_session()
393
+	{
394
+		return EE_Registry::instance()->SSN->reset_data(
395
+			[EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY]
396
+		);
397
+	}
398
+
399
+
400
+	/**
401
+	 * Populates this form and its subsections with data from the session.
402
+	 * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
403
+	 * validation errors when displaying too)
404
+	 * Returns true if the form was populated from the session, false otherwise
405
+	 *
406
+	 * @return boolean
407
+	 * @throws InvalidArgumentException
408
+	 * @throws InvalidInterfaceException
409
+	 * @throws InvalidDataTypeException
410
+	 * @throws EE_Error
411
+	 */
412
+	public function populate_from_session()
413
+	{
414
+		$form_data_in_session = $this->get_submitted_form_data_from_session();
415
+		if (empty($form_data_in_session)) {
416
+			return false;
417
+		}
418
+		$this->receive_form_submission($form_data_in_session);
419
+		add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session'));
420
+		if ($this->form_data_present_in($form_data_in_session)) {
421
+			return true;
422
+		}
423
+		return false;
424
+	}
425
+
426
+
427
+	/**
428
+	 * Populates the default data for the form, given an array where keys are
429
+	 * the input names, and values are their values (preferably normalized to be their
430
+	 * proper PHP types, not all strings... although that should be ok too).
431
+	 * Proper subsections are sub-arrays, the key being the subsection's name, and
432
+	 * the value being an array formatted in teh same way
433
+	 *
434
+	 * @param array $default_data
435
+	 * @throws EE_Error
436
+	 */
437
+	public function populate_defaults($default_data)
438
+	{
439
+		foreach ($this->subsections(false) as $subsection_name => $subsection) {
440
+			if (isset($default_data[ $subsection_name ])) {
441
+				if ($subsection instanceof EE_Form_Input_Base) {
442
+					$subsection->set_default($default_data[ $subsection_name ]);
443
+				} elseif ($subsection instanceof EE_Form_Section_Proper) {
444
+					$subsection->populate_defaults($default_data[ $subsection_name ]);
445
+				}
446
+			}
447
+		}
448
+	}
449
+
450
+
451
+	/**
452
+	 * returns true if subsection exists
453
+	 *
454
+	 * @param string $name
455
+	 * @return boolean
456
+	 */
457
+	public function subsection_exists(string $name): bool
458
+	{
459
+		return isset($this->_subsections[ $name ]);
460
+	}
461
+
462
+
463
+	/**
464
+	 * Gets the subsection specified by its name
465
+	 *
466
+	 * @param string  $name
467
+	 * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
468
+	 *                                                      so that the inputs will be properly configured.
469
+	 *                                                      However, some client code may be ok
470
+	 *                                                      with construction finalize being called later
471
+	 *                                                      (realizing that the subsections' html names
472
+	 *                                                      might not be set yet, etc.)
473
+	 * @return EE_Form_Section_Base
474
+	 * @throws EE_Error
475
+	 */
476
+	public function get_subsection($name, $require_construction_to_be_finalized = true)
477
+	{
478
+		if ($require_construction_to_be_finalized) {
479
+			$this->ensure_construct_finalized_called();
480
+		}
481
+		return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null;
482
+	}
483
+
484
+
485
+	/**
486
+	 * Gets all the validatable subsections of this form section
487
+	 *
488
+	 * @return EE_Form_Section_Validatable[]
489
+	 * @throws EE_Error
490
+	 */
491
+	public function get_validatable_subsections()
492
+	{
493
+		$validatable_subsections = array();
494
+		foreach ($this->subsections() as $name => $obj) {
495
+			if ($obj instanceof EE_Form_Section_Validatable) {
496
+				$validatable_subsections[ $name ] = $obj;
497
+			}
498
+		}
499
+		return $validatable_subsections;
500
+	}
501
+
502
+
503
+	/**
504
+	 * Gets an input by the given name. If not found, or if it's not an EE_Form_Input_Base child,
505
+	 * throw an EE_Error.
506
+	 *
507
+	 * @param string  $name
508
+	 * @param boolean $require_construction_to_be_finalized most client code should
509
+	 *                                                      leave this as TRUE so that the inputs will be properly
510
+	 *                                                      configured. However, some client code may be ok with
511
+	 *                                                      construction finalize being called later
512
+	 *                                                      (realizing that the subsections' html names might not be
513
+	 *                                                      set yet, etc.)
514
+	 * @return EE_Form_Input_Base
515
+	 * @throws EE_Error
516
+	 */
517
+	public function get_input($name, $require_construction_to_be_finalized = true)
518
+	{
519
+		$subsection = $this->get_subsection(
520
+			$name,
521
+			$require_construction_to_be_finalized
522
+		);
523
+		if (! $subsection instanceof EE_Form_Input_Base) {
524
+			throw new EE_Error(
525
+				sprintf(
526
+					esc_html__(
527
+						"Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
528
+						'event_espresso'
529
+					),
530
+					$name,
531
+					get_class($this),
532
+					$subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
533
+				)
534
+			);
535
+		}
536
+		return $subsection;
537
+	}
538
+
539
+
540
+	/**
541
+	 * drills down recursively through form subsections and finds the input with the given html name
542
+	 *
543
+	 * @param string $html_name
544
+	 * @return EE_Form_Input_Base|null
545
+	 * @throws EE_Error
546
+	 * @since 5.0.30.p
547
+	 */
548
+	public function findInput(string $html_name): ?EE_Form_Input_Base
549
+	{
550
+		// breadth first search
551
+		if ($this->subsection_exists($html_name)) {
552
+			return $this->_subsections[ $html_name ];
553
+		}
554
+		$input = null;
555
+		foreach ($this->subsections() as $subsection) {
556
+			if ($subsection instanceof EE_Form_Section_Proper) {
557
+				$input = $subsection->findInput($html_name);
558
+				if ($input !== null) {
559
+					return $input;
560
+				}
561
+			} else if (
562
+				$subsection instanceof EE_Form_Input_Base
563
+				&& $subsection->html_name() === $html_name
564
+			) {
565
+				return $subsection;
566
+			}
567
+		}
568
+		return $input;
569
+	}
570
+
571
+
572
+	/**
573
+	 * Like get_input(), gets the proper subsection of the form given the name,
574
+	 * otherwise throws an EE_Error
575
+	 *
576
+	 * @param string  $name
577
+	 * @param boolean $require_construction_to_be_finalized most client code should
578
+	 *                                                      leave this as TRUE so that the inputs will be properly
579
+	 *                                                      configured. However, some client code may be ok with
580
+	 *                                                      construction finalize being called later
581
+	 *                                                      (realizing that the subsections' html names might not be
582
+	 *                                                      set yet, etc.)
583
+	 * @return EE_Form_Section_Proper
584
+	 * @throws EE_Error
585
+	 */
586
+	public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
587
+	{
588
+		$subsection = $this->get_subsection(
589
+			$name,
590
+			$require_construction_to_be_finalized
591
+		);
592
+		if (! $subsection instanceof EE_Form_Section_Proper) {
593
+			throw new EE_Error(
594
+				sprintf(
595
+					esc_html__(
596
+						"Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'",
597
+						'event_espresso'
598
+					),
599
+					$name,
600
+					get_class($this)
601
+				)
602
+			);
603
+		}
604
+		return $subsection;
605
+	}
606
+
607
+
608
+	/**
609
+	 * Gets the value of the specified input. Should be called after receive_form_submission()
610
+	 * or populate_defaults() on the form, where the normalized value on the input is set.
611
+	 *
612
+	 * @param string $name
613
+	 * @return mixed depending on the input's type and its normalization strategy
614
+	 * @throws EE_Error
615
+	 */
616
+	public function get_input_value($name)
617
+	{
618
+		$input = $this->get_input($name);
619
+		return $input->normalized_value();
620
+	}
621
+
622
+
623
+	/**
624
+	 * Checks if this form section itself is valid, and then checks its subsections
625
+	 *
626
+	 * @throws EE_Error
627
+	 * @return boolean
628
+	 */
629
+	public function is_valid()
630
+	{
631
+		if ($this->is_valid === null) {
632
+			if (! $this->has_received_submission()) {
633
+				throw new EE_Error(
634
+					sprintf(
635
+						esc_html__(
636
+							'You cannot check if a form is valid before receiving the form submission using receive_form_submission',
637
+							'event_espresso'
638
+						)
639
+					)
640
+				);
641
+			}
642
+			if (! parent::is_valid()) {
643
+				$this->is_valid = false;
644
+			} else {
645
+				// ok so no general errors to this entire form section.
646
+				// so let's check the subsections, but only set errors if that hasn't been done yet
647
+				$this->is_valid = true;
648
+				foreach ($this->get_validatable_subsections() as $subsection) {
649
+					if (! $subsection->is_valid()) {
650
+						$this->is_valid = false;
651
+					}
652
+				}
653
+			}
654
+		}
655
+		return $this->is_valid;
656
+	}
657
+
658
+
659
+	/**
660
+	 * gets the default name of this form section if none is specified
661
+	 *
662
+	 * @return void
663
+	 */
664
+	protected function _set_default_name_if_empty()
665
+	{
666
+		if (! $this->_name) {
667
+			$classname    = get_class($this);
668
+			$default_name = str_replace('EE_', '', $classname);
669
+			$this->_name  = $default_name;
670
+		}
671
+	}
672
+
673
+
674
+	/**
675
+	 * Returns the HTML for the form, except for the form opening and closing tags
676
+	 * (as the form section doesn't know where you necessarily want to send the information to),
677
+	 * and except for a submit button. Enqueues JS and CSS; if called early enough we will
678
+	 * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
679
+	 * Not doing_it_wrong because theoretically this CAN be used properly,
680
+	 * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
681
+	 * any CSS.
682
+	 *
683
+	 * @throws InvalidArgumentException
684
+	 * @throws InvalidInterfaceException
685
+	 * @throws InvalidDataTypeException
686
+	 * @throws EE_Error
687
+	 */
688
+	public function get_html_and_js()
689
+	{
690
+		$this->enqueue_js();
691
+		return $this->get_html();
692
+	}
693
+
694
+
695
+	/**
696
+	 * returns HTML for displaying this form section. recursively calls display_section() on all subsections
697
+	 *
698
+	 * @param bool $display_previously_submitted_data
699
+	 * @return string
700
+	 * @throws InvalidArgumentException
701
+	 * @throws InvalidInterfaceException
702
+	 * @throws InvalidDataTypeException
703
+	 * @throws EE_Error
704
+	 * @throws EE_Error
705
+	 * @throws EE_Error
706
+	 */
707
+	public function get_html($display_previously_submitted_data = true)
708
+	{
709
+		$this->ensure_construct_finalized_called();
710
+		if ($display_previously_submitted_data) {
711
+			$this->populate_from_session();
712
+		}
713
+		return $this->_form_html_filter
714
+			? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this)
715
+			: $this->_layout_strategy->layout_form();
716
+	}
717
+
718
+
719
+	/**
720
+	 * enqueues JS and CSS for the form.
721
+	 * It is preferred to call this before wp_enqueue_scripts so the
722
+	 * scripts and styles can be put in the header, but if called later
723
+	 * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
724
+	 * only be in the header; but in HTML5 its ok in the body.
725
+	 * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
726
+	 * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
727
+	 *
728
+	 * @return void
729
+	 * @throws EE_Error
730
+	 */
731
+	public function enqueue_js()
732
+	{
733
+		$this->_enqueue_and_localize_form_js();
734
+		foreach ($this->subsections() as $subsection) {
735
+			$subsection->enqueue_js();
736
+		}
737
+	}
738
+
739
+
740
+	/**
741
+	 * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
742
+	 * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
743
+	 * the wp_enqueue_scripts hook.
744
+	 * However, registering the form js and localizing it can happen when we
745
+	 * actually output the form (which is preferred, seeing how teh form's fields
746
+	 * could change until it's actually outputted)
747
+	 *
748
+	 * @param boolean $init_form_validation_automatically whether or not we want the form validation
749
+	 *                                                    to be triggered automatically or not
750
+	 * @return void
751
+	 */
752
+	public static function wp_enqueue_scripts($init_form_validation_automatically = true)
753
+	{
754
+		wp_register_script(
755
+			'ee_form_section_validation',
756
+			EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js',
757
+			[
758
+				JqueryAssetManager::JS_HANDLE_JQUERY_VALIDATE,
759
+				JqueryAssetManager::JS_HANDLE_JQUERY_UI_DATEPICKER,
760
+				JqueryAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA
761
+			],
762
+			EVENT_ESPRESSO_VERSION,
763
+			true
764
+		);
765
+		wp_localize_script(
766
+			'ee_form_section_validation',
767
+			'ee_form_section_validation_init',
768
+			array('init' => $init_form_validation_automatically ? '1' : '0')
769
+		);
770
+	}
771
+
772
+
773
+	/**
774
+	 * gets the variables used by form_section_validation.js.
775
+	 * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
776
+	 * but before the wordpress hook wp_loaded
777
+	 *
778
+	 * @throws EE_Error
779
+	 */
780
+	public function _enqueue_and_localize_form_js()
781
+	{
782
+		$this->ensure_construct_finalized_called();
783
+		// actually, we don't want to localize just yet. There may be other forms on the page.
784
+		// so we need to add our form section data to a static variable accessible by all form sections
785
+		// and localize it just before the footer
786
+		$this->localize_validation_rules();
787
+		add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
788
+		add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
789
+	}
790
+
791
+
792
+	/**
793
+	 * add our form section data to a static variable accessible by all form sections
794
+	 *
795
+	 * @param bool $return_for_subsection
796
+	 * @return void
797
+	 * @throws EE_Error
798
+	 */
799
+	public function localize_validation_rules($return_for_subsection = false)
800
+	{
801
+		// we only want to localize vars ONCE for the entire form,
802
+		// so if the form section doesn't have a parent, then it must be the top dog
803
+		if ($return_for_subsection || ! $this->parent_section()) {
804
+			EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array(
805
+				'form_section_id'  => $this->html_id(true),
806
+				'validation_rules' => $this->get_jquery_validation_rules(),
807
+				'other_data'       => $this->get_other_js_data(),
808
+				'errors'           => $this->subsection_validation_errors_by_html_name(),
809
+			);
810
+			EE_Form_Section_Proper::$_scripts_localized                                = true;
811
+		}
812
+	}
813
+
814
+
815
+	/**
816
+	 * Gets an array of extra data that will be useful for client-side javascript.
817
+	 * This is primarily data added by inputs and forms in addition to any
818
+	 * scripts they might enqueue
819
+	 *
820
+	 * @param array $form_other_js_data
821
+	 * @return array
822
+	 * @throws EE_Error
823
+	 */
824
+	public function get_other_js_data($form_other_js_data = array())
825
+	{
826
+		foreach ($this->subsections() as $subsection) {
827
+			$form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
828
+		}
829
+		return $form_other_js_data;
830
+	}
831
+
832
+
833
+	/**
834
+	 * Gets a flat array of inputs for this form section and its subsections.
835
+	 * Keys are their form names, and values are the inputs themselves
836
+	 *
837
+	 * @return EE_Form_Input_Base
838
+	 * @throws EE_Error
839
+	 */
840
+	public function inputs_in_subsections()
841
+	{
842
+		$inputs = array();
843
+		foreach ($this->subsections() as $subsection) {
844
+			if ($subsection instanceof EE_Form_Input_Base) {
845
+				$inputs[ $subsection->html_name() ] = $subsection;
846
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
847
+				$inputs += $subsection->inputs_in_subsections();
848
+			}
849
+		}
850
+		return $inputs;
851
+	}
852
+
853
+
854
+	/**
855
+	 * Gets a flat array of all the validation errors.
856
+	 * Keys are html names (because those should be unique)
857
+	 * and values are a string of all their validation errors
858
+	 *
859
+	 * @return string[]
860
+	 * @throws EE_Error
861
+	 */
862
+	public function subsection_validation_errors_by_html_name()
863
+	{
864
+		$inputs = $this->inputs();
865
+		$errors = array();
866
+		foreach ($inputs as $form_input) {
867
+			if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
868
+				$errors[ $form_input->html_name() ] = $form_input->get_validation_error_string();
869
+			}
870
+		}
871
+		return $errors;
872
+	}
873
+
874
+
875
+	/**
876
+	 * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
877
+	 * Should be setup by each form during the _enqueues_and_localize_form_js
878
+	 *
879
+	 * @throws InvalidArgumentException
880
+	 * @throws InvalidInterfaceException
881
+	 * @throws InvalidDataTypeException
882
+	 */
883
+	public static function localize_script_for_all_forms()
884
+	{
885
+		// allow inputs and stuff to hook in their JS and stuff here
886
+		do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
887
+		EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
888
+		$email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
889
+			? EE_Registry::instance()->CFG->registration->email_validation_level
890
+			: 'wp_default';
891
+		EE_Form_Section_Proper::$_js_localization['email_validation_level']   = $email_validation_level;
892
+		wp_enqueue_script('ee_form_section_validation');
893
+		wp_localize_script(
894
+			'ee_form_section_validation',
895
+			'ee_form_section_vars',
896
+			EE_Form_Section_Proper::$_js_localization
897
+		);
898
+	}
899
+
900
+
901
+	/**
902
+	 * ensure_scripts_localized
903
+	 *
904
+	 * @throws EE_Error
905
+	 */
906
+	public function ensure_scripts_localized()
907
+	{
908
+		if (! EE_Form_Section_Proper::$_scripts_localized) {
909
+			$this->_enqueue_and_localize_form_js();
910
+		}
911
+	}
912
+
913
+
914
+	/**
915
+	 * Gets the hard-coded validation error messages to be used in the JS. The convention
916
+	 * is that the key here should be the same as the custom validation rule put in the JS file
917
+	 *
918
+	 * @return array keys are custom validation rules, and values are internationalized strings
919
+	 */
920
+	private static function _get_localized_error_messages()
921
+	{
922
+		return array(
923
+			'validUrl' => wp_strip_all_tags(__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso')),
924
+			'regex'    => wp_strip_all_tags(__('Please check your input', 'event_espresso'))
925
+		);
926
+	}
927
+
928
+
929
+	/**
930
+	 * @return array
931
+	 */
932
+	public static function js_localization()
933
+	{
934
+		return self::$_js_localization;
935
+	}
936
+
937
+
938
+	/**
939
+	 * @return void
940
+	 */
941
+	public static function reset_js_localization()
942
+	{
943
+		self::$_js_localization = array();
944
+	}
945
+
946
+
947
+	/**
948
+	 * Gets the JS to put inside the jquery validation rules for subsection of this form section.
949
+	 * See parent function for more...
950
+	 *
951
+	 * @return array
952
+	 * @throws EE_Error
953
+	 */
954
+	public function get_jquery_validation_rules()
955
+	{
956
+		$jquery_validation_rules = array();
957
+		foreach ($this->get_validatable_subsections() as $subsection) {
958
+			$jquery_validation_rules = array_merge(
959
+				$jquery_validation_rules,
960
+				$subsection->get_jquery_validation_rules()
961
+			);
962
+		}
963
+		return $jquery_validation_rules;
964
+	}
965
+
966
+
967
+	/**
968
+	 * Sanitizes all the data and sets the sanitized value of each field
969
+	 *
970
+	 * @param array $req_data
971
+	 * @return void
972
+	 * @throws EE_Error
973
+	 */
974
+	protected function _normalize($req_data)
975
+	{
976
+		$this->_received_submission = true;
977
+		$this->_validation_errors   = array();
978
+		foreach ($this->get_validatable_subsections() as $subsection) {
979
+			try {
980
+				$subsection->_normalize($req_data);
981
+			} catch (EE_Validation_Error $e) {
982
+				$subsection->add_validation_error($e);
983
+			}
984
+		}
985
+	}
986
+
987
+
988
+	/**
989
+	 * Performs validation on this form section and its subsections.
990
+	 * For each subsection,
991
+	 * calls _validate_{subsection_name} on THIS form (if the function exists)
992
+	 * and passes it the subsection, then calls _validate on that subsection.
993
+	 * If you need to perform validation on the form as a whole (considering multiple)
994
+	 * you would be best to override this _validate method,
995
+	 * calling parent::_validate() first.
996
+	 *
997
+	 * @throws EE_Error
998
+	 */
999
+	protected function _validate()
1000
+	{
1001
+		// reset the cache of whether this form is valid or not - we're re-validating it now
1002
+		$this->is_valid = null;
1003
+		foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
1004
+			if (method_exists($this, '_validate_' . $subsection_name)) {
1005
+				call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
1006
+			}
1007
+			$subsection->_validate();
1008
+		}
1009
+	}
1010
+
1011
+
1012
+	/**
1013
+	 * Gets all the validated inputs for the form section
1014
+	 *
1015
+	 * @return array
1016
+	 * @throws EE_Error
1017
+	 */
1018
+	public function valid_data()
1019
+	{
1020
+		$inputs = array();
1021
+		foreach ($this->subsections() as $subsection_name => $subsection) {
1022
+			if ($subsection instanceof EE_Form_Section_Proper) {
1023
+				$inputs[ $subsection_name ] = $subsection->valid_data();
1024
+			} elseif ($subsection instanceof EE_Form_Input_Base) {
1025
+				$inputs[ $subsection_name ] = $subsection->normalized_value();
1026
+			}
1027
+		}
1028
+		return $inputs;
1029
+	}
1030
+
1031
+
1032
+	/**
1033
+	 * Gets all the inputs on this form section
1034
+	 *
1035
+	 * @return EE_Form_Input_Base[]
1036
+	 * @throws EE_Error
1037
+	 */
1038
+	public function inputs()
1039
+	{
1040
+		$inputs = array();
1041
+		foreach ($this->subsections() as $subsection_name => $subsection) {
1042
+			if ($subsection instanceof EE_Form_Input_Base) {
1043
+				$inputs[ $subsection_name ] = $subsection;
1044
+			}
1045
+		}
1046
+		return $inputs;
1047
+	}
1048
+
1049
+
1050
+	/**
1051
+	 * Gets all the subsections which are a proper form
1052
+	 *
1053
+	 * @return EE_Form_Section_Proper[]
1054
+	 * @throws EE_Error
1055
+	 */
1056
+	public function subforms()
1057
+	{
1058
+		$form_sections = array();
1059
+		foreach ($this->subsections() as $name => $obj) {
1060
+			if ($obj instanceof EE_Form_Section_Proper) {
1061
+				$form_sections[ $name ] = $obj;
1062
+			}
1063
+		}
1064
+		return $form_sections;
1065
+	}
1066
+
1067
+
1068
+	/**
1069
+	 * Gets all the subsections (inputs, proper subsections, or html-only sections).
1070
+	 * Consider using inputs() or subforms()
1071
+	 * if you only want form inputs or proper form sections.
1072
+	 *
1073
+	 * @param boolean $require_construction_to_be_finalized most client code should
1074
+	 *                                                      leave this as TRUE so that the inputs will be properly
1075
+	 *                                                      configured. However, some client code may be ok with
1076
+	 *                                                      construction finalize being called later
1077
+	 *                                                      (realizing that the subsections' html names might not be
1078
+	 *                                                      set yet, etc.)
1079
+	 * @return EE_Form_Section_Proper[]
1080
+	 * @throws EE_Error
1081
+	 */
1082
+	public function subsections($require_construction_to_be_finalized = true)
1083
+	{
1084
+		if ($require_construction_to_be_finalized) {
1085
+			$this->ensure_construct_finalized_called();
1086
+		}
1087
+		return $this->_subsections;
1088
+	}
1089
+
1090
+
1091
+	/**
1092
+	 * Returns whether this form has any subforms or inputs
1093
+	 * @return bool
1094
+	 */
1095
+	public function hasSubsections()
1096
+	{
1097
+		return ! empty($this->_subsections);
1098
+	}
1099
+
1100
+
1101
+	/**
1102
+	 * Returns a simple array where keys are input names, and values are their normalized
1103
+	 * values. (Similar to calling get_input_value on inputs)
1104
+	 *
1105
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1106
+	 *                                        or just this forms' direct children inputs
1107
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1108
+	 *                                        or allow multidimensional array
1109
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
1110
+	 *                                        with array keys being input names
1111
+	 *                                        (regardless of whether they are from a subsection or not),
1112
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1113
+	 *                                        where keys are always subsection names and values are either
1114
+	 *                                        the input's normalized value, or an array like the top-level array
1115
+	 * @throws EE_Error
1116
+	 */
1117
+	public function input_values($include_subform_inputs = false, $flatten = false)
1118
+	{
1119
+		return $this->_input_values(false, $include_subform_inputs, $flatten);
1120
+	}
1121
+
1122
+
1123
+	/**
1124
+	 * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
1125
+	 * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
1126
+	 * is not necessarily the value we want to display to users. This creates an array
1127
+	 * where keys are the input names, and values are their display values
1128
+	 *
1129
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1130
+	 *                                        or just this forms' direct children inputs
1131
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1132
+	 *                                        or allow multidimensional array
1133
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
1134
+	 *                                        with array keys being input names
1135
+	 *                                        (regardless of whether they are from a subsection or not),
1136
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1137
+	 *                                        where keys are always subsection names and values are either
1138
+	 *                                        the input's normalized value, or an array like the top-level array
1139
+	 * @throws EE_Error
1140
+	 */
1141
+	public function input_pretty_values($include_subform_inputs = false, $flatten = false)
1142
+	{
1143
+		return $this->_input_values(true, $include_subform_inputs, $flatten);
1144
+	}
1145
+
1146
+
1147
+	/**
1148
+	 * Gets the input values from the form
1149
+	 *
1150
+	 * @param boolean $pretty                 Whether to retrieve the pretty value,
1151
+	 *                                        or just the normalized value
1152
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1153
+	 *                                        or just this forms' direct children inputs
1154
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1155
+	 *                                        or allow multidimensional array
1156
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
1157
+	 *                                        input names (regardless of whether they are from a subsection or not),
1158
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1159
+	 *                                        where keys are always subsection names and values are either
1160
+	 *                                        the input's normalized value, or an array like the top-level array
1161
+	 * @throws EE_Error
1162
+	 */
1163
+	public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
1164
+	{
1165
+		$input_values = array();
1166
+		foreach ($this->subsections() as $subsection_name => $subsection) {
1167
+			if ($subsection instanceof EE_Form_Input_Base) {
1168
+				$input_values[ $subsection_name ] = $pretty
1169
+					? $subsection->pretty_value()
1170
+					: $subsection->normalized_value();
1171
+			} elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1172
+				$subform_input_values = $subsection->_input_values(
1173
+					$pretty,
1174
+					$include_subform_inputs,
1175
+					$flatten
1176
+				);
1177
+				if ($flatten) {
1178
+					$input_values = array_merge($input_values, $subform_input_values);
1179
+				} else {
1180
+					$input_values[ $subsection_name ] = $subform_input_values;
1181
+				}
1182
+			}
1183
+		}
1184
+		return $input_values;
1185
+	}
1186
+
1187
+
1188
+	/**
1189
+	 * Gets the originally submitted input values from the form
1190
+	 *
1191
+	 * @param boolean $include_subforms  Whether to include inputs from subforms,
1192
+	 *                                   or just this forms' direct children inputs
1193
+	 * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1194
+	 *                                   with array keys being input names
1195
+	 *                                   (regardless of whether they are from a subsection or not),
1196
+	 *                                   and if $flatten is FALSE it can be a multidimensional array
1197
+	 *                                   where keys are always subsection names and values are either
1198
+	 *                                   the input's normalized value, or an array like the top-level array
1199
+	 * @throws EE_Error
1200
+	 */
1201
+	public function submitted_values($include_subforms = false)
1202
+	{
1203
+		$submitted_values = array();
1204
+		foreach ($this->subsections() as $subsection) {
1205
+			if ($subsection instanceof EE_Form_Input_Base) {
1206
+				// is this input part of an array of inputs?
1207
+				if (strpos($subsection->html_name(), '[') !== false) {
1208
+					$full_input_name  = EEH_Array::convert_array_values_to_keys(
1209
+						explode(
1210
+							'[',
1211
+							str_replace(']', '', $subsection->html_name())
1212
+						),
1213
+						$subsection->raw_value()
1214
+					);
1215
+					$submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1216
+				} else {
1217
+					$submitted_values[ $subsection->html_name() ] = $subsection->raw_value();
1218
+				}
1219
+			} elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1220
+				$subform_input_values = $subsection->submitted_values($include_subforms);
1221
+				$submitted_values     = array_replace_recursive($submitted_values, $subform_input_values);
1222
+			}
1223
+		}
1224
+		return $submitted_values;
1225
+	}
1226
+
1227
+
1228
+	/**
1229
+	 * Indicates whether or not this form has received a submission yet
1230
+	 * (ie, had receive_form_submission called on it yet)
1231
+	 *
1232
+	 * @return boolean
1233
+	 * @throws EE_Error
1234
+	 */
1235
+	public function has_received_submission()
1236
+	{
1237
+		$this->ensure_construct_finalized_called();
1238
+		return $this->_received_submission;
1239
+	}
1240
+
1241
+
1242
+	/**
1243
+	 * Equivalent to passing 'exclude' in the constructor's options array.
1244
+	 * Removes the listed inputs from the form
1245
+	 *
1246
+	 * @param array $inputs_to_exclude values are the input names
1247
+	 * @return void
1248
+	 */
1249
+	public function exclude(array $inputs_to_exclude = array())
1250
+	{
1251
+		foreach ($inputs_to_exclude as $input_to_exclude_name) {
1252
+			unset($this->_subsections[ $input_to_exclude_name ]);
1253
+		}
1254
+	}
1255
+
1256
+
1257
+	/**
1258
+	 * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy.
1259
+	 * @param array $inputs_to_hide
1260
+	 * @throws EE_Error
1261
+	 */
1262
+	public function hide(array $inputs_to_hide = array())
1263
+	{
1264
+		foreach ($inputs_to_hide as $input_to_hide) {
1265
+			$input = $this->get_input($input_to_hide);
1266
+			$input->set_display_strategy(new EE_Hidden_Display_Strategy());
1267
+		}
1268
+	}
1269
+
1270
+
1271
+	/**
1272
+	 * add_subsections
1273
+	 * Adds the listed subsections to the form section.
1274
+	 * If $subsection_name_to_target is provided,
1275
+	 * then new subsections are added before or after that subsection,
1276
+	 * otherwise to the start or end of the entire subsections array.
1277
+	 *
1278
+	 * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1279
+	 *                                                          where keys are their names
1280
+	 * @param string|null            $subsection_name_to_target an existing form section that $new_subsections
1281
+	 *                                                          should be added before or after
1282
+	 *                                                          IF $subsection_name_to_target is null,
1283
+	 *                                                          then $new_subsections will be added to
1284
+	 *                                                          the beginning or end of the entire subsections array
1285
+	 * @param boolean                $add_before                whether to add $new_subsections, before or after
1286
+	 *                                                          $subsection_name_to_target,
1287
+	 *                                                          or if $subsection_name_to_target is null,
1288
+	 *                                                          before or after entire subsections array
1289
+	 * @return void
1290
+	 * @throws EE_Error
1291
+	 */
1292
+	public function add_subsections(
1293
+		array $new_subsections,
1294
+		?string $subsection_name_to_target = null,
1295
+		bool $add_before = true
1296
+	) {
1297
+		foreach ($new_subsections as $subsection_name => $subsection) {
1298
+			if (! $subsection instanceof EE_Form_Section_Base) {
1299
+				EE_Error::add_error(
1300
+					sprintf(
1301
+						esc_html__(
1302
+							"Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1303
+							'event_espresso'
1304
+						),
1305
+						get_class($subsection),
1306
+						$subsection_name,
1307
+						$this->name()
1308
+					),
1309
+					__FILE__,
1310
+					__FUNCTION__,
1311
+					__LINE__
1312
+				);
1313
+				unset($new_subsections[ $subsection_name ]);
1314
+			}
1315
+		}
1316
+		$this->_subsections = EEH_Array::insert_into_array(
1317
+			$this->_subsections,
1318
+			$new_subsections,
1319
+			$subsection_name_to_target,
1320
+			$add_before
1321
+		);
1322
+		if ($this->_construction_finalized) {
1323
+			foreach ($this->_subsections as $name => $subsection) {
1324
+				$subsection->_construct_finalize($this, $name);
1325
+			}
1326
+		}
1327
+	}
1328
+
1329
+
1330
+	/**
1331
+	 * @param string $subsection_name
1332
+	 * @param bool   $recursive
1333
+	 * @return bool
1334
+	 */
1335
+	public function has_subsection($subsection_name, $recursive = false)
1336
+	{
1337
+		foreach ($this->_subsections as $name => $subsection) {
1338
+			if (
1339
+				$name === $subsection_name
1340
+				|| (
1341
+					$recursive
1342
+					&& $subsection instanceof EE_Form_Section_Proper
1343
+					&& $subsection->has_subsection($subsection_name, $recursive)
1344
+				)
1345
+			) {
1346
+				return true;
1347
+			}
1348
+		}
1349
+		return false;
1350
+	}
1351
+
1352
+
1353
+
1354
+	/**
1355
+	 * Just gets all validatable subsections to clean their sensitive data
1356
+	 *
1357
+	 * @throws EE_Error
1358
+	 */
1359
+	public function clean_sensitive_data()
1360
+	{
1361
+		foreach ($this->get_validatable_subsections() as $subsection) {
1362
+			$subsection->clean_sensitive_data();
1363
+		}
1364
+	}
1365
+
1366
+
1367
+	/**
1368
+	 * Sets the submission error message (aka validation error message for this form section and all sub-sections)
1369
+	 * @param string                           $form_submission_error_message
1370
+	 * @param EE_Form_Section_Validatable $form_section unused
1371
+	 * @throws EE_Error
1372
+	 */
1373
+	public function set_submission_error_message(
1374
+		$form_submission_error_message = ''
1375
+	) {
1376
+		$this->_form_submission_error_message = ! empty($form_submission_error_message)
1377
+			? $form_submission_error_message
1378
+			: $this->getAllValidationErrorsString();
1379
+	}
1380
+
1381
+
1382
+	/**
1383
+	 * Returns the cached error message. A default value is set for this during _validate(),
1384
+	 * (called during receive_form_submission) but it can be explicitly set using
1385
+	 * set_submission_error_message
1386
+	 *
1387
+	 * @return string
1388
+	 */
1389
+	public function submission_error_message()
1390
+	{
1391
+		return $this->_form_submission_error_message;
1392
+	}
1393
+
1394
+
1395
+	/**
1396
+	 * Sets a message to display if the data submitted to the form was valid.
1397
+	 * @param string $form_submission_success_message
1398
+	 */
1399
+	public function set_submission_success_message($form_submission_success_message = '')
1400
+	{
1401
+		$this->_form_submission_success_message = ! empty($form_submission_success_message)
1402
+			? $form_submission_success_message
1403
+			: esc_html__('Form submitted successfully', 'event_espresso');
1404
+	}
1405
+
1406
+
1407
+	/**
1408
+	 * Gets a message appropriate for display when the form is correctly submitted
1409
+	 * @return string
1410
+	 */
1411
+	public function submission_success_message()
1412
+	{
1413
+		return $this->_form_submission_success_message;
1414
+	}
1415
+
1416
+
1417
+	/**
1418
+	 * Returns the prefix that should be used on child of this form section for
1419
+	 * their html names. If this form section itself has a parent, prepends ITS
1420
+	 * prefix onto this form section's prefix. Used primarily by
1421
+	 * EE_Form_Input_Base::_set_default_html_name_if_empty
1422
+	 *
1423
+	 * @return string
1424
+	 * @throws EE_Error
1425
+	 */
1426
+	public function html_name_prefix()
1427
+	{
1428
+		if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1429
+			return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1430
+		}
1431
+		return $this->name();
1432
+	}
1433
+
1434
+
1435
+	/**
1436
+	 * Gets the name, but first checks _construct_finalize has been called. If not,
1437
+	 * calls it (assumes there is no parent and that we want the name to be whatever
1438
+	 * was set, which is probably nothing, or the classname)
1439
+	 *
1440
+	 * @return string
1441
+	 * @throws EE_Error
1442
+	 */
1443
+	public function name()
1444
+	{
1445
+		$this->ensure_construct_finalized_called();
1446
+		return parent::name();
1447
+	}
1448
+
1449
+
1450
+	/**
1451
+	 * @return EE_Form_Section_Proper
1452
+	 * @throws EE_Error
1453
+	 */
1454
+	public function parent_section()
1455
+	{
1456
+		$this->ensure_construct_finalized_called();
1457
+		return parent::parent_section();
1458
+	}
1459
+
1460
+
1461
+	/**
1462
+	 * make sure construction finalized was called, otherwise children might not be ready
1463
+	 *
1464
+	 * @return void
1465
+	 * @throws EE_Error
1466
+	 */
1467
+	public function ensure_construct_finalized_called()
1468
+	{
1469
+		if (! $this->_construction_finalized) {
1470
+			$this->_construct_finalize($this->_parent_section, $this->_name);
1471
+		}
1472
+	}
1473
+
1474
+
1475
+	/**
1476
+	 * Checks if any of this form section's inputs, or any of its children's inputs,
1477
+	 * are in teh form data. If any are found, returns true. Else false
1478
+	 *
1479
+	 * @param array $req_data
1480
+	 * @return boolean
1481
+	 * @throws EE_Error
1482
+	 */
1483
+	public function form_data_present_in($req_data = null)
1484
+	{
1485
+		$req_data = $this->getCachedRequest($req_data);
1486
+		foreach ($this->subsections() as $subsection) {
1487
+			if ($subsection instanceof EE_Form_Input_Base) {
1488
+				if ($subsection->form_data_present_in($req_data)) {
1489
+					return true;
1490
+				}
1491
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
1492
+				if ($subsection->form_data_present_in($req_data)) {
1493
+					return true;
1494
+				}
1495
+			}
1496
+		}
1497
+		return false;
1498
+	}
1499
+
1500
+
1501
+	/**
1502
+	 * Gets validation errors for this form section and subsections
1503
+	 * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1504
+	 * gets the validation errors for ALL subsection
1505
+	 *
1506
+	 * @return EE_Validation_Error[]
1507
+	 * @throws EE_Error
1508
+	 */
1509
+	public function get_validation_errors_accumulated()
1510
+	{
1511
+		$validation_errors = $this->get_validation_errors();
1512
+		foreach ($this->get_validatable_subsections() as $subsection) {
1513
+			if ($subsection instanceof EE_Form_Section_Proper) {
1514
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1515
+			} else {
1516
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors();
1517
+			}
1518
+			if ($validation_errors_on_this_subsection) {
1519
+				$validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1520
+			}
1521
+		}
1522
+		return $validation_errors;
1523
+	}
1524
+
1525
+	/**
1526
+	 * Fetch validation errors from children and grandchildren and puts them in a single string.
1527
+	 * This traverses the form section tree to generate this, but you probably want to instead use
1528
+	 * get_form_submission_error_message() which is usually this message cached (or a custom validation error message)
1529
+	 *
1530
+	 * @return string
1531
+	 * @since 4.9.59.p
1532
+	 */
1533
+	protected function getAllValidationErrorsString()
1534
+	{
1535
+		$submission_error_messages = array();
1536
+		// bad, bad, bad registrant
1537
+		foreach ($this->get_validation_errors_accumulated() as $validation_error) {
1538
+			if ($validation_error instanceof EE_Validation_Error) {
1539
+				$form_section = $validation_error->get_form_section();
1540
+				if ($form_section instanceof EE_Form_Input_Base) {
1541
+					$label = $validation_error->get_form_section()->html_label_text();
1542
+				} elseif ($form_section instanceof EE_Form_Section_Validatable) {
1543
+					$label = $validation_error->get_form_section()->name();
1544
+				} else {
1545
+					$label = esc_html__('Unknown', 'event_espresso');
1546
+				}
1547
+				$submission_error_messages[] = sprintf(
1548
+					esc_html__('%s : %s', 'event_espresso'),
1549
+					$label,
1550
+					$validation_error->getMessage()
1551
+				);
1552
+			}
1553
+		}
1554
+		return implode('<br>', $submission_error_messages);
1555
+	}
1556
+
1557
+
1558
+	/**
1559
+	 * This isn't just the name of an input, it's a path pointing to an input. The
1560
+	 * path is similar to a folder path: slash (/) means to descend into a subsection,
1561
+	 * dot-dot-slash (../) means to ascend into the parent section.
1562
+	 * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1563
+	 * which will be returned.
1564
+	 * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1565
+	 * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1566
+	 * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1567
+	 * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1568
+	 * Etc
1569
+	 *
1570
+	 * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1571
+	 * @return EE_Form_Section_Base
1572
+	 * @throws EE_Error
1573
+	 */
1574
+	public function find_section_from_path($form_section_path)
1575
+	{
1576
+		// check if we can find the input from purely going straight up the tree
1577
+		$input = parent::find_section_from_path($form_section_path);
1578
+		if ($input instanceof EE_Form_Section_Base) {
1579
+			return $input;
1580
+		}
1581
+		$next_slash_pos = strpos($form_section_path, '/');
1582
+		if ($next_slash_pos !== false) {
1583
+			$child_section_name = substr($form_section_path, 0, $next_slash_pos);
1584
+			$subpath            = substr($form_section_path, $next_slash_pos + 1);
1585
+		} else {
1586
+			$child_section_name = $form_section_path;
1587
+			$subpath            = '';
1588
+		}
1589
+		$child_section = $this->get_subsection($child_section_name);
1590
+		if ($child_section instanceof EE_Form_Section_Base) {
1591
+			return $child_section->find_section_from_path($subpath);
1592
+		}
1593
+		return null;
1594
+	}
1595
+
1596
+
1597
+	/**
1598
+	 * @param EE_Form_Section_Base $form_section
1599
+	 * @param int                  $depth
1600
+	 * @return void
1601
+	 * @throws EE_Error
1602
+	 * @since 5.0.30.p
1603
+	 */
1604
+	public static function visualize(EE_Form_Section_Base $form_section, int $depth = 0)
1605
+	{
1606
+		$indent = str_repeat(' .', $depth * 2);
1607
+		echo "$indent form_section: " . ($form_section->_name ?: get_class($form_section));
1608
+		$depth++;
1609
+		if ($form_section instanceof EE_Form_Section_Proper) {
1610
+			foreach ($form_section->_subsections as $subsection) {
1611
+				if ($subsection instanceof EE_Form_Section_Proper) {
1612
+					self::visualize($subsection, $depth);
1613
+				} elseif ($subsection instanceof EE_Form_Input_Base) {
1614
+					echo "$indent input: " . ($subsection->html_name() ?: get_class($subsection));
1615
+				} else {
1616
+					echo "$indent input: " . ($subsection->_name ?: get_class($subsection));
1617
+				}
1618
+			}
1619
+		}
1620
+	}
1621 1621
 }
Please login to merge, or discard this patch.
Spacing   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -113,8 +113,8 @@  discard block
 block discarded – undo
113 113
             // AND we are going to make sure they're in that specified order
114 114
             $reordered_subsections = array();
115 115
             foreach ($options_array['include'] as $input_name) {
116
-                if (isset($this->_subsections[ $input_name ])) {
117
-                    $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ];
116
+                if (isset($this->_subsections[$input_name])) {
117
+                    $reordered_subsections[$input_name] = $this->_subsections[$input_name];
118 118
                 }
119 119
             }
120 120
             $this->_subsections = $reordered_subsections;
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
         if (isset($options_array['layout_strategy'])) {
127 127
             $this->_layout_strategy = $options_array['layout_strategy'];
128 128
         }
129
-        if (! $this->_layout_strategy) {
129
+        if ( ! $this->_layout_strategy) {
130 130
             $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
131 131
         }
132 132
         $this->_layout_strategy->_construct_finalize($this);
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
         if ($validate) {
321 321
             $this->_validate();
322 322
             // if it's invalid, we're going to want to re-display so remember what they submitted
323
-            if (! $this->is_valid()) {
323
+            if ( ! $this->is_valid()) {
324 324
                 $this->store_submitted_form_data_in_session();
325 325
             }
326 326
         }
@@ -437,11 +437,11 @@  discard block
 block discarded – undo
437 437
     public function populate_defaults($default_data)
438 438
     {
439 439
         foreach ($this->subsections(false) as $subsection_name => $subsection) {
440
-            if (isset($default_data[ $subsection_name ])) {
440
+            if (isset($default_data[$subsection_name])) {
441 441
                 if ($subsection instanceof EE_Form_Input_Base) {
442
-                    $subsection->set_default($default_data[ $subsection_name ]);
442
+                    $subsection->set_default($default_data[$subsection_name]);
443 443
                 } elseif ($subsection instanceof EE_Form_Section_Proper) {
444
-                    $subsection->populate_defaults($default_data[ $subsection_name ]);
444
+                    $subsection->populate_defaults($default_data[$subsection_name]);
445 445
                 }
446 446
             }
447 447
         }
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
      */
457 457
     public function subsection_exists(string $name): bool
458 458
     {
459
-        return isset($this->_subsections[ $name ]);
459
+        return isset($this->_subsections[$name]);
460 460
     }
461 461
 
462 462
 
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
         if ($require_construction_to_be_finalized) {
479 479
             $this->ensure_construct_finalized_called();
480 480
         }
481
-        return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null;
481
+        return $this->subsection_exists($name) ? $this->_subsections[$name] : null;
482 482
     }
483 483
 
484 484
 
@@ -493,7 +493,7 @@  discard block
 block discarded – undo
493 493
         $validatable_subsections = array();
494 494
         foreach ($this->subsections() as $name => $obj) {
495 495
             if ($obj instanceof EE_Form_Section_Validatable) {
496
-                $validatable_subsections[ $name ] = $obj;
496
+                $validatable_subsections[$name] = $obj;
497 497
             }
498 498
         }
499 499
         return $validatable_subsections;
@@ -520,7 +520,7 @@  discard block
 block discarded – undo
520 520
             $name,
521 521
             $require_construction_to_be_finalized
522 522
         );
523
-        if (! $subsection instanceof EE_Form_Input_Base) {
523
+        if ( ! $subsection instanceof EE_Form_Input_Base) {
524 524
             throw new EE_Error(
525 525
                 sprintf(
526 526
                     esc_html__(
@@ -549,7 +549,7 @@  discard block
 block discarded – undo
549 549
     {
550 550
         // breadth first search
551 551
         if ($this->subsection_exists($html_name)) {
552
-            return $this->_subsections[ $html_name ];
552
+            return $this->_subsections[$html_name];
553 553
         }
554 554
         $input = null;
555 555
         foreach ($this->subsections() as $subsection) {
@@ -589,7 +589,7 @@  discard block
 block discarded – undo
589 589
             $name,
590 590
             $require_construction_to_be_finalized
591 591
         );
592
-        if (! $subsection instanceof EE_Form_Section_Proper) {
592
+        if ( ! $subsection instanceof EE_Form_Section_Proper) {
593 593
             throw new EE_Error(
594 594
                 sprintf(
595 595
                     esc_html__(
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
     public function is_valid()
630 630
     {
631 631
         if ($this->is_valid === null) {
632
-            if (! $this->has_received_submission()) {
632
+            if ( ! $this->has_received_submission()) {
633 633
                 throw new EE_Error(
634 634
                     sprintf(
635 635
                         esc_html__(
@@ -639,14 +639,14 @@  discard block
 block discarded – undo
639 639
                     )
640 640
                 );
641 641
             }
642
-            if (! parent::is_valid()) {
642
+            if ( ! parent::is_valid()) {
643 643
                 $this->is_valid = false;
644 644
             } else {
645 645
                 // ok so no general errors to this entire form section.
646 646
                 // so let's check the subsections, but only set errors if that hasn't been done yet
647 647
                 $this->is_valid = true;
648 648
                 foreach ($this->get_validatable_subsections() as $subsection) {
649
-                    if (! $subsection->is_valid()) {
649
+                    if ( ! $subsection->is_valid()) {
650 650
                         $this->is_valid = false;
651 651
                     }
652 652
                 }
@@ -663,7 +663,7 @@  discard block
 block discarded – undo
663 663
      */
664 664
     protected function _set_default_name_if_empty()
665 665
     {
666
-        if (! $this->_name) {
666
+        if ( ! $this->_name) {
667 667
             $classname    = get_class($this);
668 668
             $default_name = str_replace('EE_', '', $classname);
669 669
             $this->_name  = $default_name;
@@ -753,7 +753,7 @@  discard block
 block discarded – undo
753 753
     {
754 754
         wp_register_script(
755 755
             'ee_form_section_validation',
756
-            EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js',
756
+            EE_GLOBAL_ASSETS_URL.'scripts'.'/form_section_validation.js',
757 757
             [
758 758
                 JqueryAssetManager::JS_HANDLE_JQUERY_VALIDATE,
759 759
                 JqueryAssetManager::JS_HANDLE_JQUERY_UI_DATEPICKER,
@@ -801,13 +801,13 @@  discard block
 block discarded – undo
801 801
         // we only want to localize vars ONCE for the entire form,
802 802
         // so if the form section doesn't have a parent, then it must be the top dog
803 803
         if ($return_for_subsection || ! $this->parent_section()) {
804
-            EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array(
804
+            EE_Form_Section_Proper::$_js_localization['form_data'][$this->html_id()] = array(
805 805
                 'form_section_id'  => $this->html_id(true),
806 806
                 'validation_rules' => $this->get_jquery_validation_rules(),
807 807
                 'other_data'       => $this->get_other_js_data(),
808 808
                 'errors'           => $this->subsection_validation_errors_by_html_name(),
809 809
             );
810
-            EE_Form_Section_Proper::$_scripts_localized                                = true;
810
+            EE_Form_Section_Proper::$_scripts_localized = true;
811 811
         }
812 812
     }
813 813
 
@@ -842,7 +842,7 @@  discard block
 block discarded – undo
842 842
         $inputs = array();
843 843
         foreach ($this->subsections() as $subsection) {
844 844
             if ($subsection instanceof EE_Form_Input_Base) {
845
-                $inputs[ $subsection->html_name() ] = $subsection;
845
+                $inputs[$subsection->html_name()] = $subsection;
846 846
             } elseif ($subsection instanceof EE_Form_Section_Proper) {
847 847
                 $inputs += $subsection->inputs_in_subsections();
848 848
             }
@@ -865,7 +865,7 @@  discard block
 block discarded – undo
865 865
         $errors = array();
866 866
         foreach ($inputs as $form_input) {
867 867
             if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
868
-                $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string();
868
+                $errors[$form_input->html_name()] = $form_input->get_validation_error_string();
869 869
             }
870 870
         }
871 871
         return $errors;
@@ -888,7 +888,7 @@  discard block
 block discarded – undo
888 888
         $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
889 889
             ? EE_Registry::instance()->CFG->registration->email_validation_level
890 890
             : 'wp_default';
891
-        EE_Form_Section_Proper::$_js_localization['email_validation_level']   = $email_validation_level;
891
+        EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level;
892 892
         wp_enqueue_script('ee_form_section_validation');
893 893
         wp_localize_script(
894 894
             'ee_form_section_validation',
@@ -905,7 +905,7 @@  discard block
 block discarded – undo
905 905
      */
906 906
     public function ensure_scripts_localized()
907 907
     {
908
-        if (! EE_Form_Section_Proper::$_scripts_localized) {
908
+        if ( ! EE_Form_Section_Proper::$_scripts_localized) {
909 909
             $this->_enqueue_and_localize_form_js();
910 910
         }
911 911
     }
@@ -1001,8 +1001,8 @@  discard block
 block discarded – undo
1001 1001
         // reset the cache of whether this form is valid or not - we're re-validating it now
1002 1002
         $this->is_valid = null;
1003 1003
         foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
1004
-            if (method_exists($this, '_validate_' . $subsection_name)) {
1005
-                call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
1004
+            if (method_exists($this, '_validate_'.$subsection_name)) {
1005
+                call_user_func_array(array($this, '_validate_'.$subsection_name), array($subsection));
1006 1006
             }
1007 1007
             $subsection->_validate();
1008 1008
         }
@@ -1020,9 +1020,9 @@  discard block
 block discarded – undo
1020 1020
         $inputs = array();
1021 1021
         foreach ($this->subsections() as $subsection_name => $subsection) {
1022 1022
             if ($subsection instanceof EE_Form_Section_Proper) {
1023
-                $inputs[ $subsection_name ] = $subsection->valid_data();
1023
+                $inputs[$subsection_name] = $subsection->valid_data();
1024 1024
             } elseif ($subsection instanceof EE_Form_Input_Base) {
1025
-                $inputs[ $subsection_name ] = $subsection->normalized_value();
1025
+                $inputs[$subsection_name] = $subsection->normalized_value();
1026 1026
             }
1027 1027
         }
1028 1028
         return $inputs;
@@ -1040,7 +1040,7 @@  discard block
 block discarded – undo
1040 1040
         $inputs = array();
1041 1041
         foreach ($this->subsections() as $subsection_name => $subsection) {
1042 1042
             if ($subsection instanceof EE_Form_Input_Base) {
1043
-                $inputs[ $subsection_name ] = $subsection;
1043
+                $inputs[$subsection_name] = $subsection;
1044 1044
             }
1045 1045
         }
1046 1046
         return $inputs;
@@ -1058,7 +1058,7 @@  discard block
 block discarded – undo
1058 1058
         $form_sections = array();
1059 1059
         foreach ($this->subsections() as $name => $obj) {
1060 1060
             if ($obj instanceof EE_Form_Section_Proper) {
1061
-                $form_sections[ $name ] = $obj;
1061
+                $form_sections[$name] = $obj;
1062 1062
             }
1063 1063
         }
1064 1064
         return $form_sections;
@@ -1165,7 +1165,7 @@  discard block
 block discarded – undo
1165 1165
         $input_values = array();
1166 1166
         foreach ($this->subsections() as $subsection_name => $subsection) {
1167 1167
             if ($subsection instanceof EE_Form_Input_Base) {
1168
-                $input_values[ $subsection_name ] = $pretty
1168
+                $input_values[$subsection_name] = $pretty
1169 1169
                     ? $subsection->pretty_value()
1170 1170
                     : $subsection->normalized_value();
1171 1171
             } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
@@ -1177,7 +1177,7 @@  discard block
 block discarded – undo
1177 1177
                 if ($flatten) {
1178 1178
                     $input_values = array_merge($input_values, $subform_input_values);
1179 1179
                 } else {
1180
-                    $input_values[ $subsection_name ] = $subform_input_values;
1180
+                    $input_values[$subsection_name] = $subform_input_values;
1181 1181
                 }
1182 1182
             }
1183 1183
         }
@@ -1205,7 +1205,7 @@  discard block
 block discarded – undo
1205 1205
             if ($subsection instanceof EE_Form_Input_Base) {
1206 1206
                 // is this input part of an array of inputs?
1207 1207
                 if (strpos($subsection->html_name(), '[') !== false) {
1208
-                    $full_input_name  = EEH_Array::convert_array_values_to_keys(
1208
+                    $full_input_name = EEH_Array::convert_array_values_to_keys(
1209 1209
                         explode(
1210 1210
                             '[',
1211 1211
                             str_replace(']', '', $subsection->html_name())
@@ -1214,7 +1214,7 @@  discard block
 block discarded – undo
1214 1214
                     );
1215 1215
                     $submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1216 1216
                 } else {
1217
-                    $submitted_values[ $subsection->html_name() ] = $subsection->raw_value();
1217
+                    $submitted_values[$subsection->html_name()] = $subsection->raw_value();
1218 1218
                 }
1219 1219
             } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1220 1220
                 $subform_input_values = $subsection->submitted_values($include_subforms);
@@ -1249,7 +1249,7 @@  discard block
 block discarded – undo
1249 1249
     public function exclude(array $inputs_to_exclude = array())
1250 1250
     {
1251 1251
         foreach ($inputs_to_exclude as $input_to_exclude_name) {
1252
-            unset($this->_subsections[ $input_to_exclude_name ]);
1252
+            unset($this->_subsections[$input_to_exclude_name]);
1253 1253
         }
1254 1254
     }
1255 1255
 
@@ -1295,7 +1295,7 @@  discard block
 block discarded – undo
1295 1295
         bool $add_before = true
1296 1296
     ) {
1297 1297
         foreach ($new_subsections as $subsection_name => $subsection) {
1298
-            if (! $subsection instanceof EE_Form_Section_Base) {
1298
+            if ( ! $subsection instanceof EE_Form_Section_Base) {
1299 1299
                 EE_Error::add_error(
1300 1300
                     sprintf(
1301 1301
                         esc_html__(
@@ -1310,7 +1310,7 @@  discard block
 block discarded – undo
1310 1310
                     __FUNCTION__,
1311 1311
                     __LINE__
1312 1312
                 );
1313
-                unset($new_subsections[ $subsection_name ]);
1313
+                unset($new_subsections[$subsection_name]);
1314 1314
             }
1315 1315
         }
1316 1316
         $this->_subsections = EEH_Array::insert_into_array(
@@ -1426,7 +1426,7 @@  discard block
 block discarded – undo
1426 1426
     public function html_name_prefix()
1427 1427
     {
1428 1428
         if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1429
-            return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1429
+            return $this->parent_section()->html_name_prefix().'['.$this->name().']';
1430 1430
         }
1431 1431
         return $this->name();
1432 1432
     }
@@ -1466,7 +1466,7 @@  discard block
 block discarded – undo
1466 1466
      */
1467 1467
     public function ensure_construct_finalized_called()
1468 1468
     {
1469
-        if (! $this->_construction_finalized) {
1469
+        if ( ! $this->_construction_finalized) {
1470 1470
             $this->_construct_finalize($this->_parent_section, $this->_name);
1471 1471
         }
1472 1472
     }
@@ -1604,16 +1604,16 @@  discard block
 block discarded – undo
1604 1604
     public static function visualize(EE_Form_Section_Base $form_section, int $depth = 0)
1605 1605
     {
1606 1606
         $indent = str_repeat(' .', $depth * 2);
1607
-        echo "$indent form_section: " . ($form_section->_name ?: get_class($form_section));
1607
+        echo "$indent form_section: ".($form_section->_name ?: get_class($form_section));
1608 1608
         $depth++;
1609 1609
         if ($form_section instanceof EE_Form_Section_Proper) {
1610 1610
             foreach ($form_section->_subsections as $subsection) {
1611 1611
                 if ($subsection instanceof EE_Form_Section_Proper) {
1612 1612
                     self::visualize($subsection, $depth);
1613 1613
                 } elseif ($subsection instanceof EE_Form_Input_Base) {
1614
-                    echo "$indent input: " . ($subsection->html_name() ?: get_class($subsection));
1614
+                    echo "$indent input: ".($subsection->html_name() ?: get_class($subsection));
1615 1615
                 } else {
1616
-                    echo "$indent input: " . ($subsection->_name ?: get_class($subsection));
1616
+                    echo "$indent input: ".($subsection->_name ?: get_class($subsection));
1617 1617
                 }
1618 1618
             }
1619 1619
         }
Please login to merge, or discard this patch.
core/libraries/form_sections/base/EE_Form_Section_Base.form.php 1 patch
Indentation   +483 added lines, -483 removed lines patch added patch discarded remove patch
@@ -14,488 +14,488 @@
 block discarded – undo
14 14
  */
15 15
 abstract class EE_Form_Section_Base
16 16
 {
17
-    /**
18
-     * the URL the form is submitted to
19
-     *
20
-     * @var string
21
-     */
22
-    protected string $_action = '';
23
-
24
-    /**
25
-     * POST (default) or GET
26
-     *
27
-     * @var string
28
-     */
29
-    protected string $_method = '';
30
-
31
-    /**
32
-     * html_id and html_name are derived from this by default
33
-     *
34
-     * @var string
35
-     */
36
-    protected string $_name = '';
37
-
38
-    /**
39
-     * $_html_id
40
-     * @var string
41
-     */
42
-    protected string $_html_id = '';
43
-
44
-    /**
45
-     * $_html_class
46
-     * @var string
47
-     */
48
-    protected string $_html_class = '';
49
-
50
-    /**
51
-     * $_html_style
52
-     * @var string
53
-     */
54
-    protected string $_html_style = '';
55
-
56
-    /**
57
-     * $_other_html_attributes
58
-     * @var string
59
-     */
60
-    protected string $_other_html_attributes = '';
61
-
62
-    /**
63
-     * The form section of which this form section is a part
64
-     *
65
-     * @var EE_Form_Section_Base|null
66
-     */
67
-    protected ?EE_Form_Section_Base $_parent_section = null;
68
-
69
-    /**
70
-     * flag indicating that _construct_finalize has been called.
71
-     * If it has not been called and we try to use functions which require it, we call it
72
-     * with no parameters. But normally, _construct_finalize should be called by the instantiating class
73
-     *
74
-     * @var bool
75
-     */
76
-    protected bool $_construction_finalized = false;
77
-
78
-    /**
79
-     * Strategy for parsing the form HTML upon display
80
-     *
81
-     * @var FormHtmlFilter|null
82
-     */
83
-    protected ?FormHtmlFilter $_form_html_filter = null;
84
-
85
-
86
-    /**
87
-     * @param array $options_array {
88
-     * @type        $name          string the name for this form section, if you want to explicitly define it
89
-     *                             }
90
-     * @throws InvalidDataTypeException
91
-     */
92
-    public function __construct(array $options_array = [])
93
-    {
94
-        // set parser which allows the form section's rendered HTML to be filtered
95
-        if (isset($options_array['form_html_filter']) && $options_array['form_html_filter'] instanceof FormHtmlFilter) {
96
-            $this->_form_html_filter = $options_array['form_html_filter'];
97
-            unset($options_array['form_html_filter']);
98
-        }
99
-        // used by display strategies
100
-        // assign incoming values to properties
101
-        foreach ($options_array as $key => $value) {
102
-            $setter = 'set_' . $key;
103
-            if (method_exists($this, $setter)) {
104
-                $this->$setter($value);
105
-                continue;
106
-            }
107
-            $_key = "_$key";
108
-            if (property_exists($this, $_key) && empty($this->{$_key})) {
109
-                if ($_key === '_subsections' && ! is_array($value)) {
110
-                    throw new InvalidDataTypeException($_key, $value, 'array');
111
-                }
112
-                $this->{$_key} = $value;
113
-            }
114
-        }
115
-    }
116
-
117
-
118
-    /**
119
-     * @param EE_Form_Section_Base|null $parent_form_section
120
-     * @param $name
121
-     */
122
-    protected function _construct_finalize($parent_form_section, $name)
123
-    {
124
-        $this->_construction_finalized = true;
125
-        $this->_parent_section         = $parent_form_section;
126
-        if ($name !== null) {
127
-            $this->_name = $name;
128
-        }
129
-    }
130
-
131
-
132
-    /**
133
-     * make sure construction finalized was called, otherwise children might not be ready
134
-     *
135
-     * @return void
136
-     */
137
-    public function ensure_construct_finalized_called()
138
-    {
139
-        if (! $this->_construction_finalized) {
140
-            $this->_construct_finalize($this->_parent_section, $this->_name);
141
-        }
142
-    }
143
-
144
-
145
-    /**
146
-     * @return string
147
-     */
148
-    public function action()
149
-    {
150
-        return $this->_action;
151
-    }
152
-
153
-
154
-    /**
155
-     * @param string $action
156
-     */
157
-    public function set_action($action)
158
-    {
159
-        $this->_action = $action;
160
-    }
161
-
162
-
163
-    /**
164
-     * @return string
165
-     */
166
-    public function method()
167
-    {
168
-        return ! empty($this->_method) ? $this->_method : 'POST';
169
-    }
170
-
171
-
172
-    /**
173
-     * @param string $method
174
-     */
175
-    public function set_method($method)
176
-    {
177
-        switch ($method) {
178
-            case 'get':
179
-            case 'GET':
180
-                $this->_method = 'GET';
181
-                break;
182
-            default:
183
-                $this->_method = 'POST';
184
-        }
185
-    }
186
-
187
-
188
-    /**
189
-     * Sets the html_id to its default value, if none was specified in the constructor.
190
-     * Calculation involves using the name and the parent's html id
191
-     * return void
192
-     *
193
-     * @throws \EE_Error
194
-     */
195
-    protected function _set_default_html_id_if_empty()
196
-    {
197
-        if (! $this->_html_id) {
198
-            if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
199
-                $this->_html_id = $this->_parent_section->html_id()
200
-                                  . '-'
201
-                                  . $this->_prep_name_for_html_id($this->name());
202
-            } else {
203
-                $this->_html_id = $this->_prep_name_for_html_id($this->name());
204
-            }
205
-        }
206
-    }
207
-
208
-
209
-    /**
210
-     * _prep_name_for_html_id
211
-     *
212
-     * @param $name
213
-     * @return string
214
-     */
215
-    private function _prep_name_for_html_id($name)
216
-    {
217
-        return sanitize_key(str_replace(['&nbsp;', ' ', '_'], '-', $name));
218
-    }
219
-
220
-
221
-    /**
222
-     * Returns the HTML, JS, and CSS necessary to display this form section on a page.
223
-     * Note however, it's recommended that you instead call enqueue_js on the "wp_enqueue_scripts" action,
224
-     * and call get_html when you want to output the html. Calling get_html_and_js after
225
-     * "wp_enqueue_scripts" has already fired seems to work for now, but is contrary
226
-     * to the instructions on https://developer.wordpress.org/reference/functions/wp_enqueue_script/
227
-     * and so might stop working anytime.
228
-     *
229
-     * @return string
230
-     */
231
-    public function get_html_and_js()
232
-    {
233
-        return $this->get_html();
234
-    }
235
-
236
-
237
-    /**
238
-     * Gets the HTML for displaying this form section
239
-     *
240
-     * @return string
241
-     */
242
-    abstract public function get_html();
243
-
244
-
245
-    /**
246
-     * @param bool $add_pound_sign
247
-     * @return string
248
-     * @throws EE_Error
249
-     */
250
-    public function html_id($add_pound_sign = false)
251
-    {
252
-        $this->_set_default_html_id_if_empty();
253
-        return $add_pound_sign ? '#' . $this->_html_id : $this->_html_id;
254
-    }
255
-
256
-
257
-    /**
258
-     * @return string
259
-     */
260
-    public function html_class()
261
-    {
262
-        return $this->_html_class;
263
-    }
264
-
265
-
266
-    /**
267
-     * @return string
268
-     */
269
-    public function html_style()
270
-    {
271
-        return $this->_html_style;
272
-    }
273
-
274
-
275
-    /**
276
-     * @param string $html_class
277
-     */
278
-    public function add_html_class(string $html_class)
279
-    {
280
-        $this->_html_class .= ' ' . trim($html_class);
281
-    }
282
-
283
-
284
-    /**
285
-     * @param string $html_class
286
-     */
287
-    public function set_html_class(string $html_class)
288
-    {
289
-        $this->_html_class = trim($html_class);
290
-    }
291
-
292
-
293
-    /**
294
-     * @param mixed $html_id
295
-     */
296
-    public function set_html_id($html_id)
297
-    {
298
-        $this->_html_id = $html_id;
299
-    }
300
-
301
-
302
-    /**
303
-     * @param mixed $html_style
304
-     */
305
-    public function set_html_style($html_style)
306
-    {
307
-        $this->_html_style = $html_style;
308
-    }
309
-
310
-
311
-    /**
312
-     * @param string $other_html_attributes
313
-     */
314
-    public function set_other_html_attributes($other_html_attributes)
315
-    {
316
-        if (empty($other_html_attributes)) {
317
-            return;
318
-        }
319
-        // make sure attributes are separated by a space
320
-        $other_html_attributes = strpos($other_html_attributes, ' ') !== 0
321
-            ? " $other_html_attributes"
322
-            : $other_html_attributes;
323
-        $this->_other_html_attributes .= $other_html_attributes;
324
-    }
325
-
326
-
327
-    /**
328
-     * @return string
329
-     */
330
-    public function other_html_attributes()
331
-    {
332
-        return ! empty($this->_other_html_attributes) ? ' ' . $this->_other_html_attributes : '';
333
-    }
334
-
335
-
336
-    /**
337
-     * Gets the name of the form section. This is not the same as the HTML name.
338
-     *
339
-     * @return string
340
-     * @throws EE_Error
341
-     */
342
-    public function name()
343
-    {
344
-        if (! $this->_construction_finalized) {
345
-            throw new EE_Error(
346
-                sprintf(
347
-                    esc_html__(
348
-                        'You cannot use the form section\'s name until _construct_finalize has been called on it (when we set the name). It was called on a form section of type \'s\'',
349
-                        'event_espresso'
350
-                    ),
351
-                    get_class($this)
352
-                )
353
-            );
354
-        }
355
-        return $this->_name;
356
-    }
357
-
358
-
359
-    /**
360
-     * Gets the parent section
361
-     *
362
-     * @return EE_Form_Section_Proper
363
-     */
364
-    public function parent_section()
365
-    {
366
-        return $this->_parent_section;
367
-    }
368
-
369
-
370
-    /**
371
-     * returns HTML for generating the opening form HTML tag (<form>)
372
-     *
373
-     * @param string $action           the URL the form is submitted to
374
-     * @param string $method           POST (default) or GET
375
-     * @param string $other_attributes anything else added to the form open tag, MUST BE VALID HTML
376
-     * @return string
377
-     * @throws EE_Error
378
-     */
379
-    public function form_open($action = '', $method = '', $other_attributes = '')
380
-    {
381
-        if (! empty($action)) {
382
-            $this->set_action($action);
383
-        }
384
-        if (! empty($method)) {
385
-            $this->set_method($method);
386
-        }
387
-        $html = EEH_HTML::nl(1, 'form') . '<form';
388
-        $html .= $this->html_id() !== '' ? ' id="' . $this->get_html_id_for_form($this->html_id()) . '"' : '';
389
-        $html .= ' action="' . esc_url_raw($this->action()) . '"';
390
-        $html .= ' method="' . $this->method() . '"';
391
-        $html .= ' name="' . $this->name() . '"';
392
-        $html .= ' ' . $other_attributes . '>';
393
-        return $html;
394
-    }
395
-
396
-
397
-    /**
398
-     * ensures that html id for form either ends in "-form" or "-frm"
399
-     * so that id doesn't conflict/collide with other elements
400
-     *
401
-     * @param string $html_id
402
-     * @return string
403
-     */
404
-    protected function get_html_id_for_form($html_id)
405
-    {
406
-        $strlen  = strlen($html_id);
407
-        $html_id = strpos($html_id, '-form') === $strlen - 5 || strpos($html_id, '-frm') === $strlen - 4
408
-            ? $html_id
409
-            : $html_id . '-frm';
410
-        return $html_id;
411
-    }
412
-
413
-
414
-    /**
415
-     * returns HTML for generating the closing form HTML tag (</form>)
416
-     *
417
-     * @return string
418
-     * @throws EE_Error
419
-     */
420
-    public function form_close()
421
-    {
422
-        return EEH_HTML::nl(-1, 'form')
423
-               . '</form>'
424
-               . EEH_HTML::nl()
425
-               . '<!-- end of ee-'
426
-               . $this->html_id()
427
-               . '-form -->'
428
-               . EEH_HTML::nl();
429
-    }
430
-
431
-
432
-    /**
433
-     * enqueues JS (and CSS) for the form (ie immediately call wp_enqueue_script and
434
-     * wp_enqueue_style; the scripts could have optionally been registered earlier)
435
-     * Default does nothing, but child classes can override
436
-     *
437
-     * @return void
438
-     */
439
-    public function enqueue_js()
440
-    {
441
-        // defaults to enqueue NO js or css
442
-    }
443
-
444
-
445
-    /**
446
-     * Adds any extra data needed by js. Eventually we'll call wp_localize_script
447
-     * with it, and it will be on each form section's 'other_data' property.
448
-     * By default nothing is added, but child classes can extend this method to add something.
449
-     * Eg, if you have an input that will cause a modal dialog to appear,
450
-     * here you could add an entry like 'modal_dialog_inputs' to this array
451
-     * to map between the input's html ID and the modal dialogue's ID, so that
452
-     * your JS code will know where to find the modal dialog when the input is pressed.
453
-     * Eg $form_other_js_data['modal_dialog_inputs']['some-input-id']='modal-dialog-id';
454
-     *
455
-     * @param array $form_other_js_data
456
-     * @return array
457
-     */
458
-    public function get_other_js_data($form_other_js_data = [])
459
-    {
460
-        return $form_other_js_data;
461
-    }
462
-
463
-
464
-    /**
465
-     * This isn't just the name of an input, it's a path pointing to an input. The
466
-     * path is similar to a folder path: slash (/) means to descend into a subsection,
467
-     * dot-dot-slash (../) means to ascend into the parent section.
468
-     * After a series of slashes and dot-dot-slashes, there should be the name of an input,
469
-     * which will be returned.
470
-     * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
471
-     * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
472
-     * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
473
-     * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
474
-     * Etc
475
-     *
476
-     * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
477
-     * @return EE_Form_Section_Base
478
-     */
479
-    public function find_section_from_path($form_section_path)
480
-    {
481
-        if (strpos($form_section_path, '/') === 0) {
482
-            $form_section_path = substr($form_section_path, strlen('/'));
483
-        }
484
-        if (empty($form_section_path)) {
485
-            return $this;
486
-        }
487
-        if (strpos($form_section_path, '../') === 0) {
488
-            $parent            = $this->parent_section();
489
-            $form_section_path = substr($form_section_path, strlen('../'));
490
-            if ($parent instanceof EE_Form_Section_Base) {
491
-                return $parent->find_section_from_path($form_section_path);
492
-            }
493
-            if (empty($form_section_path)) {
494
-                return $this;
495
-            }
496
-        }
497
-        // couldn't find it using simple parent following
498
-        return null;
499
-    }
17
+	/**
18
+	 * the URL the form is submitted to
19
+	 *
20
+	 * @var string
21
+	 */
22
+	protected string $_action = '';
23
+
24
+	/**
25
+	 * POST (default) or GET
26
+	 *
27
+	 * @var string
28
+	 */
29
+	protected string $_method = '';
30
+
31
+	/**
32
+	 * html_id and html_name are derived from this by default
33
+	 *
34
+	 * @var string
35
+	 */
36
+	protected string $_name = '';
37
+
38
+	/**
39
+	 * $_html_id
40
+	 * @var string
41
+	 */
42
+	protected string $_html_id = '';
43
+
44
+	/**
45
+	 * $_html_class
46
+	 * @var string
47
+	 */
48
+	protected string $_html_class = '';
49
+
50
+	/**
51
+	 * $_html_style
52
+	 * @var string
53
+	 */
54
+	protected string $_html_style = '';
55
+
56
+	/**
57
+	 * $_other_html_attributes
58
+	 * @var string
59
+	 */
60
+	protected string $_other_html_attributes = '';
61
+
62
+	/**
63
+	 * The form section of which this form section is a part
64
+	 *
65
+	 * @var EE_Form_Section_Base|null
66
+	 */
67
+	protected ?EE_Form_Section_Base $_parent_section = null;
68
+
69
+	/**
70
+	 * flag indicating that _construct_finalize has been called.
71
+	 * If it has not been called and we try to use functions which require it, we call it
72
+	 * with no parameters. But normally, _construct_finalize should be called by the instantiating class
73
+	 *
74
+	 * @var bool
75
+	 */
76
+	protected bool $_construction_finalized = false;
77
+
78
+	/**
79
+	 * Strategy for parsing the form HTML upon display
80
+	 *
81
+	 * @var FormHtmlFilter|null
82
+	 */
83
+	protected ?FormHtmlFilter $_form_html_filter = null;
84
+
85
+
86
+	/**
87
+	 * @param array $options_array {
88
+	 * @type        $name          string the name for this form section, if you want to explicitly define it
89
+	 *                             }
90
+	 * @throws InvalidDataTypeException
91
+	 */
92
+	public function __construct(array $options_array = [])
93
+	{
94
+		// set parser which allows the form section's rendered HTML to be filtered
95
+		if (isset($options_array['form_html_filter']) && $options_array['form_html_filter'] instanceof FormHtmlFilter) {
96
+			$this->_form_html_filter = $options_array['form_html_filter'];
97
+			unset($options_array['form_html_filter']);
98
+		}
99
+		// used by display strategies
100
+		// assign incoming values to properties
101
+		foreach ($options_array as $key => $value) {
102
+			$setter = 'set_' . $key;
103
+			if (method_exists($this, $setter)) {
104
+				$this->$setter($value);
105
+				continue;
106
+			}
107
+			$_key = "_$key";
108
+			if (property_exists($this, $_key) && empty($this->{$_key})) {
109
+				if ($_key === '_subsections' && ! is_array($value)) {
110
+					throw new InvalidDataTypeException($_key, $value, 'array');
111
+				}
112
+				$this->{$_key} = $value;
113
+			}
114
+		}
115
+	}
116
+
117
+
118
+	/**
119
+	 * @param EE_Form_Section_Base|null $parent_form_section
120
+	 * @param $name
121
+	 */
122
+	protected function _construct_finalize($parent_form_section, $name)
123
+	{
124
+		$this->_construction_finalized = true;
125
+		$this->_parent_section         = $parent_form_section;
126
+		if ($name !== null) {
127
+			$this->_name = $name;
128
+		}
129
+	}
130
+
131
+
132
+	/**
133
+	 * make sure construction finalized was called, otherwise children might not be ready
134
+	 *
135
+	 * @return void
136
+	 */
137
+	public function ensure_construct_finalized_called()
138
+	{
139
+		if (! $this->_construction_finalized) {
140
+			$this->_construct_finalize($this->_parent_section, $this->_name);
141
+		}
142
+	}
143
+
144
+
145
+	/**
146
+	 * @return string
147
+	 */
148
+	public function action()
149
+	{
150
+		return $this->_action;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @param string $action
156
+	 */
157
+	public function set_action($action)
158
+	{
159
+		$this->_action = $action;
160
+	}
161
+
162
+
163
+	/**
164
+	 * @return string
165
+	 */
166
+	public function method()
167
+	{
168
+		return ! empty($this->_method) ? $this->_method : 'POST';
169
+	}
170
+
171
+
172
+	/**
173
+	 * @param string $method
174
+	 */
175
+	public function set_method($method)
176
+	{
177
+		switch ($method) {
178
+			case 'get':
179
+			case 'GET':
180
+				$this->_method = 'GET';
181
+				break;
182
+			default:
183
+				$this->_method = 'POST';
184
+		}
185
+	}
186
+
187
+
188
+	/**
189
+	 * Sets the html_id to its default value, if none was specified in the constructor.
190
+	 * Calculation involves using the name and the parent's html id
191
+	 * return void
192
+	 *
193
+	 * @throws \EE_Error
194
+	 */
195
+	protected function _set_default_html_id_if_empty()
196
+	{
197
+		if (! $this->_html_id) {
198
+			if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
199
+				$this->_html_id = $this->_parent_section->html_id()
200
+								  . '-'
201
+								  . $this->_prep_name_for_html_id($this->name());
202
+			} else {
203
+				$this->_html_id = $this->_prep_name_for_html_id($this->name());
204
+			}
205
+		}
206
+	}
207
+
208
+
209
+	/**
210
+	 * _prep_name_for_html_id
211
+	 *
212
+	 * @param $name
213
+	 * @return string
214
+	 */
215
+	private function _prep_name_for_html_id($name)
216
+	{
217
+		return sanitize_key(str_replace(['&nbsp;', ' ', '_'], '-', $name));
218
+	}
219
+
220
+
221
+	/**
222
+	 * Returns the HTML, JS, and CSS necessary to display this form section on a page.
223
+	 * Note however, it's recommended that you instead call enqueue_js on the "wp_enqueue_scripts" action,
224
+	 * and call get_html when you want to output the html. Calling get_html_and_js after
225
+	 * "wp_enqueue_scripts" has already fired seems to work for now, but is contrary
226
+	 * to the instructions on https://developer.wordpress.org/reference/functions/wp_enqueue_script/
227
+	 * and so might stop working anytime.
228
+	 *
229
+	 * @return string
230
+	 */
231
+	public function get_html_and_js()
232
+	{
233
+		return $this->get_html();
234
+	}
235
+
236
+
237
+	/**
238
+	 * Gets the HTML for displaying this form section
239
+	 *
240
+	 * @return string
241
+	 */
242
+	abstract public function get_html();
243
+
244
+
245
+	/**
246
+	 * @param bool $add_pound_sign
247
+	 * @return string
248
+	 * @throws EE_Error
249
+	 */
250
+	public function html_id($add_pound_sign = false)
251
+	{
252
+		$this->_set_default_html_id_if_empty();
253
+		return $add_pound_sign ? '#' . $this->_html_id : $this->_html_id;
254
+	}
255
+
256
+
257
+	/**
258
+	 * @return string
259
+	 */
260
+	public function html_class()
261
+	{
262
+		return $this->_html_class;
263
+	}
264
+
265
+
266
+	/**
267
+	 * @return string
268
+	 */
269
+	public function html_style()
270
+	{
271
+		return $this->_html_style;
272
+	}
273
+
274
+
275
+	/**
276
+	 * @param string $html_class
277
+	 */
278
+	public function add_html_class(string $html_class)
279
+	{
280
+		$this->_html_class .= ' ' . trim($html_class);
281
+	}
282
+
283
+
284
+	/**
285
+	 * @param string $html_class
286
+	 */
287
+	public function set_html_class(string $html_class)
288
+	{
289
+		$this->_html_class = trim($html_class);
290
+	}
291
+
292
+
293
+	/**
294
+	 * @param mixed $html_id
295
+	 */
296
+	public function set_html_id($html_id)
297
+	{
298
+		$this->_html_id = $html_id;
299
+	}
300
+
301
+
302
+	/**
303
+	 * @param mixed $html_style
304
+	 */
305
+	public function set_html_style($html_style)
306
+	{
307
+		$this->_html_style = $html_style;
308
+	}
309
+
310
+
311
+	/**
312
+	 * @param string $other_html_attributes
313
+	 */
314
+	public function set_other_html_attributes($other_html_attributes)
315
+	{
316
+		if (empty($other_html_attributes)) {
317
+			return;
318
+		}
319
+		// make sure attributes are separated by a space
320
+		$other_html_attributes = strpos($other_html_attributes, ' ') !== 0
321
+			? " $other_html_attributes"
322
+			: $other_html_attributes;
323
+		$this->_other_html_attributes .= $other_html_attributes;
324
+	}
325
+
326
+
327
+	/**
328
+	 * @return string
329
+	 */
330
+	public function other_html_attributes()
331
+	{
332
+		return ! empty($this->_other_html_attributes) ? ' ' . $this->_other_html_attributes : '';
333
+	}
334
+
335
+
336
+	/**
337
+	 * Gets the name of the form section. This is not the same as the HTML name.
338
+	 *
339
+	 * @return string
340
+	 * @throws EE_Error
341
+	 */
342
+	public function name()
343
+	{
344
+		if (! $this->_construction_finalized) {
345
+			throw new EE_Error(
346
+				sprintf(
347
+					esc_html__(
348
+						'You cannot use the form section\'s name until _construct_finalize has been called on it (when we set the name). It was called on a form section of type \'s\'',
349
+						'event_espresso'
350
+					),
351
+					get_class($this)
352
+				)
353
+			);
354
+		}
355
+		return $this->_name;
356
+	}
357
+
358
+
359
+	/**
360
+	 * Gets the parent section
361
+	 *
362
+	 * @return EE_Form_Section_Proper
363
+	 */
364
+	public function parent_section()
365
+	{
366
+		return $this->_parent_section;
367
+	}
368
+
369
+
370
+	/**
371
+	 * returns HTML for generating the opening form HTML tag (<form>)
372
+	 *
373
+	 * @param string $action           the URL the form is submitted to
374
+	 * @param string $method           POST (default) or GET
375
+	 * @param string $other_attributes anything else added to the form open tag, MUST BE VALID HTML
376
+	 * @return string
377
+	 * @throws EE_Error
378
+	 */
379
+	public function form_open($action = '', $method = '', $other_attributes = '')
380
+	{
381
+		if (! empty($action)) {
382
+			$this->set_action($action);
383
+		}
384
+		if (! empty($method)) {
385
+			$this->set_method($method);
386
+		}
387
+		$html = EEH_HTML::nl(1, 'form') . '<form';
388
+		$html .= $this->html_id() !== '' ? ' id="' . $this->get_html_id_for_form($this->html_id()) . '"' : '';
389
+		$html .= ' action="' . esc_url_raw($this->action()) . '"';
390
+		$html .= ' method="' . $this->method() . '"';
391
+		$html .= ' name="' . $this->name() . '"';
392
+		$html .= ' ' . $other_attributes . '>';
393
+		return $html;
394
+	}
395
+
396
+
397
+	/**
398
+	 * ensures that html id for form either ends in "-form" or "-frm"
399
+	 * so that id doesn't conflict/collide with other elements
400
+	 *
401
+	 * @param string $html_id
402
+	 * @return string
403
+	 */
404
+	protected function get_html_id_for_form($html_id)
405
+	{
406
+		$strlen  = strlen($html_id);
407
+		$html_id = strpos($html_id, '-form') === $strlen - 5 || strpos($html_id, '-frm') === $strlen - 4
408
+			? $html_id
409
+			: $html_id . '-frm';
410
+		return $html_id;
411
+	}
412
+
413
+
414
+	/**
415
+	 * returns HTML for generating the closing form HTML tag (</form>)
416
+	 *
417
+	 * @return string
418
+	 * @throws EE_Error
419
+	 */
420
+	public function form_close()
421
+	{
422
+		return EEH_HTML::nl(-1, 'form')
423
+			   . '</form>'
424
+			   . EEH_HTML::nl()
425
+			   . '<!-- end of ee-'
426
+			   . $this->html_id()
427
+			   . '-form -->'
428
+			   . EEH_HTML::nl();
429
+	}
430
+
431
+
432
+	/**
433
+	 * enqueues JS (and CSS) for the form (ie immediately call wp_enqueue_script and
434
+	 * wp_enqueue_style; the scripts could have optionally been registered earlier)
435
+	 * Default does nothing, but child classes can override
436
+	 *
437
+	 * @return void
438
+	 */
439
+	public function enqueue_js()
440
+	{
441
+		// defaults to enqueue NO js or css
442
+	}
443
+
444
+
445
+	/**
446
+	 * Adds any extra data needed by js. Eventually we'll call wp_localize_script
447
+	 * with it, and it will be on each form section's 'other_data' property.
448
+	 * By default nothing is added, but child classes can extend this method to add something.
449
+	 * Eg, if you have an input that will cause a modal dialog to appear,
450
+	 * here you could add an entry like 'modal_dialog_inputs' to this array
451
+	 * to map between the input's html ID and the modal dialogue's ID, so that
452
+	 * your JS code will know where to find the modal dialog when the input is pressed.
453
+	 * Eg $form_other_js_data['modal_dialog_inputs']['some-input-id']='modal-dialog-id';
454
+	 *
455
+	 * @param array $form_other_js_data
456
+	 * @return array
457
+	 */
458
+	public function get_other_js_data($form_other_js_data = [])
459
+	{
460
+		return $form_other_js_data;
461
+	}
462
+
463
+
464
+	/**
465
+	 * This isn't just the name of an input, it's a path pointing to an input. The
466
+	 * path is similar to a folder path: slash (/) means to descend into a subsection,
467
+	 * dot-dot-slash (../) means to ascend into the parent section.
468
+	 * After a series of slashes and dot-dot-slashes, there should be the name of an input,
469
+	 * which will be returned.
470
+	 * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
471
+	 * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
472
+	 * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
473
+	 * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
474
+	 * Etc
475
+	 *
476
+	 * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
477
+	 * @return EE_Form_Section_Base
478
+	 */
479
+	public function find_section_from_path($form_section_path)
480
+	{
481
+		if (strpos($form_section_path, '/') === 0) {
482
+			$form_section_path = substr($form_section_path, strlen('/'));
483
+		}
484
+		if (empty($form_section_path)) {
485
+			return $this;
486
+		}
487
+		if (strpos($form_section_path, '../') === 0) {
488
+			$parent            = $this->parent_section();
489
+			$form_section_path = substr($form_section_path, strlen('../'));
490
+			if ($parent instanceof EE_Form_Section_Base) {
491
+				return $parent->find_section_from_path($form_section_path);
492
+			}
493
+			if (empty($form_section_path)) {
494
+				return $this;
495
+			}
496
+		}
497
+		// couldn't find it using simple parent following
498
+		return null;
499
+	}
500 500
 }
501 501
 // End of file EE_Form_Section_Base.form.php
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Checkbox_Input.input.php 1 patch
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -11,24 +11,24 @@
 block discarded – undo
11 11
  */
12 12
 class EE_Checkbox_Input extends EE_Form_Input_With_Options_Base
13 13
 {
14
-    /**
15
-     * @param array  $input_settings
16
-     */
17
-    public function __construct($input_settings = [])
18
-    {
19
-        $this->_set_display_strategy(new EE_Checkbox_Display_Strategy());
20
-        $this->_add_validation_strategy(
14
+	/**
15
+	 * @param array  $input_settings
16
+	 */
17
+	public function __construct($input_settings = [])
18
+	{
19
+		$this->_set_display_strategy(new EE_Checkbox_Display_Strategy());
20
+		$this->_add_validation_strategy(
21 21
 			new EE_Enum_Validation_Strategy(
22 22
 				$input_settings['validation_error_message'] ?? null
23 23
 			)
24
-        );
24
+		);
25 25
 		$input_settings['default'] = is_array($input_settings['default'])
26 26
 			? $input_settings['default']
27 27
 			: [$input_settings['default']];
28
-        $html_label_text = $input_settings['html_label_text'] ?? '';
29
-        $value = $input_settings['value'] ?? '';
30
-        unset($input_settings['html_label_text'], $input_settings['value']);
31
-        $this->_multiple_selections = false;
32
-        parent::__construct([$value => $html_label_text], $input_settings);
33
-    }
28
+		$html_label_text = $input_settings['html_label_text'] ?? '';
29
+		$value = $input_settings['value'] ?? '';
30
+		unset($input_settings['html_label_text'], $input_settings['value']);
31
+		$this->_multiple_selections = false;
32
+		parent::__construct([$value => $html_label_text], $input_settings);
33
+	}
34 34
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_State_Select_Input.php 2 patches
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -13,88 +13,88 @@
 block discarded – undo
13 13
  */
14 14
 class EE_State_Select_Input extends EE_Select_Input
15 15
 {
16
-    /**
17
-     * @var string the name of the EE_State field to use for option values in the HTML form input.
18
-     */
19
-    protected string $valueFieldName;
16
+	/**
17
+	 * @var string the name of the EE_State field to use for option values in the HTML form input.
18
+	 */
19
+	protected string $valueFieldName;
20 20
 
21 21
 
22
-    /**
23
-     * @param EE_State[]|array|null $state_options    . If a flat array of string is provided,
24
-     *                                                $input_settings['value_field_name'] is ignored. If an array of
25
-     *                                                states is passed, that field will be used for the keys (which
26
-     *                                                will become the option values). If null or empty is passed, all
27
-     *                                                active states will be used, and
28
-     *                                                $input_settings['value_field_name'] will again be used.     *
29
-     * @param array                 $input_settings   same as parent, but also {
30
-     * @type string                 $value_field_name the name of the field to use
31
-     *                                                for the HTML option values, ie, `STA_ID`, `STA_abbrev`, or
32
-     *                                                `STA_name`.
33
-     *                                                }
34
-     * @throws EE_Error
35
-     * @throws InvalidArgumentException
36
-     * @throws InvalidDataTypeException
37
-     * @throws InvalidInterfaceException
38
-     * @throws ReflectionException
39
-     */
40
-    public function __construct($state_options, $input_settings = [])
41
-    {
42
-        $this->valueFieldName = 'STA_ID';
43
-        if (isset($input_settings['value_field_name'])) {
44
-            $this->valueFieldName = (string) $input_settings['value_field_name'];
45
-            if (! EEM_State::instance()->has_field($this->valueFieldName)) {
46
-                throw new InvalidArgumentException(
47
-                    sprintf(
48
-                        esc_html__(
49
-                            'An invalid state field "%1$s" was specified for the state input\'s option values.',
50
-                            'event_espresso'
51
-                        ),
52
-                        $this->valueFieldName()
53
-                    )
54
-                );
55
-            }
56
-        }
57
-        $state_options                = apply_filters(
58
-            'FHEE__EE_State_Select_Input____construct__state_options',
59
-            $this->get_state_answer_options($state_options),
60
-            $this
61
-        );
62
-        $input_settings['html_class'] = isset($input_settings['html_class'])
63
-            ? $input_settings['html_class'] . ' ee-state-select-js'
64
-            : 'ee-state-select-js';
65
-        parent::__construct($state_options, $input_settings);
66
-    }
22
+	/**
23
+	 * @param EE_State[]|array|null $state_options    . If a flat array of string is provided,
24
+	 *                                                $input_settings['value_field_name'] is ignored. If an array of
25
+	 *                                                states is passed, that field will be used for the keys (which
26
+	 *                                                will become the option values). If null or empty is passed, all
27
+	 *                                                active states will be used, and
28
+	 *                                                $input_settings['value_field_name'] will again be used.     *
29
+	 * @param array                 $input_settings   same as parent, but also {
30
+	 * @type string                 $value_field_name the name of the field to use
31
+	 *                                                for the HTML option values, ie, `STA_ID`, `STA_abbrev`, or
32
+	 *                                                `STA_name`.
33
+	 *                                                }
34
+	 * @throws EE_Error
35
+	 * @throws InvalidArgumentException
36
+	 * @throws InvalidDataTypeException
37
+	 * @throws InvalidInterfaceException
38
+	 * @throws ReflectionException
39
+	 */
40
+	public function __construct($state_options, $input_settings = [])
41
+	{
42
+		$this->valueFieldName = 'STA_ID';
43
+		if (isset($input_settings['value_field_name'])) {
44
+			$this->valueFieldName = (string) $input_settings['value_field_name'];
45
+			if (! EEM_State::instance()->has_field($this->valueFieldName)) {
46
+				throw new InvalidArgumentException(
47
+					sprintf(
48
+						esc_html__(
49
+							'An invalid state field "%1$s" was specified for the state input\'s option values.',
50
+							'event_espresso'
51
+						),
52
+						$this->valueFieldName()
53
+					)
54
+				);
55
+			}
56
+		}
57
+		$state_options                = apply_filters(
58
+			'FHEE__EE_State_Select_Input____construct__state_options',
59
+			$this->get_state_answer_options($state_options),
60
+			$this
61
+		);
62
+		$input_settings['html_class'] = isset($input_settings['html_class'])
63
+			? $input_settings['html_class'] . ' ee-state-select-js'
64
+			: 'ee-state-select-js';
65
+		parent::__construct($state_options, $input_settings);
66
+	}
67 67
 
68 68
 
69
-    /**
70
-     * Returns the name of the state field used for the HTML option values.
71
-     *
72
-     * @return string
73
-     * @since 4.10.0.p
74
-     */
75
-    public function valueFieldName(): string
76
-    {
77
-        return $this->valueFieldName;
78
-    }
69
+	/**
70
+	 * Returns the name of the state field used for the HTML option values.
71
+	 *
72
+	 * @return string
73
+	 * @since 4.10.0.p
74
+	 */
75
+	public function valueFieldName(): string
76
+	{
77
+		return $this->valueFieldName;
78
+	}
79 79
 
80 80
 
81
-    /**
82
-     * get_state_answer_options
83
-     *
84
-     * @param array|null $state_options
85
-     * @return array
86
-     * @throws EE_Error
87
-     * @throws InvalidArgumentException
88
-     * @throws ReflectionException
89
-     * @throws InvalidDataTypeException
90
-     * @throws InvalidInterfaceException
91
-     */
92
-    public function get_state_answer_options(?array $state_options = null): array
93
-    {
94
-        // if passed an array, then just return it
95
-        if (is_array($state_options) && reset($state_options) instanceof EE_State) {
96
-            return $state_options;
97
-        }
98
-        return States::arrayOfNames($this->valueFieldName);
99
-    }
81
+	/**
82
+	 * get_state_answer_options
83
+	 *
84
+	 * @param array|null $state_options
85
+	 * @return array
86
+	 * @throws EE_Error
87
+	 * @throws InvalidArgumentException
88
+	 * @throws ReflectionException
89
+	 * @throws InvalidDataTypeException
90
+	 * @throws InvalidInterfaceException
91
+	 */
92
+	public function get_state_answer_options(?array $state_options = null): array
93
+	{
94
+		// if passed an array, then just return it
95
+		if (is_array($state_options) && reset($state_options) instanceof EE_State) {
96
+			return $state_options;
97
+		}
98
+		return States::arrayOfNames($this->valueFieldName);
99
+	}
100 100
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -42,7 +42,7 @@  discard block
 block discarded – undo
42 42
         $this->valueFieldName = 'STA_ID';
43 43
         if (isset($input_settings['value_field_name'])) {
44 44
             $this->valueFieldName = (string) $input_settings['value_field_name'];
45
-            if (! EEM_State::instance()->has_field($this->valueFieldName)) {
45
+            if ( ! EEM_State::instance()->has_field($this->valueFieldName)) {
46 46
                 throw new InvalidArgumentException(
47 47
                     sprintf(
48 48
                         esc_html__(
@@ -54,13 +54,13 @@  discard block
 block discarded – undo
54 54
                 );
55 55
             }
56 56
         }
57
-        $state_options                = apply_filters(
57
+        $state_options = apply_filters(
58 58
             'FHEE__EE_State_Select_Input____construct__state_options',
59 59
             $this->get_state_answer_options($state_options),
60 60
             $this
61 61
         );
62 62
         $input_settings['html_class'] = isset($input_settings['html_class'])
63
-            ? $input_settings['html_class'] . ' ee-state-select-js'
63
+            ? $input_settings['html_class'].' ee-state-select-js'
64 64
             : 'ee-state-select-js';
65 65
         parent::__construct($state_options, $input_settings);
66 66
     }
Please login to merge, or discard this patch.