PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.22.1
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.22.1
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/helpers/FrmStylesHelper.php +440 -129 6.36.22.1 View file →
@@ -37,10 +37,17 @@
37 37 'inside' => __( 'inside', 'formidable' ),
38 38 );
39 39 }
40 40
41 - public static function get_single_label_positions() {
42 - return array(
41 + /**
42 + * @since 6.11 Added $field param.
43 + *
44 + * @param array|object $field
45 + *
46 + * @return array
47 + */
48 + public static function get_single_label_positions( $field = array() ) {
49 + $label_positions = array(
43 50 'top' => __( 'Top', 'formidable' ),
44 51 'left' => __( 'Left', 'formidable' ),
45 52 'right' => __( 'Right', 'formidable' ),
46 53 'inline' => __( 'Inline (left without a set width)', 'formidable' ),
@@ -47,8 +54,18 @@
47 54 'none' => __( 'None', 'formidable' ),
48 55 'hidden' => __( 'Hidden (but leave the space)', 'formidable' ),
49 56 'inside' => __( 'Placeholder inside the field', 'formidable' ),
50 57 );
58 +
59 + /**
60 + * Allows updating label positions in field settings.
61 + *
62 + * @since 6.11
63 + *
64 + * @param array $label_positions
65 + * @param array|object $field
66 + */
67 + return apply_filters( 'frm_single_label_positions', $label_positions, $field );
51 68 }
52 69
53 70 public static function minus_icons() {
54 71 return array(
@@ -120,9 +137,9 @@
120 137 * @return string The class for this icon.
121 138 */
122 139 public static function icon_key_to_class( $key, $icon = '+', $type = 'arrow' ) {
123 140 if ( 'arrow' === $type && is_numeric( $key ) ) {
124 - //frm_arrowup6_icon
141 + // frm_arrowup6_icon.
125 142 $arrow = array(
126 143 '-' => 'down',
127 144 '+' => 'up',
128 145 );
@@ -127,9 +144,9 @@
127 144 '+' => 'up',
128 145 );
129 146 $class = 'frm_arrow' . $arrow[ $icon ];
130 147 } else {
131 - //frm_minus1_icon
148 + // frm_minus1_icon.
132 149 $key = str_replace( 'p', '', $key );
133 150 $plus = array(
134 151 '-' => 'minus',
135 152 '+' => 'plus',
@@ -165,9 +182,9 @@
165 182 <b class="caret"></b>
166 183 </button>
167 184 <ul class="multiselect-container frm-dropdown-menu">
168 185 <?php foreach ( $icons as $key => $icon ) { ?>
169 - <li <?php echo ( $style->post_content['collapse_icon'] == $key ) ? 'class="active"' : ''; ?>>
186 + <li <?php echo $style->post_content['collapse_icon'] == $key ? 'class="active"' : ''; ?>>
170 187 <a href="javascript:void(0);">
171 188 <label>
172 189 <input type="radio" value="<?php echo esc_attr( $key ); ?>" name="<?php echo esc_attr( $frm_style->get_field_name( $name ) ); ?>" <?php checked( $style->post_content[ $name ], $key ); ?> />
173 190 <span>
@@ -184,16 +201,55 @@
184 201 </div>
185 202 <?php
186 203 }
187 204
188 - public static function hex2rgb( $hex ) {
189 - $hex = str_replace( '#', '', $hex );
205 + /**
206 + * Convert a color setting to a RGB CSV (without the rgb()/rgba() wrapper).
207 + *
208 + * @since 2.0
209 + *
210 + * @param string $color Color setting value. This could be hex or rgb.
211 + * @return string RGB value without the rgb() wrapper.
212 + */
213 + public static function hex2rgb( $color ) {
214 + if ( 0 === strpos( $color, 'rgb' ) ) {
215 + $rgb = self::get_rgb_array_from_rgb( $color );
216 + } else {
217 + $rgb = self::get_rgb_array_from_hex( $color );
218 + }
219 + return implode( ',', $rgb );
220 + }
190 221
222 + /**
223 + * Remove the rgb()/rgba() wrapper from a RGB color and return its R, G and B values as an array.
224 + *
225 + * @since 6.8.3
226 + *
227 + * @param string $rgb RGB value including the rgb() or rgba() wrapper.
228 + * @return array<string> including three numeric values for R, G, and B.
229 + */
230 + private static function get_rgb_array_from_rgb( $rgb ) {
231 + $rgb = str_replace( array( 'rgb(', 'rgba(', ')' ), '', $rgb );
232 + $rgb = explode( ',', $rgb );
233 + if ( 4 === count( $rgb ) ) {
234 + // Drop the alpha. The function is expected to only return r,g,b with no alpha.
235 + array_pop( $rgb );
236 + }
237 + return $rgb;
238 + }
239 +
240 + /**
241 + * Get the R, G, and B array values from a Hex color code.
242 + *
243 + * @since 6.8.3
244 + *
245 + * @param string $hex A hex color string.
246 + * @return array<string> Including three numeric values for R, G, and B.
247 + */
248 + private static function get_rgb_array_from_hex( $hex ) {
249 + $hex = str_replace( '#', '', $hex );
191 250 list( $r, $g, $b ) = sscanf( $hex, '%02x%02x%02x' );
192 -
193 - $rgb = array( $r, $g, $b );
194 -
195 - return implode( ',', $rgb );
251 + return array( $r, $g, $b );
196 252 }
197 253
198 254 /**
199 255 * @since 4.0
@@ -206,13 +262,14 @@
206 262
207 263 /**
208 264 * @since 6.0
209 265 *
210 - * @param string $rgba
211 - * @return string
266 + * @param string $rgba Color setting value. This could be hex or rgb.
267 + * @return string Hex color value.
212 268 */
213 269 private static function rgb_to_hex( $rgba ) {
214 270 if ( strpos( $rgba, '#' ) === 0 ) {
271 + // Color is already hex.
215 272 return $rgba;
216 273 }
217 274 preg_match( '/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i', $rgba, $by_color );
218 275 return sprintf( '%02x%02x%02x', $by_color[1], $by_color[2], $by_color[3] );
@@ -218,12 +275,73 @@
218 275 return sprintf( '%02x%02x%02x', $by_color[1], $by_color[2], $by_color[3] );
219 276 }
220 277
221 278 /**
222 - * @param $hex string - The original color in hex format #ffffff
223 - * @param $steps integer - should be between -255 and 255. Negative = darker, positive = lighter
279 + * @since 6.8
224 280 *
281 + * @param string $hsl
282 + * @return string|null Null if it fails to parse the HSL string.
283 + */
284 + private static function hsl_to_hex( $hsl ) {
285 + // Convert hsla to hsl.
286 + $hsl = preg_replace( '/hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/', 'hsl($1, $2%, $3%)', $hsl );
287 +
288 + // Extract HSL components from the color string.
289 + preg_match( '/hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)/', $hsl, $matches );
290 +
291 + if ( count( $matches ) !== 4 ) {
292 + // Invalid HSL string format.
293 + return null;
294 + }
295 +
296 + // Extract HSL values.
297 + $h = (int) $matches[1];
298 + $s = (int) $matches[2] / 100;
299 + $l = (int) $matches[3] / 100;
300 +
301 + // Calculate RGB values.
302 + $c = ( 1 - abs( 2 * $l - 1 ) ) * $s;
303 + $x = $c * ( 1 - abs( ( (int) ( $h / 60 ) % 2 ) - 1 ) );
304 + $m = $l - $c / 2;
305 + $r = 0;
306 + $g = 0;
307 + $b = 0;
308 +
309 + if ( $h >= 0 && $h < 60 ) {
310 + $r = $c;
311 + $g = $x;
312 + } elseif ( $h >= 60 && $h < 120 ) {
313 + $r = $x;
314 + $g = $c;
315 + } elseif ( $h >= 120 && $h < 180 ) {
316 + $g = $c;
317 + $b = $x;
318 + } elseif ( $h >= 180 && $h < 240 ) {
319 + $g = $x;
320 + $b = $c;
321 + } elseif ( $h >= 240 && $h < 300 ) {
322 + $r = $x;
323 + $b = $c;
324 + } elseif ( $h >= 300 && $h < 360 ) {
325 + $r = $c;
326 + $b = $x;
327 + }//end if
328 +
329 + // Convert RGB to 8-bit values
330 + $r = round( ( $r + $m ) * 255 );
331 + $g = round( ( $g + $m ) * 255 );
332 + $b = round( ( $b + $m ) * 255 );
333 +
334 + // Convert RGB to hex
335 + $hex = sprintf( '%02x%02x%02x', $r, $g, $b );
336 +
337 + return $hex;
338 + }
339 +
340 + /**
225 341 * @since 2.3
342 + * @param string $hex string The original color in hex format #ffffff.
343 + * @param int $steps integer Should be between -255 and 255. Negative = darker, positive = lighter.
226 344 */
227 345 public static function adjust_brightness( $hex, $steps ) {
228 346 $steps = max( - 255, min( 255, $steps ) );
229 347
@@ -244,11 +362,15 @@
244 362 $color_parts = str_split( $hex, 2 );
245 363 $return = '#';
246 364
247 365 foreach ( $color_parts as $color ) {
248 - $color = hexdec( $color ); // Convert to decimal
249 - $color = max( 0, min( 255, $color + $steps ) ); // Adjust color
250 - $return .= str_pad( dechex( $color ), 2, '0', STR_PAD_LEFT ); // Make two char hex code
366 + // Convert to decimal.
367 + $color = hexdec( $color );
368 + // Adjust color.
369 + $color = max( 0, min( 255, $color + $steps ) );
370 +
371 + // Make two char hex code.
372 + $return .= str_pad( dechex( $color ), 2, '0', STR_PAD_LEFT );
251 373 }
252 374
253 375 return $return;
254 376 }
@@ -263,8 +385,17 @@
263 385 if ( 0 === strpos( $color, 'rgb' ) ) {
264 386 $color = self::rgb_to_hex( $color );
265 387 }
266 388
389 + if ( 0 === strpos( $color, 'hsl' ) ) {
390 + $hsl_to_hex = self::hsl_to_hex( $color );
391 + if ( is_null( $hsl_to_hex ) ) {
392 + // Fallback if we cannot convert the HSL value.
393 + return 0;
394 + }
395 + $color = $hsl_to_hex;
396 + }
397 +
267 398 self::fill_hex( $color );
268 399
269 400 $c_r = hexdec( substr( $color, 0, 2 ) );
270 401 $c_g = hexdec( substr( $color, 2, 2 ) );
@@ -278,9 +409,9 @@
278 409 * Change a 3 character hex color to a 6 character one.
279 410 *
280 411 * @since 6.0
281 412 *
282 - * @return array
413 + * @return void
283 414 */
284 415 private static function fill_hex( &$color ) {
285 416 if ( 3 === strlen( $color ) ) {
286 417 $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
@@ -301,13 +432,13 @@
301 432 public static function output_vars( $settings, $defaults = array(), $vars = array() ) {
302 433 if ( empty( $vars ) ) {
303 434 $vars = self::get_css_vars( array_keys( $settings ) );
304 435 }
305 - $remove = array( 'remove_box_shadow', 'remove_box_shadow_active', 'theme_css', 'theme_name', 'theme_selector', 'important_style', 'submit_style', 'collapse_icon', 'center_form', 'custom_css', 'style_class', 'submit_bg_img', 'change_margin', 'repeat_icon' );
436 + $remove = array( 'remove_box_shadow', 'remove_box_shadow_active', 'theme_css', 'theme_name', 'theme_selector', 'important_style', 'submit_style', 'collapse_icon', 'center_form', 'custom_css', 'style_class', 'submit_bg_img', 'change_margin', 'repeat_icon', 'use_base_font_size', 'field_shape_type' );
306 437 $vars = array_diff( $vars, $remove );
307 438
308 439 foreach ( $vars as $var ) {
309 - if ( ! isset( $settings[ $var ] ) ) {
440 + if ( ! isset( $settings[ $var ] ) || ! self::css_key_is_valid( $var ) ) {
310 441 continue;
311 442 }
312 443 if ( ! isset( $defaults[ $var ] ) ) {
313 444 $defaults[ $var ] = '';
@@ -312,15 +443,116 @@
312 443 if ( ! isset( $defaults[ $var ] ) ) {
313 444 $defaults[ $var ] = '';
314 445 }
315 446 $show = empty( $defaults ) || ( $settings[ $var ] !== '' && $settings[ $var ] !== $defaults[ $var ] );
316 - if ( $show ) {
317 - echo '--' . esc_html( str_replace( '_', '-', $var ) ) . ':' . ( $var === 'font' ? FrmAppHelper::kses( $settings[ $var ] ) : esc_html( $settings[ $var ] ) ) . ';'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
447 + if ( $show && self::css_value_is_valid( $settings[ $var ] ) ) {
448 + echo '--' . esc_html( self::clean_var_name( str_replace( '_', '-', $var ) ) ) . ':' . self::css_var_prepare_value( $settings, $var ) . ';'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
318 449 }
319 450 }
320 451 }
321 452
322 453 /**
454 + * Prevent invalid CSS keys from getting added to the generated CSS.
455 + *
456 + * @since 6.20
457 + *
458 + * @param string $key
459 + * @return bool
460 + */
461 + private static function css_key_is_valid( $key ) {
462 + // Any key that is abnormally large is not valid.
463 + // Any key that contains a '{' is not valid.
464 + return strlen( $key ) < 100 && false === strpos( $key, '{' );
465 + }
466 +
467 + /**
468 + * Confirm a CSS value is valid.
469 + * If it appears to contain JavaScript, it will not be added.
470 + *
471 + * @since 6.20
472 + *
473 + * @param string $var
474 + * @return bool
475 + */
476 + private static function css_value_is_valid( $var ) {
477 + // None of these substrings should be present in any CSS value.
478 + $invalid_substrings = array(
479 + 'function(',
480 + ';userAgent',
481 + ';stopPropagation',
482 + '{const',
483 + 'window[',
484 + 'navigator[',
485 + 'Array;',
486 + );
487 +
488 + foreach ( $invalid_substrings as $substring ) {
489 + if ( strpos( $var, $substring ) !== false ) {
490 + return false;
491 + }
492 + }
493 +
494 + return true;
495 + }
496 +
497 +
498 + /**
499 + * Remove anything that isn't used as a CSS variable name.
500 + *
501 + * @param string $var_name
502 + * @return string
503 + */
504 + private static function clean_var_name( $var_name ) {
505 + return preg_replace( '/[^a-zA-Z0-9_-]/', '', $var_name );
506 + }
507 +
508 + /**
509 + * Prepare the value for a CSS variable.
510 + *
511 + * @since 6.14
512 + *
513 + * @param array $settings An array of css style.
514 + * @param string $key
515 + *
516 + * @return string
517 + */
518 + private static function css_var_prepare_value( $settings, $key ) {
519 + $value = $settings[ $key ];
520 +
521 + switch ( $key ) {
522 + case 'font':
523 + return safecss_filter_attr( $value );
524 +
525 + case 'border_width_error':
526 + case 'field_border_width':
527 + if ( ! empty( $settings['field_shape_type'] ) && 'underline' === $settings['field_shape_type'] ) {
528 + return safecss_filter_attr( '0px 0px ' . $value . ' 0px' );
529 + }
530 + break;
531 +
532 + case 'box_shadow':
533 + if ( ! empty( $settings['field_shape_type'] ) && 'underline' === $settings['field_shape_type'] ) {
534 + return safecss_filter_attr( 'none' );
535 + }
536 + break;
537 +
538 + case 'border_radius':
539 + if ( ! empty( $settings['field_shape_type'] ) ) {
540 + switch ( $settings['field_shape_type'] ) {
541 + case 'underline':
542 + case 'regular':
543 + return safecss_filter_attr( '0px' );
544 + case 'circle':
545 + return safecss_filter_attr( '30px' );
546 + }
547 + }
548 + break;
549 + }//end switch
550 +
551 + return esc_html( $settings[ $key ] );
552 + }
553 +
554 + /**
323 555 * @since 2.3
324 556 *
325 557 * @param WP_Post $style
326 558 * @return array
@@ -345,8 +577,10 @@
345 577 $settings = $frm_style->sanitize_post_content( wp_unslash( $_GET ) );
346 578 $style_name = FrmAppHelper::get_param( 'style_name', '', 'get', 'sanitize_title' );
347 579 }
348 580
581 + $settings = self::update_base_font_size( $settings, $frm_style->get_defaults() );
582 +
349 583 FrmAppHelper::sanitize_value( 'sanitize_text_field', $settings );
350 584
351 585 $settings['style_class'] = '';
352 586 if ( ! empty( $style_name ) ) {
@@ -354,9 +588,9 @@
354 588 }
355 589 } else {
356 590 $settings = $style->post_content;
357 591 $settings['style_class'] = 'frm_style_' . $style->post_name . '.';
358 - }
592 + }//end if
359 593
360 594 $settings['style_class'] .= 'with_frm_style';
361 595 $settings['font'] = stripslashes( $settings['font'] );
362 596 $settings['change_margin'] = self::description_margin_for_screensize( $settings['width'] );
@@ -372,9 +606,9 @@
372 606
373 607 $settings['field_height'] = $settings['field_height'] === '' ? 'auto' : $settings['field_height'];
374 608 $settings['field_width'] = $settings['field_width'] === '' ? 'auto' : $settings['field_width'];
375 609 $settings['auto_width'] = $settings['auto_width'] ? 'auto' : $settings['field_width'];
376 - $settings['box_shadow'] = ! empty( $settings['remove_box_shadow'] ) ? 'none' : '0 1px 1px rgba(0, 0, 0, 0.075) inset';
610 + $settings['box_shadow'] = ! empty( $settings['remove_box_shadow'] ) ? 'none' : '0 1px 2px 0 rgba(18, 18, 23, 0.05)';
377 611
378 612 if ( ! isset( $settings['repeat_icon'] ) ) {
379 613 $settings['repeat_icon'] = 1;
380 614 }
@@ -382,8 +616,64 @@
382 616 return $settings;
383 617 }
384 618
385 619 /**
620 + * Update the "Base Font Size" value from "Quick Settings across multiple settings values".
621 + *
622 + * @since 6.14
623 + *
624 + * @param array $settings An array of css style.
625 + *
626 + * @return array
627 + */
628 + public static function update_base_font_size( $settings, $defaults ) {
629 + if ( empty( $settings['base_font_size'] ) || empty( $settings['use_base_font_size'] ) || 'false' === $settings['use_base_font_size'] ) {
630 + return $settings;
631 + }
632 + $base_font_size = (int) $settings['base_font_size'];
633 + $font_size = $settings['font_size'];
634 + $font_sizes_to_update = array(
635 + 'font_size',
636 + 'field_font_size',
637 + 'check_font_size',
638 + 'title_size',
639 + 'form_desc_size',
640 + 'description_font_size',
641 + 'section_font_size',
642 + 'submit_font_size',
643 + 'success_font_size',
644 + 'error_font_size',
645 + 'progress_size',
646 + );
647 +
648 + array_map(
649 + function ( $key ) use ( $defaults, $font_size, $base_font_size, &$settings ) {
650 + if ( isset( $settings[ $key ] ) ) {
651 + $settings[ $key ] = round( self::get_base_font_size_scale( $key, $font_size, $defaults ) * $base_font_size ) . 'px';
652 + }
653 + },
654 + $font_sizes_to_update
655 + );
656 +
657 + return $settings;
658 + }
659 +
660 + /**
661 + * Get style font size scale value.
662 + *
663 + * @since 6.14
664 + *
665 + * @return float
666 + */
667 + private static function get_base_font_size_scale( $key, $value, $defaults ) {
668 + if ( empty( $defaults[ $key ] ) || ! is_numeric( (int) $defaults[ $key ] ) || ! is_numeric( (int) $value ) || 0 === (int) $value ) {
669 + return 1;
670 + }
671 +
672 + return round( (int) $defaults[ $key ] / (int) $value, 2 );
673 + }
674 +
675 + /**
386 676 * @since 2.3
387 677 */
388 678 public static function prepare_color_output( &$settings, $allow_transparent = true ) {
389 679 $colors = self::allow_color_override();
@@ -439,14 +729,40 @@
439 729 $color = $default;
440 730 } elseif ( false !== strpos( $color, 'rgb(' ) ) {
441 731 $color = str_replace( 'rgb(', 'rgba(', $color );
442 732 $color = str_replace( ')', ',1)', $color );
443 - } elseif ( strpos( $color, '#' ) === false && false === strpos( $color, 'rgba(' ) ) {
733 + } elseif ( strpos( $color, '#' ) === false && self::is_hex( $color ) ) {
444 734 $color = '#' . $color;
445 735 }
446 736 }
447 737
448 738 /**
739 + * If a color looks like a hex code without the #, prepend the #.
740 + * A color looks like a hex code if it does not contain the substrings "rgb", "rgba", "hsl", "hsla", or "hwb".
741 + *
742 + * @since 6.8
743 + *
744 + * @param string $color
745 + * @return bool
746 + */
747 + private static function is_hex( $color ) {
748 + $non_hex_substrings = array(
749 + 'rgba(',
750 + 'hsl(',
751 + 'hsla(',
752 + 'hwb(',
753 + );
754 +
755 + foreach ( $non_hex_substrings as $substring ) {
756 + if ( false !== strpos( $color, $substring ) ) {
757 + return false;
758 + }
759 + }
760 +
761 + return true;
762 + }
763 +
764 + /**
449 765 * If left/right label is over a certain size,
450 766 * adjust the field description margin at a different screen size
451 767 *
452 768 * @since 2.3
@@ -476,45 +792,13 @@
476 792 return $ajax_change || isset( $_GET['flat'] );
477 793 }
478 794
479 795 /**
480 - * @since 5.5.1
481 - * @return void
482 - */
483 - public static function maybe_include_font_icon_css() {
484 - $signature_add_on_is_active = class_exists( 'FrmSigAppHelper', false );
485 -
486 - if ( ! FrmAppHelper::pro_is_installed() && ! $signature_add_on_is_active ) {
487 - // If Pro and Signatures are both not active, there is no need to include the font icon CSS in lite.
488 - return;
489 - }
490 -
491 - $pro_version_will_handle_loading = false;
492 -
493 - if ( class_exists( 'FrmProDb', false ) ) {
494 - $pro_version_that_includes_font_icons_css = '5.5.1';
495 -
496 - // Include font icons in Lite for backward compatibility with older version of Pro.
497 - $pro_version_will_handle_loading = version_compare( FrmProDb::$plug_version, $pro_version_that_includes_font_icons_css, '>=' );
498 - }
499 -
500 - $load_it_here = false;
501 - if ( ! $pro_version_will_handle_loading ) {
502 - // If Pro is not handling it, we still need to include it for the Signature add on.
503 - $load_it_here = $signature_add_on_is_active;
504 - }
505 -
506 - if ( $load_it_here ) {
507 - readfile( FrmAppHelper::plugin_path() . '/css/font_icons.css' );
508 - }
509 - }
510 -
511 - /**
512 796 * Get the URL for the Styler page list view (where you can assign styles to a form and view style templates) for a target form.
513 797 *
514 798 * @since 6.0
515 799 *
516 - * @param string|int $form_id
800 + * @param int|string $form_id
517 801 * @return string
518 802 */
519 803 public static function get_list_url( $form_id ) {
520 804 return admin_url( 'admin.php?page=formidable-styles&form=' . absint( $form_id ) );
@@ -520,19 +804,44 @@
520 804 return admin_url( 'admin.php?page=formidable-styles&form=' . absint( $form_id ) );
521 805 }
522 806
523 807 /**
808 + * Get the back button args from Style settings.
809 + *
810 + * @since 6.14
811 + *
812 + * @param stdClass|WP_Post $style
813 + * @param int $form_id
814 + * @return array
815 + */
816 + public static function get_style_options_back_button_args( $style, $form_id ) {
817 + if ( self::is_advanced_settings() ) {
818 + return array(
819 + 'title' => __( 'Quick Settings', 'formidable' ),
820 + 'id' => 'frm_style_back_to_quick_settings',
821 + );
822 + }
823 + return array(
824 + 'href' => self::get_list_url( $form_id ),
825 + 'title' => $style->post_title,
826 + );
827 + }
828 +
829 + /**
524 830 * Get a link to edit a target style post object in the visual styler.
525 831 *
526 - * @param WP_Post|stdClass $style
527 - * @param string|int $form_id Used for the back button and preview form target.
832 + * @param stdClass|WP_Post $style
833 + * @param int|string $form_id Used for the back button and preview form target.
834 + * @param string $section The url param section.
835 + *
528 836 * @return string
529 837 */
530 - public static function get_edit_url( $style, $form_id = 0 ) {
838 + public static function get_edit_url( $style, $form_id = 0, $section = '' ) {
531 839 $query_args = array(
532 840 'page' => 'formidable-styles',
533 841 'frm_action' => 'edit',
534 842 'id' => $style->ID,
843 + 'section' => $section,
535 844 );
536 845
537 846 if ( $form_id ) {
538 847 // We include &form_id for the back button to know where to point to.
@@ -547,15 +856,16 @@
547 856 * All unassigned forms are included in the count for the default style.
548 857 *
549 858 * @since 6.0
550 859 *
551 - * @param string|int $style_id
860 + * @param int|string $style_id
552 861 * @param bool $is_default
553 862 * @return int
554 863 */
555 864 public static function get_form_count_for_style( $style_id, $is_default ) {
556 - $serialized = serialize( array( 'custom_style' => (string) $style_id ) );
557 - $substring = substr( $serialized, 5, -1 ); // Chop off the "a:1:{" from the front and the "}" from the back.
865 + $serialized = serialize( array( 'custom_style' => (string) $style_id ) );
866 + // Chop off the "a:1:{" from the front and the "}" from the back.
867 + $substring = substr( $serialized, 5, -1 );
558 868 $number_of_forms = FrmDb::get_count(
559 869 'frm_forms',
560 870 array(
561 871 'status' => 'published',
@@ -578,21 +888,21 @@
578 888 * Get the number of forms that use the default style.
579 889 *
580 890 * @since 6.0
581 891 *
582 - * @param string|int $style_id
892 + * @param int|string $style_id
583 893 * @param mixed $conversational_style_id
584 894 * @return int
585 895 */
586 896 private static function get_default_style_count( $style_id, $conversational_style_id ) {
587 897 $substrings = array_map(
588 - function( $value ) {
898 + function ( $value ) {
589 899 $substring = serialize( array( 'custom_style' => $value ) );
590 900 return substr( $substring, 5, -1 );
591 901 },
592 902 array( '1', 1 )
593 903 );
594 - $where = array(
904 + $where = array(
595 905 'status' => 'published',
596 906 0 => array(
597 907 'options NOT LIKE' => 'custom_style',
598 908 'or' => 1,
@@ -602,9 +912,9 @@
602 912
603 913 if ( $conversational_style_id ) {
604 914 // When a conversational style is set, check for it in the query by wrapping the where and adding a conversational option check.
605 915 $is_conversational_style = (int) $style_id === (int) $conversational_style_id;
606 - $where[0] = array(
916 + $where[0] = array(
607 917 // The chat option doesn't exist if it isn't on.
608 918 ( $is_conversational_style ? 'options LIKE' : 'options NOT LIKE' ) => ';s:4:"chat";',
609 919 $where[0],
610 920 );
@@ -613,89 +923,90 @@
613 923 return FrmDb::get_count( 'frm_forms', $where );
614 924 }
615 925
616 926 /**
617 - * @deprecated 3.01
618 - * @codeCoverageIgnore
927 + * Check if the current page is the advanced settings page.
928 + *
929 + * @since 6.14
930 + *
931 + * @return bool True if is advanced settings, false otherwise.
619 932 */
620 - public static function get_sigle_label_postitions() {
621 - return FrmDeprecated::get_sigle_label_postitions();
933 + public static function is_advanced_settings() {
934 + return FrmAppHelper::get_param( 'section' ) === 'advanced-settings' && FrmAppHelper::get_param( 'page' ) === 'formidable-styles';
622 935 }
623 936
624 937 /**
625 - * @deprecated 3.02.03
626 - * @codeCoverageIgnore
938 + * Get wrapper classname for style editor sections.
939 + *
940 + * @since 6.16
941 + *
942 + * @param string $section_type
943 + *
944 + * @return string The style editor wrapper classname.
627 945 */
628 - public static function jquery_themes() {
629 - return FrmDeprecated::jquery_themes();
630 - }
946 + public static function style_editor_get_wrapper_classname( $section_type ) {
947 + $is_quick_settings = ( 'quick-settings' === $section_type );
948 + $classname = 'frm-style-editor-form';
949 + $classname .= ( ! self::is_advanced_settings() xor $is_quick_settings ) ? ' frm_hidden' : '';
950 + $classname .= FrmAppHelper::pro_is_installed() ? ' frm-pro' : '';
631 951
632 - /**
633 - * @deprecated 3.02.03
634 - * @codeCoverageIgnore
635 - */
636 - public static function jquery_css_url( $theme_css ) {
637 - return FrmDeprecated::jquery_css_url( $theme_css );
952 + return $classname;
638 953 }
639 954
640 955 /**
641 - * @deprecated 3.02.03
642 - * @codeCoverageIgnore
956 + * Retrieve the background image URL of the submit button.
957 + * It may be either a full URL string (used in versions prior to 6.14) or a numeric attachment ID (introduced in version 6.14).
958 + *
959 + * @since 6.14
960 + *
961 + * @param array $settings
962 + * @return false|string Return image url or false.
643 963 */
644 - public static function enqueue_jquery_css() {
645 - FrmDeprecated::enqueue_jquery_css();
646 - }
964 + public static function get_submit_image_bg_url( $settings ) {
965 + $background_image = $settings['submit_bg_img'];
966 + if ( empty( $background_image ) ) {
967 + return false;
968 + }
969 + // Handle the case where the submit_bg_img is a full URL string. If the settings were saved with the older styler version prior to 6.14, the submit_bg_img will be a full URL string.
970 + if ( ! is_numeric( $background_image ) ) {
971 + return $background_image;
972 + }
647 973
648 - /**
649 - * @deprecated 3.02.03
650 - * @codeCoverageIgnore
651 - */
652 - public static function get_form_for_page() {
653 - return FrmDeprecated::get_form_for_page();
974 + return wp_get_attachment_url( (int) $background_image );
654 975 }
655 976
656 977 /**
657 - * @since 4.0
658 - * @deprecated 6.0 The style menu is no longer used in the styler.
978 + * Determines if the chosen JavaScript library should be used.
659 979 *
660 - * @param string $active
661 - * @return string
980 + * @since 6.13
981 + *
982 + * @return bool
662 983 */
663 - public static function get_style_menu( $active = '' ) {
664 - _deprecated_function( __METHOD__, '6.0' );
665 - return '';
666 - }
984 + public static function use_chosen_js() {
985 + if ( ! FrmAppHelper::pro_is_installed() ) {
986 + return false;
987 + }
667 988
668 - /**
669 - * @deprecated 6.0 The style menu is no longer used in the styler.
670 - *
671 - * @param string $active
672 - * @return void
673 - */
674 - public static function style_menu( $active = '' ) {
675 - _deprecated_function( __METHOD__, '6.0' );
989 + return is_callable( 'FrmProAppHelper::use_chosen_js' )
990 + ? FrmProAppHelper::use_chosen_js()
991 + : true;
676 992 }
677 993
678 994 /**
679 - * Either get the heading or the style switcher.
995 + * Returns the bottom part from a margin/padding value.
680 996 *
681 - * @since 4.0
682 - * @deprecated 6.0 The style switcher was replaced with a form switcher and is no longer used.
997 + * @since 6.17
683 998 *
684 - * @param array $atts
685 - * @return void
999 + * @param string $value The margin/padding value.
1000 + * @return string
686 1001 */
687 - public static function styler_switcher( $atts ) {
688 - _deprecated_function( __METHOD__, '6.0' );
689 - }
690 -
691 - /**
692 - * @since 4.0
693 - * @deprecated 6.0 The styler now uses the Embed/Preview/Update header. It uses the same save button as other pages with Form tabs.
694 - *
695 - * @param array $atts
696 - * @return void
697 - */
698 - public static function styler_save_button( $atts ) {
699 - _deprecated_function( __METHOD__, '6.0' );
1002 + public static function get_bottom_value( $value ) {
1003 + if ( ! $value ) {
1004 + return $value;
1005 + }
1006 + $parts = explode( ' ', $value );
1007 + if ( count( $parts ) < 3 ) {
1008 + return $parts[0];
1009 + }
1010 + return $parts[2];
700 1011 }
701 1012 }