PluginProbe
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management / 1.6.1
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management v1.6.1
1.6.1 1.6.0 1.5.1 1.5.0 1.4.0 1.3.0 trunk 0.0.1 1.0.0 1.1.0 1.1.1 1.1.2 1.2.0
← All changes | inc/fields/form-styling.php +104 -23 1.3.0 → 1.6.1 View file →
@@ -90,36 +90,40 @@
90 90 * @since 1.0.0
91 91 */
92 92 public static function get_defaults() {
93 93 return [
94 - 'bgType' => 'color',
95 - 'bgColor' => '',
96 - 'bgGradient' => 'linear-gradient(90deg,#FFC9B2 0%,#C7CBFF 100%)',
97 - 'bgImage' => '',
98 - 'bgImageId' => 0,
99 - 'bgImageSize' => 'cover',
100 - 'bgImagePosition' => 'center center',
101 - 'bgImageRepeat' => 'no-repeat',
94 + 'bgType' => 'color',
95 + 'bgColor' => '',
96 + 'bgGradient' => 'linear-gradient(90deg,#FFC9B2 0%,#C7CBFF 100%)',
97 + 'bgImage' => '',
98 + 'bgImageId' => 0,
99 + 'bgImageSize' => 'cover',
100 + 'bgImagePosition' => 'center center',
101 + 'bgImageRepeat' => 'no-repeat',
102 102 // Colors default to empty here so unset values fall through to the
103 103 // :root defaults in _variables.scss (the editor's STYLE_DEFAULTS seeds
104 104 // the actual hex values instead, only to populate the panel swatches).
105 - 'primaryColor' => '',
106 - 'textColor' => '',
107 - 'textOnPrimaryColor' => '',
108 - 'padding' => [
105 + 'primaryColor' => '',
106 + 'textColor' => '',
107 + 'textOnPrimaryColor' => '',
108 + 'padding' => [
109 109 'top' => '',
110 110 'right' => '',
111 111 'bottom' => '',
112 112 'left' => '',
113 113 ],
114 - 'borderRadius' => [
114 + 'borderRadius' => [
115 115 'top' => '',
116 116 'right' => '',
117 117 'bottom' => '',
118 118 'left' => '',
119 119 ],
120 - 'fieldSpacing' => 'medium',
121 - 'buttonAlignment' => 'justify',
120 + 'fieldSpacing' => 'medium',
121 + 'buttonAlignment' => 'justify',
122 + // When true the form renders without the SureDonation stylesheet and
123 + // inline CSS variables so the site's own CSS fully controls its
124 + // appearance (mirrors SureForms' disable_default_styles).
125 + 'disable_default_styles' => false,
122 126 ];
123 127 }
124 128
125 129 /**
@@ -187,13 +191,52 @@
187 191 $clean['borderRadius'] = self::sanitize_box( $decoded['borderRadius'] ?? [], $defaults['borderRadius'] );
188 192 $clean['fieldSpacing'] = in_array( $decoded['fieldSpacing'] ?? '', [ 'small', 'medium', 'large' ], true ) ? $decoded['fieldSpacing'] : 'medium';
189 193 $clean['buttonAlignment'] = in_array( $decoded['buttonAlignment'] ?? '', [ 'left', 'center', 'right', 'justify' ], true ) ? $decoded['buttonAlignment'] : 'justify';
190 194
195 + // Boolean flag, not a style value — must survive sanitization or an
196 + // editor save silently re-enables the default styling.
197 + $clean['disable_default_styles'] = ! empty( $decoded['disable_default_styles'] );
198 +
191 199 $encoded = wp_json_encode( $clean );
192 200 return is_string( $encoded ) ? $encoded : '';
193 201 }
194 202
195 203 /**
204 + * Check whether the form renders without SureDonation's default styling.
205 + *
206 + * When enabled the frontend stylesheet is not enqueued for the form and the
207 + * inline CSS-variable style attribute is omitted, so the site's own CSS
208 + * fully controls the form's appearance. The container is stamped with an
209 + * `sd-styling-none` marker class so custom CSS can target the state.
210 + *
211 + * @param int $form_id Form post ID.
212 + * @return bool True when default styling is disabled for the form.
213 + * @since 1.4.0
214 + */
215 + public static function is_default_styling_disabled( $form_id ) {
216 + $form_id = absint( $form_id );
217 + if ( ! $form_id ) {
218 + return false;
219 + }
220 +
221 + $settings = self::get_settings( $form_id );
222 + $disabled = ! empty( $settings['disable_default_styles'] );
223 +
224 + /**
225 + * Filters whether SureDonation's default frontend styling is disabled for a form.
226 + *
227 + * Lets themes/plugins toggle the unstyled mode programmatically, overriding
228 + * the stored per-form meta. Return true to render the form without the
229 + * SureDonation stylesheet and inline CSS variables.
230 + *
231 + * @param bool $disabled Whether default styling is disabled (from meta).
232 + * @param int $form_id Form post ID.
233 + * @since 1.4.0
234 + */
235 + return (bool) apply_filters( 'suredonation_disable_default_styles', $disabled, $form_id );
236 + }
237 +
238 + /**
196 239 * Build the inline CSS custom-property string for the form wrapper.
197 240 *
198 241 * Returns the CSS declarations only (no surrounding style attribute). The
199 242 * caller is expected to output the result via esc_attr() inside a style
@@ -203,8 +246,14 @@
203 246 * @return string CSS declarations, or '' when nothing is customized.
204 247 * @since 1.0.0
205 248 */
206 249 public static function get_style_attr( $form_id ) {
250 + // Unstyled mode: no inline CSS variables either — an inline style on the
251 + // container would override any site/custom CSS that themes the form.
252 + if ( self::is_default_styling_disabled( $form_id ) ) {
253 + return '';
254 + }
255 +
207 256 $settings = self::get_settings( $form_id );
208 257 $vars = [];
209 258
210 259 // Colors. Color-derived tints are emitted per-form so they track the
@@ -275,14 +324,42 @@
275 324 $vars['--sd-btn-align-items'] = $align_map[ $settings['buttonAlignment'] ];
276 325 $vars['--sd-btn-width'] = 'auto';
277 326 }
278 327
279 - if ( empty( $vars ) ) {
328 + /**
329 + * Filter the form style CSS custom properties before they are serialized
330 + * onto the `.sd-form-container` wrapper.
331 + *
332 + * Add-ons (e.g. SureDonation Pro) use this to contribute additional
333 + * `--sd-*` variables. Runs before the empty-check so an add-on can style a
334 + * form even when the free panel set nothing. Values must be pre-sanitized
335 + * CSS tokens — they are emitted verbatim inside the inline style attribute.
336 + *
337 + * @param array<string, string> $vars Map of `--sd-*` variable => value.
338 + * @param int $form_id Form post ID.
339 + * @param array<string, mixed> $settings Merged free style settings.
340 + * @since 1.5.0
341 + */
342 + $vars = apply_filters( 'suredonation_form_style_vars', $vars, (int) $form_id, $settings );
343 +
344 + if ( ! is_array( $vars ) || empty( $vars ) ) {
280 345 return '';
281 346 }
282 347
283 348 $declarations = [];
284 349 foreach ( $vars as $name => $value ) {
350 + // Defense-in-depth for the public filter above: only emit custom
351 + // properties with scalar, declaration-safe values, so a
352 + // non-sanitizing add-on callback cannot append arbitrary
353 + // declarations or trigger array-to-string notices. Values are
354 + // additionally escaped by the caller via esc_attr().
355 + if (
356 + ! is_scalar( $value )
357 + || ! preg_match( '/^--[A-Za-z0-9_-]+$/', (string) $name )
358 + || preg_match( '/[;{}]/', (string) $value )
359 + ) {
360 + continue;
361 + }
285 362 $declarations[] = $name . ':' . $value;
286 363 }
287 364
288 365 return implode( ';', $declarations ) . ';';
@@ -358,9 +435,9 @@
358 435 * @param array<string, mixed> $fallback Default box.
359 436 * @return array<string, mixed>
360 437 * @since 1.0.0
361 438 */
362 - private static function sanitize_box( $box, $fallback ) {
439 + public static function sanitize_box( $box, $fallback ) {
363 440 if ( ! is_array( $box ) ) {
364 441 return $fallback;
365 442 }
366 443
@@ -374,21 +451,25 @@
374 451
375 452 /**
376 453 * Validate a CSS length (e.g. "10px", "1.5rem"); bare numbers become px.
377 454 *
455 + * Negative values are rejected: every consumer here (padding, border
456 + * radius) is invalid with a negative length, which the browser would
457 + * silently drop.
458 + *
378 459 * @param mixed $value Incoming value.
379 - * @return string Valid length, or '' when invalid/empty.
460 + * @return string Valid length, or '' when invalid/empty/negative.
380 461 * @since 1.0.0
381 462 */
382 - private static function sanitize_length( $value ) {
463 + public static function sanitize_length( $value ) {
383 464 if ( is_numeric( $value ) ) {
384 - return ( 0 + $value ) . 'px';
465 + return $value < 0 ? '' : ( 0 + $value ) . 'px';
385 466 }
386 467 $value = is_string( $value ) ? trim( $value ) : '';
387 468 if ( '' === $value ) {
388 469 return '';
389 470 }
390 - return preg_match( '/^-?\d*\.?\d+(px|em|rem|%|vw|vh)$/', $value ) ? $value : '';
471 + return preg_match( '/^\d*\.?\d+(px|em|rem|%|vw|vh)$/', $value ) ? $value : '';
391 472 }
392 473
393 474 /**
394 475 * Sanitize a color value via a strict allowlist.
@@ -400,9 +481,9 @@
400 481 * @param mixed $value Incoming color.
401 482 * @return string Valid color, or '' when invalid/empty.
402 483 * @since 1.0.0
403 484 */
404 - private static function sanitize_color( $value ) {
485 + public static function sanitize_color( $value ) {
405 486 $value = is_string( $value ) ? trim( $value ) : '';
406 487 if ( '' === $value ) {
407 488 return '';
408 489 }
@@ -440,9 +521,9 @@
440 521 * @param mixed $value Incoming gradient.
441 522 * @return string Valid gradient, or '' when invalid/empty.
442 523 * @since 1.0.0
443 524 */
444 - private static function sanitize_gradient( $value ) {
525 + public static function sanitize_gradient( $value ) {
445 526 $value = is_string( $value ) ? trim( $value ) : '';
446 527 if ( '' === $value ) {
447 528 return '';
448 529 }