PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.12.8
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.12.8
2.12.8 2.12.7 2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 All 98 releases
← All changes | inc/fields/multichoice-markup.php +91 -0 2.8.0 → 2.12.8 View file →
@@ -9,8 +9,9 @@
9 9 namespace SRFM\Inc\Fields;
10 10
11 11 use Spec_Gb_Helper;
12 12 use SRFM\Inc\Helper;
13 +use SRFM\Inc\Smart_Tags;
13 14
14 15 if ( ! defined( 'ABSPATH' ) ) {
15 16 exit; // Exit if accessed directly.
16 17 }
@@ -121,8 +122,9 @@
121 122 $this->name_attr = $this->single_selection ? 'name="srfm-input-' . esc_attr( $this->slug ) . '-' . esc_attr( $this->block_id ) . '"' : '';
122 123 $this->choice_width_attr = $this->choice_width ? 'srfm-choice-width-' . str_replace( '.', '-', $this->choice_width ) : '';
123 124 $this->show_values = apply_filters( 'srfm_show_options_values', false, $attributes['showValues'] ?? false );
124 125 $this->preselected_options = $attributes['preselectedOptions'] ?? [];
126 + $this->resolve_dynamic_default( $attributes );
125 127 $this->set_markup_properties();
126 128 $this->set_aria_described_by();
127 129 }
128 130
@@ -198,8 +200,97 @@
198 200 'field_name' => $this->field_name,
199 201 'attributes' => $this->attributes,
200 202 ]
201 203 );
204 + }
205 +
206 + /**
207 + * Resolve dynamic default value from smart tags and override preselected options.
208 + *
209 + * Radio (single-selection) mode matches the resolved value as a single
210 + * trimmed string, so option titles that legitimately contain delimiter
211 + * characters (commas, pipes, etc.) still match.
212 + *
213 + * Checkbox mode splits the resolved value on the pipe character (`|`) and
214 + * matches every segment (for example "{get_input:a}|{get_input:b}" resolving
215 + * to "Red|Blue", or a single `{get_input:colors}` with URL
216 + * `?colors=Red|Blue`). The same pipe split applies to multi-character
217 + * resolved values from `{get_input:...}` and `{get_cookie:...}`, so cookie
218 + * payloads that contain pipes are treated as multi-value in checkbox mode.
219 + *
220 + * When the `Add Numeric Values to Options` (showValues) setting is on,
221 + * each segment is also compared against the option's `value`.
222 + *
223 + * @param array<mixed> $attributes Block attributes.
224 + * @since 2.8.1
225 + * @since 2.10.0 Added checkbox (pipe-delimited) multi-value matching.
226 + * @return void
227 + */
228 + protected function resolve_dynamic_default( $attributes ) {
229 + // Coalesce first so blocks saved before this attribute existed (pre-2.10.0)
230 + // don't trigger an "Undefined array key" warning on every frontend render.
231 + $raw_default = $attributes['dynamicDefaultValue'] ?? '';
232 + $dynamic_default = is_string( $raw_default ) ? $raw_default : '';
233 + if ( empty( $dynamic_default ) ) {
234 + return;
235 + }
236 +
237 + $smart_tags = new Smart_Tags();
238 + $resolved = $smart_tags->process_smart_tags( $dynamic_default );
239 +
240 + if ( empty( $resolved ) || ! is_string( $resolved ) || ! is_array( $this->options ) ) {
241 + return;
242 + }
243 +
244 + // START: multi-value dynamic default resolution.
245 + if ( ! $this->single_selection ) {
246 + $segments = array_filter(
247 + array_map( 'trim', explode( '|', $resolved ) ),
248 + static function ( $segment ) {
249 + return '' !== $segment;
250 + }
251 + );
252 + // Cap segments to avoid pathological URLs (e.g. ?colors=|||||...) producing thousands of comparisons.
253 + $segments = array_slice( $segments, 0, 50 );
254 + } else {
255 + $trimmed = trim( $resolved );
256 + $segments = '' === $trimmed ? [] : [ $trimmed ];
257 + }
258 +
259 + if ( empty( $segments ) ) {
260 + return;
261 + }
262 +
263 + $match_value_too = ! empty( $attributes['showValues'] );
264 + $matching_indices = [];
265 +
266 + foreach ( $segments as $segment ) {
267 + foreach ( $this->options as $i => $option ) {
268 + if ( ! is_array( $option ) || in_array( $i, $matching_indices, true ) ) {
269 + continue;
270 + }
271 +
272 + $option_title = isset( $option['optionTitle'] ) && is_scalar( $option['optionTitle'] ) ? (string) $option['optionTitle'] : '';
273 + $raw_value = $option['value'] ?? '';
274 + $option_value = $match_value_too && is_scalar( $raw_value ) ? (string) $raw_value : '';
275 +
276 + $is_match = ( '' !== $option_title && strcasecmp( $option_title, $segment ) === 0 )
277 + || ( $match_value_too && '' !== $option_value && strcasecmp( $option_value, $segment ) === 0 );
278 +
279 + if ( $is_match ) {
280 + $matching_indices[] = $i;
281 + if ( $this->single_selection ) {
282 + break 2;
283 + }
284 + break;
285 + }
286 + }
287 + }
288 +
289 + if ( ! empty( $matching_indices ) ) {
290 + $this->preselected_options = $this->single_selection ? [ $matching_indices[0] ] : $matching_indices;
291 + }
292 + // END: multi-value dynamic default resolution.
202 293 }
203 294
204 295 /**
205 296 * Data attribute markup for min and max value