PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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/FrmAppHelper.php +47 -15 6.32 → trunk View file →
@@ -9,9 +9,9 @@
9 9 * Version of the database we are moving to.
10 10 *
11 11 * @var int
12 12 */
13 - public static $db_version = 105;
13 + public static $db_version = 106;
14 14
15 15 /**
16 16 * Used by the API add-on.
17 17 *
@@ -28,9 +28,9 @@
28 28 * @since 2.0
29 29 *
30 30 * @var string
31 31 */
32 - public static $plug_version = '6.32';
32 + public static $plug_version = '6.35';
33 33
34 34 /**
35 35 * @var bool
36 36 */
@@ -937,8 +937,9 @@
937 937 } else {
938 938 self::sanitize_value( self::class . '::strip_most_html', $value );
939 939 }
940 940 self::decode_specialchars( $value );
941 + self::sanitize_value( 'FrmHtmlSanitizer::sanitize_url_attributes', $value );
941 942 }
942 943
943 944 /**
944 945 * Allow only a small set of very basic HTML for unprivileged users.
@@ -1368,10 +1369,9 @@
1368 1369 if ( isset( $atts['echo'] ) ) {
1369 1370 unset( $atts['echo'] );
1370 1371 }
1371 1372
1372 - $html_atts = self::array_to_html_params( $atts );
1373 - $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1373 + $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1374 1374
1375 1375 // Replace icons that have been removed or renamed.
1376 1376 $deprecated = array(
1377 1377 'frm_clone_solid_icon' => 'frm_clone_icon',
@@ -1383,11 +1383,11 @@
1383 1383 $icon = $deprecated[ $icon ];
1384 1384 $class = str_replace( $icon, $deprecated[ $icon ], $class );
1385 1385 }
1386 1386
1387 - if ( $icon === $class ) {
1388 - $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
1389 - } else {
1387 + $is_font_icon = $icon === $class;
1388 +
1389 + if ( ! $is_font_icon ) {
1390 1390 $class = str_contains( $icon, ' ' ) ? ' ' . $icon : '';
1391 1391
1392 1392 if ( str_contains( $icon, ' ' ) ) {
1393 1393 $icon = explode( ' ', $icon );
@@ -1392,18 +1392,46 @@
1392 1392 if ( str_contains( $icon, ' ' ) ) {
1393 1393 $icon = explode( ' ', $icon );
1394 1394 $icon = reset( $icon );
1395 1395 }
1396 + }
1396 1397
1397 - $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use href="#' . esc_attr( $icon ) . '" /></svg>';
1398 - }
1398 + if ( $atts ) {
1399 + // A caller passed attributes, so kses still has to decide which of them survive. Its
1400 + // allowlist comes from safe_html() through the frm_striphtml_allowed_tags filter, and
1401 + // add-ons widen it around their own icons, so there is no fixed list to check against.
1402 + $html_atts = self::array_to_html_params( $atts );
1403 + $markup = $is_font_icon
1404 + ? '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>'
1405 + : '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use href="#' . esc_attr( $icon ) . '" /></svg>';
1399 1406
1400 - if ( $echo ) {
1401 - echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1407 + if ( ! $echo ) {
1408 + return $markup;
1409 + }
1410 +
1411 + echo self::kses_icon( $markup ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1402 1412 return null;
1403 1413 }
1404 1414
1405 - return $icon;
1415 + /**
1416 + * With no attributes from the caller, the tag is nothing but this method's own markup
1417 + * around an escaped class and icon id, so there is nothing left for kses to decide and it
1418 + * can be skipped. Echoing the pieces rather than a finished string keeps that safe to the
1419 + * escaping sniff without an annotation.
1420 + *
1421 + * This is the path the form builder takes for most of the tens of thousands of icons it
1422 + * renders on a large form, and the kses pass was most of what each one cost.
1423 + */
1424 + $callback = function () use ( $is_font_icon, $class, $icon ) {
1425 + if ( $is_font_icon ) {
1426 + echo '<i class="' . esc_attr( $class ) . '"></i>';
1427 + return;
1428 + }
1429 +
1430 + echo '<svg class="frmsvg' . esc_attr( $class ) . '"><use href="#' . esc_attr( $icon ) . '" /></svg>';
1431 + };
1432 +
1433 + return self::clip( $callback, $echo );
1406 1434 }
1407 1435
1408 1436 /**
1409 1437 * Run kses for icons. It needs to add a few filters first in order to preserve some custom style values.
@@ -1630,9 +1658,9 @@
1630 1658
1631 1659 printf(
1632 1660 /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */
1633 1661 esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ),
1634 - '<a href="' . esc_url( $upgrade_link ) . '">',
1662 + '<a href="' . esc_url( $upgrade_link ) . '" target="_blank" rel="noopener">',
1635 1663 esc_html( $cta_text ),
1636 1664 '</a>'
1637 1665 );
1638 1666 ?>
@@ -4053,10 +4081,14 @@
4053 4081 if ( $square_connected ) {
4054 4082 $gateway_texts['square'] = esc_html__( 'Square', 'formidable' );
4055 4083 }
4056 4084
4085 + if ( $paypal_connected ) {
4086 + $gateway_texts['paypal'] = esc_html__( 'PayPal', 'formidable' );
4087 + }
4088 +
4057 4089 $admin_script_strings['pricingFieldsModal']['msg'] = sprintf(
4058 - // translators: %s: Stripe or Square.
4090 + // translators: %s: Stripe, Square, or PayPal.
4059 4091 esc_html__( 'You already have %s connected, so these have already been unlocked.', 'formidable' ),
4060 4092 esc_html( implode( ' ' . esc_html__( 'and', 'formidable' ) . ' ', $gateway_texts ) )
4061 4093 );
4062 4094 } else {
@@ -4063,9 +4095,9 @@
4063 4095 $admin_script_strings['pricingFieldsModal']['closeText'] = __( 'I\'ll do it later!', 'formidable' );
4064 4096 $admin_script_strings['pricingFieldsModal']['actionText'] = __( 'Setup Payments Now', 'formidable' );
4065 4097 $admin_script_strings['pricingFieldsModal']['actionUrl'] = $payments_settings_url;
4066 4098 // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4067 - $admin_script_strings['pricingFieldsModal']['msg'] = __( 'We\'ve unlocked Product, Quantity, and Total fields for Lite users! You can now transform your forms into checkout pages. To start collecting revenue, simply connect your preferred payment gateway (Stripe, or Square) in your settings.', 'formidable' );
4099 + $admin_script_strings['pricingFieldsModal']['msg'] = __( 'We\'ve unlocked Product, Quantity, and Total fields for Lite users! You can now transform your forms into checkout pages. To start collecting revenue, simply connect your preferred payment gateway (Stripe, Square, or PayPal) in your settings.', 'formidable' );
4068 4100 }//end if
4069 4101
4070 4102 delete_option( 'frm_show_pricing_fields_modal' );
4071 4103 }