| @@ -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 = 104; | |
| 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.27'; | |
| 32 | + public static $plug_version = '6.35'; | |
| 33 | 33 | |
| 34 | 34 | /** |
| 35 | 35 | * @var bool |
| 36 | 36 | */ |
| @@ -202,9 +202,9 @@ | ||
| 202 | 202 | } |
| 203 | 203 | |
| 204 | 204 | $query_args = wp_parse_args( $parsed['query'] ); |
| 205 | 205 | |
| 206 | - return empty( $query_args['utm_medium'] ) ? '' : $query_args['utm_medium']; | |
| 206 | + return ! empty( $query_args['utm_medium'] ) ? $query_args['utm_medium'] : ''; | |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | /** |
| 210 | 210 | * @since 6.25.1 |
| @@ -270,14 +270,14 @@ | ||
| 270 | 270 | * @since 2.0 |
| 271 | 271 | * |
| 272 | 272 | * @param array $args - May include the form id when values need translation. |
| 273 | 273 | * |
| 274 | - * @return FrmSettings $frm_settings | |
| 274 | + * @return FrmSettings | |
| 275 | 275 | */ |
| 276 | 276 | public static function get_settings( $args = array() ) { |
| 277 | 277 | global $frm_settings; |
| 278 | 278 | |
| 279 | - if ( empty( $frm_settings ) ) { | |
| 279 | + if ( ! $frm_settings ) { | |
| 280 | 280 | $frm_settings = new FrmSettings( $args ); |
| 281 | 281 | } elseif ( isset( $args['current_form'] ) ) { |
| 282 | 282 | // If the global has already been set, allow strings to be filtered. |
| 283 | 283 | $frm_settings->maybe_filter_for_form( $args ); |
| @@ -289,10 +289,13 @@ | ||
| 289 | 289 | /** |
| 290 | 290 | * @return string |
| 291 | 291 | */ |
| 292 | 292 | public static function get_menu_name() { |
| 293 | - $frm_settings = self::get_settings(); | |
| 294 | - return FrmAddonsController::is_license_expired() || ! self::pro_is_installed() ? 'Formidable' : $frm_settings->menu; | |
| 293 | + if ( ! self::pro_is_installed() || FrmAddonsController::is_license_expired() ) { | |
| 294 | + return 'Formidable'; | |
| 295 | + } | |
| 296 | + | |
| 297 | + return self::get_settings()->menu; | |
| 295 | 298 | } |
| 296 | 299 | |
| 297 | 300 | /** |
| 298 | 301 | * Determine if the current branding is set to 'formidable'. |
| @@ -306,10 +309,9 @@ | ||
| 306 | 309 | if ( ! self::pro_is_installed() ) { |
| 307 | 310 | return true; |
| 308 | 311 | } |
| 309 | 312 | |
| 310 | - $menu_icon = self::get_menu_icon_class(); | |
| 311 | - return str_contains( $menu_icon, 'frm_logo_icon' ); | |
| 313 | + return str_contains( self::get_menu_icon_class(), 'frm_logo_icon' ); | |
| 312 | 314 | } |
| 313 | 315 | |
| 314 | 316 | /** |
| 315 | 317 | * @since 3.05 |
| @@ -494,9 +496,9 @@ | ||
| 494 | 496 | global $pagenow; |
| 495 | 497 | $get_page = self::simple_get( 'page', 'sanitize_title' ); |
| 496 | 498 | |
| 497 | 499 | if ( $pagenow ) { |
| 498 | - // allow this to be true during ajax load i.e. ajax form builder loading | |
| 500 | + // Allow this to be true during ajax load i.e. ajax form builder loading | |
| 499 | 501 | $is_page = ( $pagenow === 'admin.php' || $pagenow === 'admin-ajax.php' ) && $get_page === $page; |
| 500 | 502 | |
| 501 | 503 | if ( $is_page ) { |
| 502 | 504 | return true; |
| @@ -756,17 +758,19 @@ | ||
| 756 | 758 | ) |
| 757 | 759 | ); |
| 758 | 760 | } |
| 759 | 761 | |
| 760 | - if ( isset( $params ) && is_array( $value ) && $value ) { | |
| 761 | - foreach ( $params as $k => $p ) { | |
| 762 | - if ( ! $k || ! is_array( $value ) ) { | |
| 763 | - continue; | |
| 764 | - } | |
| 762 | + if ( ! isset( $params ) || ! is_array( $value ) || ! $value ) { | |
| 763 | + return $value; | |
| 764 | + } | |
| 765 | 765 | |
| 766 | - $p = trim( $p, ']' ); | |
| 767 | - $value = $value[ $p ] ?? $default; | |
| 766 | + foreach ( $params as $k => $p ) { | |
| 767 | + if ( ! $k || ! is_array( $value ) ) { | |
| 768 | + continue; | |
| 768 | 769 | } |
| 770 | + | |
| 771 | + $p = trim( $p, ']' ); | |
| 772 | + $value = $value[ $p ] ?? $default; | |
| 769 | 773 | } |
| 770 | 774 | |
| 771 | 775 | return $value; |
| 772 | 776 | } |
| @@ -799,9 +803,9 @@ | ||
| 799 | 803 | * @param string $param |
| 800 | 804 | * @param string $sanitize |
| 801 | 805 | * @param string $default |
| 802 | 806 | * |
| 803 | - * @return array|string | |
| 807 | + * @return array|int|string | |
| 804 | 808 | */ |
| 805 | 809 | public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) { |
| 806 | 810 | return self::get_simple_request( |
| 807 | 811 | array( |
| @@ -847,11 +851,10 @@ | ||
| 847 | 851 | self::unserialize_or_decode( $value ); |
| 848 | 852 | } |
| 849 | 853 | } |
| 850 | 854 | } elseif ( isset( $_REQUEST[ $args['param'] ] ) ) { |
| 851 | - // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 852 | - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 853 | - $value = wp_unslash( $_REQUEST[ $args['param'] ] ); | |
| 855 | + // phpcs:ignore phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 856 | + $value = wp_unslash( $_REQUEST[ $args['param'] ] ); | |
| 854 | 857 | } |
| 855 | 858 | |
| 856 | 859 | self::sanitize_value( $args['sanitize'], $value ); |
| 857 | 860 | |
| @@ -864,17 +867,13 @@ | ||
| 864 | 867 | * @since 2.0.8 |
| 865 | 868 | * |
| 866 | 869 | * @param string $value |
| 867 | 870 | * |
| 868 | - * @return string $value | |
| 871 | + * @return string Value. | |
| 869 | 872 | */ |
| 870 | 873 | public static function preserve_backslashes( $value ) { |
| 871 | 874 | // If backslashes have already been added, don't add them again |
| 872 | - if ( ! str_contains( $value, '\\\\' ) ) { | |
| 873 | - $value = addslashes( $value ); | |
| 874 | - } | |
| 875 | - | |
| 876 | - return $value; | |
| 875 | + return str_contains( $value, '\\\\' ) ? $value : addslashes( $value ); | |
| 877 | 876 | } |
| 878 | 877 | |
| 879 | 878 | /** |
| 880 | 879 | * Sanitize a value in-place. |
| @@ -938,8 +937,9 @@ | ||
| 938 | 937 | } else { |
| 939 | 938 | self::sanitize_value( self::class . '::strip_most_html', $value ); |
| 940 | 939 | } |
| 941 | 940 | self::decode_specialchars( $value ); |
| 941 | + self::sanitize_value( 'FrmHtmlSanitizer::sanitize_url_attributes', $value ); | |
| 942 | 942 | } |
| 943 | 943 | |
| 944 | 944 | /** |
| 945 | 945 | * Allow only a small set of very basic HTML for unprivileged users. |
| @@ -948,8 +948,12 @@ | ||
| 948 | 948 | * |
| 949 | 949 | * @param string $value |
| 950 | 950 | */ |
| 951 | 951 | public static function strip_most_html( $value ) { |
| 952 | + if ( '' === $value ) { | |
| 953 | + return $value; | |
| 954 | + } | |
| 955 | + | |
| 952 | 956 | $allowed_html = array( |
| 953 | 957 | 'b' => array(), |
| 954 | 958 | 'br' => array(), |
| 955 | 959 | 'strong' => array(), |
| @@ -1046,10 +1050,9 @@ | ||
| 1046 | 1050 | * |
| 1047 | 1051 | * @return string |
| 1048 | 1052 | */ |
| 1049 | 1053 | public static function kses( $value, $allowed = array() ) { |
| 1050 | - $allowed_html = self::allowed_html( $allowed ); | |
| 1051 | - return wp_kses( $value, $allowed_html ); | |
| 1054 | + return wp_kses( $value, self::allowed_html( $allowed ) ); | |
| 1052 | 1055 | } |
| 1053 | 1056 | |
| 1054 | 1057 | /** |
| 1055 | 1058 | * Sanitizes and echoes a given value. |
| @@ -1098,9 +1101,9 @@ | ||
| 1098 | 1101 | $html = str_replace( 'class="frm_prev_page"', 'class="frm_prev_page" [back_hook]', $html ); |
| 1099 | 1102 | } |
| 1100 | 1103 | |
| 1101 | 1104 | if ( $included_draft_hook ) { |
| 1102 | - $html = str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html ); | |
| 1105 | + return str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html ); | |
| 1103 | 1106 | } |
| 1104 | 1107 | |
| 1105 | 1108 | return $html; |
| 1106 | 1109 | } |
| @@ -1161,8 +1164,10 @@ | ||
| 1161 | 1164 | } |
| 1162 | 1165 | |
| 1163 | 1166 | /** |
| 1164 | 1167 | * @since 2.05.03 |
| 1168 | + * | |
| 1169 | + * @return array | |
| 1165 | 1170 | */ |
| 1166 | 1171 | private static function safe_html() { |
| 1167 | 1172 | $allow_class = array( |
| 1168 | 1173 | 'class' => true, |
| @@ -1344,13 +1349,9 @@ | ||
| 1344 | 1349 | } |
| 1345 | 1350 | |
| 1346 | 1351 | global $wp_query; |
| 1347 | 1352 | |
| 1348 | - if ( isset( $wp_query->query_vars[ $param ] ) ) { | |
| 1349 | - $value = $wp_query->query_vars[ $param ]; | |
| 1350 | - } | |
| 1351 | - | |
| 1352 | - return $value; | |
| 1353 | + return $wp_query->query_vars[ $param ] ?? $value; | |
| 1353 | 1354 | } |
| 1354 | 1355 | |
| 1355 | 1356 | /** |
| 1356 | 1357 | * Try to show the SVG if possible. Otherwise, use the font icon. |
| @@ -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,27 +1383,55 @@ | ||
| 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 { | |
| 1390 | - $class = ! str_contains( $icon, ' ' ) ? '' : ' ' . $icon; | |
| 1387 | + $is_font_icon = $icon === $class; | |
| 1391 | 1388 | |
| 1389 | + if ( ! $is_font_icon ) { | |
| 1390 | + $class = str_contains( $icon, ' ' ) ? ' ' . $icon : ''; | |
| 1391 | + | |
| 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. |
| @@ -1515,13 +1543,15 @@ | ||
| 1515 | 1543 | * @return string|void |
| 1516 | 1544 | */ |
| 1517 | 1545 | public static function array_to_html_params( $atts, $echo = false ) { |
| 1518 | 1546 | $callback = function () use ( $atts ) { |
| 1519 | - if ( $atts ) { | |
| 1520 | - foreach ( $atts as $key => $value ) { | |
| 1521 | - echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"'; | |
| 1522 | - } | |
| 1547 | + if ( ! $atts ) { | |
| 1548 | + return; | |
| 1523 | 1549 | } |
| 1550 | + | |
| 1551 | + foreach ( $atts as $key => $value ) { | |
| 1552 | + echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"'; | |
| 1553 | + } | |
| 1524 | 1554 | }; |
| 1525 | 1555 | return self::clip( $callback, $echo ); |
| 1526 | 1556 | } |
| 1527 | 1557 | |
| @@ -1533,8 +1563,10 @@ | ||
| 1533 | 1563 | * @param Closure $echo_function |
| 1534 | 1564 | * @param bool $echo |
| 1535 | 1565 | * |
| 1536 | 1566 | * @return string|null |
| 1567 | + * | |
| 1568 | + * @psalm-return ($echo is true ? null : string) | |
| 1537 | 1569 | */ |
| 1538 | 1570 | public static function clip( $echo_function, $echo = false ) { |
| 1539 | 1571 | if ( ! $echo ) { |
| 1540 | 1572 | ob_start(); |
| @@ -1575,13 +1607,15 @@ | ||
| 1575 | 1607 | * |
| 1576 | 1608 | * @return void |
| 1577 | 1609 | */ |
| 1578 | 1610 | public static function import_link( $type = 'secondary' ) { |
| 1611 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 1579 | 1612 | ?> |
| 1580 | 1613 | <a href="<?php echo esc_url( admin_url( 'admin.php?page=formidable-import' ) ); ?>" class="button frm-button-<?php echo esc_attr( $type ); ?> frm_animate_bg"> |
| 1581 | 1614 | <?php esc_html_e( 'Import', 'formidable' ); ?> |
| 1582 | 1615 | </a> |
| 1583 | 1616 | <?php |
| 1617 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 1584 | 1618 | } |
| 1585 | 1619 | |
| 1586 | 1620 | /** |
| 1587 | 1621 | * Print applicable admin banner. |
| @@ -1602,8 +1636,9 @@ | ||
| 1602 | 1636 | // Print license warning or inbox banner and exit if either prints. |
| 1603 | 1637 | // And exit before printing the upgrade bar if it shouldn't be shown. |
| 1604 | 1638 | return; |
| 1605 | 1639 | } |
| 1640 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 1606 | 1641 | ?> |
| 1607 | 1642 | <div class="frm-upgrade-bar"> |
| 1608 | 1643 | <div class="frm-upgrade-bar-inner"> |
| 1609 | 1644 | <?php |
| @@ -1623,9 +1658,9 @@ | ||
| 1623 | 1658 | |
| 1624 | 1659 | printf( |
| 1625 | 1660 | /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */ |
| 1626 | 1661 | esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ), |
| 1627 | - '<a href="' . esc_url( $upgrade_link ) . '">', | |
| 1662 | + '<a href="' . esc_url( $upgrade_link ) . '" target="_blank" rel="noopener">', | |
| 1628 | 1663 | esc_html( $cta_text ), |
| 1629 | 1664 | '</a>' |
| 1630 | 1665 | ); |
| 1631 | 1666 | ?> |
| @@ -1631,8 +1666,9 @@ | ||
| 1631 | 1666 | ?> |
| 1632 | 1667 | </div> |
| 1633 | 1668 | </div> |
| 1634 | 1669 | <?php |
| 1670 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 1635 | 1671 | } |
| 1636 | 1672 | |
| 1637 | 1673 | /** |
| 1638 | 1674 | * @since 5.4.2 |
| @@ -1730,8 +1766,9 @@ | ||
| 1730 | 1766 | |
| 1731 | 1767 | if ( ! empty( $atts['tosearch'] ) ) { |
| 1732 | 1768 | $input_atts['autocomplete'] = 'off'; |
| 1733 | 1769 | } |
| 1770 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 1734 | 1771 | ?> |
| 1735 | 1772 | <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>"> |
| 1736 | 1773 | <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"> |
| 1737 | 1774 | <?php echo esc_html( $atts['text'] ); ?>: |
| @@ -1744,8 +1781,9 @@ | ||
| 1744 | 1781 | } |
| 1745 | 1782 | ?> |
| 1746 | 1783 | </p> |
| 1747 | 1784 | <?php |
| 1785 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 1748 | 1786 | } |
| 1749 | 1787 | |
| 1750 | 1788 | /** |
| 1751 | 1789 | * @param string $type Hook type slug. |
| @@ -1816,9 +1854,9 @@ | ||
| 1816 | 1854 | * True when value is 1, true, 'true', 'yes' |
| 1817 | 1855 | * |
| 1818 | 1856 | * @since 1.07.10 |
| 1819 | 1857 | * |
| 1820 | - * @param int|string $value The value to compare. | |
| 1858 | + * @param bool|int|string $value The value to compare. | |
| 1821 | 1859 | * |
| 1822 | 1860 | * @return bool |
| 1823 | 1861 | */ |
| 1824 | 1862 | public static function is_true( $value ) { |
| @@ -1939,8 +1977,9 @@ | ||
| 1939 | 1977 | if ( ! empty( $args['id'] ) ) { |
| 1940 | 1978 | $html_attrs['id'] = $args['id']; |
| 1941 | 1979 | } |
| 1942 | 1980 | |
| 1981 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 1943 | 1982 | if ( count( $args['source'] ) <= $args['dropdown_limit'] ) { |
| 1944 | 1983 | ?> |
| 1945 | 1984 | <select <?php self::array_to_html_params( $html_attrs, true ); ?>> |
| 1946 | 1985 | <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option> |
| @@ -1955,33 +1994,35 @@ | ||
| 1955 | 1994 | <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?> |
| 1956 | 1995 | <?php endforeach; ?> |
| 1957 | 1996 | </select> |
| 1958 | 1997 | <?php |
| 1959 | - } else { | |
| 1960 | - $options = array(); | |
| 1961 | - $autocomplete_value = ''; | |
| 1998 | + return; | |
| 1999 | + } | |
| 2000 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 1962 | 2001 | |
| 1963 | - foreach ( $args['source'] as $key => $source ) { | |
| 1964 | - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args ); | |
| 2002 | + $options = array(); | |
| 2003 | + $autocomplete_value = ''; | |
| 1965 | 2004 | |
| 1966 | - if ( $value_label['value'] === $args['selected'] ) { | |
| 1967 | - $autocomplete_value = $value_label['label']; | |
| 1968 | - } | |
| 2005 | + foreach ( $args['source'] as $key => $source ) { | |
| 2006 | + $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args ); | |
| 1969 | 2007 | |
| 1970 | - $options[] = $value_label; | |
| 2008 | + if ( $value_label['value'] === $args['selected'] ) { | |
| 2009 | + $autocomplete_value = $value_label['label']; | |
| 1971 | 2010 | } |
| 1972 | 2011 | |
| 1973 | - $html_attrs['type'] = 'hidden'; | |
| 1974 | - $html_attrs['class'] = 'frm_autocomplete_value_input'; | |
| 1975 | - $html_attrs['value'] = $args['selected']; | |
| 1976 | - ?> | |
| 1977 | - <input type="text" class="frm-custom-search" | |
| 1978 | - data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>" | |
| 1979 | - placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>" | |
| 1980 | - value="<?php echo esc_attr( $autocomplete_value ); ?>" /> | |
| 1981 | - <input <?php self::array_to_html_params( $html_attrs, true ); ?> /> | |
| 1982 | - <?php | |
| 1983 | - }//end if | |
| 2012 | + $options[] = $value_label; | |
| 2013 | + } | |
| 2014 | + | |
| 2015 | + $html_attrs['type'] = 'hidden'; | |
| 2016 | + $html_attrs['class'] = 'frm_autocomplete_value_input'; | |
| 2017 | + $html_attrs['value'] = $args['selected']; | |
| 2018 | + ?> | |
| 2019 | + <input type="text" class="frm-custom-search" | |
| 2020 | + data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>" | |
| 2021 | + placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>" | |
| 2022 | + value="<?php echo esc_attr( $autocomplete_value ); ?>" /> | |
| 2023 | + <input <?php self::array_to_html_params( $html_attrs, true ); ?> /> | |
| 2024 | + <?php | |
| 1984 | 2025 | } |
| 1985 | 2026 | |
| 1986 | 2027 | /** |
| 1987 | 2028 | * Gets dropdown value and label from autodropdown option. |
| @@ -2015,8 +2056,9 @@ | ||
| 2015 | 2056 | self::prep_page_dropdown_params( $page_id, $truncate, $args ); |
| 2016 | 2057 | |
| 2017 | 2058 | $pages = self::get_post_ids_and_titles( $args['post_type'] ); |
| 2018 | 2059 | $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' ); |
| 2060 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 2019 | 2061 | ?> |
| 2020 | 2062 | <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown"> |
| 2021 | 2063 | <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option> |
| 2022 | 2064 | <?php foreach ( $pages as $page ) { ?> |
| @@ -2025,8 +2067,9 @@ | ||
| 2025 | 2067 | </option> |
| 2026 | 2068 | <?php } ?> |
| 2027 | 2069 | </select> |
| 2028 | 2070 | <?php |
| 2071 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 2029 | 2072 | } |
| 2030 | 2073 | |
| 2031 | 2074 | /** |
| 2032 | 2075 | * Fill in missing parameters passed to wp_pages_dropdown(). |
| @@ -2098,11 +2141,9 @@ | ||
| 2098 | 2141 | * |
| 2099 | 2142 | * @return bool |
| 2100 | 2143 | */ |
| 2101 | 2144 | public static function is_full_screen() { |
| 2102 | - return self::is_form_builder_page() || | |
| 2103 | - self::is_style_editor_page() || | |
| 2104 | - self::is_full_screen_view_builder_page(); | |
| 2145 | + return self::is_form_builder_page() || self::is_style_editor_page() || self::is_full_screen_view_builder_page(); | |
| 2105 | 2146 | } |
| 2106 | 2147 | |
| 2107 | 2148 | /** |
| 2108 | 2149 | * Check if user is on the style editor or its alternative URL. |
| @@ -2151,8 +2192,9 @@ | ||
| 2151 | 2192 | * @param array|string $capability |
| 2152 | 2193 | * @param string $multiple 'single' and 'multiple'. |
| 2153 | 2194 | */ |
| 2154 | 2195 | public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) { |
| 2196 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 2155 | 2197 | ?> |
| 2156 | 2198 | <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>" |
| 2157 | 2199 | <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?> |
| 2158 | 2200 | class="frm_multiselect"> |
| @@ -2158,8 +2200,9 @@ | ||
| 2158 | 2200 | class="frm_multiselect"> |
| 2159 | 2201 | <?php self::roles_options( $capability ); ?> |
| 2160 | 2202 | </select> |
| 2161 | 2203 | <?php |
| 2204 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 2162 | 2205 | } |
| 2163 | 2206 | |
| 2164 | 2207 | /** |
| 2165 | 2208 | * @since 4.07 |
| @@ -2325,10 +2368,9 @@ | ||
| 2325 | 2368 | if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) { |
| 2326 | 2369 | return; |
| 2327 | 2370 | } |
| 2328 | 2371 | |
| 2329 | - $user_id = get_current_user_id(); | |
| 2330 | - $user = new WP_User( $user_id ); | |
| 2372 | + $user = new WP_User( get_current_user_id() ); | |
| 2331 | 2373 | $frm_roles = self::frm_capabilities(); |
| 2332 | 2374 | |
| 2333 | 2375 | foreach ( $frm_roles as $frm_role => $frm_role_description ) { |
| 2334 | 2376 | $user->add_cap( $frm_role ); |
| @@ -2345,15 +2387,17 @@ | ||
| 2345 | 2387 | * |
| 2346 | 2388 | * @return void |
| 2347 | 2389 | */ |
| 2348 | 2390 | public static function force_capability( $cap = 'frm_change_settings' ) { |
| 2349 | - if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) { | |
| 2350 | - $role = get_role( 'administrator' ); | |
| 2351 | - $frm_roles = self::frm_capabilities(); | |
| 2391 | + if ( ! current_user_can( 'administrator' ) || current_user_can( $cap ) ) { | |
| 2392 | + return; | |
| 2393 | + } | |
| 2352 | 2394 | |
| 2353 | - foreach ( $frm_roles as $frm_role => $frm_role_description ) { | |
| 2354 | - $role->add_cap( $frm_role ); | |
| 2355 | - } | |
| 2395 | + $role = get_role( 'administrator' ); | |
| 2396 | + $frm_roles = self::frm_capabilities(); | |
| 2397 | + | |
| 2398 | + foreach ( $frm_roles as $frm_role => $frm_role_description ) { | |
| 2399 | + $role->add_cap( $frm_role ); | |
| 2356 | 2400 | } |
| 2357 | 2401 | } |
| 2358 | 2402 | |
| 2359 | 2403 | /** |
| @@ -2367,15 +2411,17 @@ | ||
| 2367 | 2411 | */ |
| 2368 | 2412 | public static function permission_check( $permission, $show_message = 'show' ) { |
| 2369 | 2413 | $permission_error = self::permission_nonce_error( $permission ); |
| 2370 | 2414 | |
| 2371 | - if ( $permission_error !== false ) { | |
| 2372 | - if ( 'hide' === $show_message ) { | |
| 2373 | - $permission_error = ''; | |
| 2374 | - } | |
| 2415 | + if ( $permission_error === false ) { | |
| 2416 | + return; | |
| 2417 | + } | |
| 2375 | 2418 | |
| 2376 | - wp_die( esc_html( $permission_error ) ); | |
| 2419 | + if ( 'hide' === $show_message ) { | |
| 2420 | + $permission_error = ''; | |
| 2377 | 2421 | } |
| 2422 | + | |
| 2423 | + wp_die( esc_html( $permission_error ) ); | |
| 2378 | 2424 | } |
| 2379 | 2425 | |
| 2380 | 2426 | /** |
| 2381 | 2427 | * Check user permission and nonce |
| @@ -2423,9 +2469,9 @@ | ||
| 2423 | 2469 | } |
| 2424 | 2470 | |
| 2425 | 2471 | /** |
| 2426 | 2472 | * @param array|string $values |
| 2427 | - * @param string $current | |
| 2473 | + * @param string|null $current | |
| 2428 | 2474 | * |
| 2429 | 2475 | * @return bool |
| 2430 | 2476 | */ |
| 2431 | 2477 | public static function check_selected( $values, $current ) { |
| @@ -2433,9 +2479,9 @@ | ||
| 2433 | 2479 | $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' ); |
| 2434 | 2480 | $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) ); |
| 2435 | 2481 | |
| 2436 | 2482 | // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons |
| 2437 | - return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current ); | |
| 2483 | + return is_array( $values ) ? in_array( $current, $values ) : $values == $current; | |
| 2438 | 2484 | } |
| 2439 | 2485 | |
| 2440 | 2486 | /** |
| 2441 | 2487 | * @param array|string $value |
| @@ -2447,16 +2493,16 @@ | ||
| 2447 | 2493 | if ( is_array( $value ) ) { |
| 2448 | 2494 | $original_function = $function; |
| 2449 | 2495 | $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function ); |
| 2450 | 2496 | |
| 2451 | - if ( ! self::is_assoc( $value ) ) { | |
| 2452 | - $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function ); | |
| 2453 | - } else { | |
| 2497 | + if ( self::is_assoc( $value ) ) { | |
| 2454 | 2498 | foreach ( $value as $k => $v ) { |
| 2455 | 2499 | if ( ! is_array( $v ) ) { |
| 2456 | 2500 | $value[ $k ] = call_user_func( $original_function, $v ); |
| 2457 | 2501 | } |
| 2458 | 2502 | } |
| 2503 | + } else { | |
| 2504 | + $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function ); | |
| 2459 | 2505 | } |
| 2460 | 2506 | } else { |
| 2461 | 2507 | $value = self::maybe_update_value_if_null( $value, $function ); |
| 2462 | 2508 | $value = call_user_func( $function, $value ); |
| @@ -2476,9 +2522,9 @@ | ||
| 2476 | 2522 | * @return mixed |
| 2477 | 2523 | */ |
| 2478 | 2524 | private static function maybe_update_value_if_null( $value, $function ) { |
| 2479 | 2525 | if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) { |
| 2480 | - $value = ''; | |
| 2526 | + return ''; | |
| 2481 | 2527 | } |
| 2482 | 2528 | |
| 2483 | 2529 | return $value; |
| 2484 | 2530 | } |
| @@ -2506,9 +2552,9 @@ | ||
| 2506 | 2552 | foreach ( $array as $key => $value ) { |
| 2507 | 2553 | if ( is_array( $value ) ) { |
| 2508 | 2554 | $return = array_merge( $return, self::array_flatten( $value, $keys ) ); |
| 2509 | 2555 | } elseif ( $keys === 'keep' ) { |
| 2510 | - $return[ $key ] = $value; | |
| 2556 | + $return[ $key ] = $value; | |
| 2511 | 2557 | } else { |
| 2512 | 2558 | $return[] = $value; |
| 2513 | 2559 | } |
| 2514 | 2560 | } |
| @@ -2563,9 +2609,9 @@ | ||
| 2563 | 2609 | * @return mixed |
| 2564 | 2610 | */ |
| 2565 | 2611 | public static function use_wpautop( $content ) { |
| 2566 | 2612 | if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) { |
| 2567 | - $content = wpautop( str_replace( '<br>', '<br />', $content ) ); | |
| 2613 | + return wpautop( str_replace( '<br>', '<br />', $content ) ); | |
| 2568 | 2614 | } |
| 2569 | 2615 | |
| 2570 | 2616 | return $content; |
| 2571 | 2617 | } |
| @@ -2606,9 +2652,9 @@ | ||
| 2606 | 2652 | |
| 2607 | 2653 | $query = $wp_scripts->registered[ $handle ]; |
| 2608 | 2654 | |
| 2609 | 2655 | if ( is_object( $query ) && ! empty( $query->ver ) ) { |
| 2610 | - $ver = $query->ver; | |
| 2656 | + return $query->ver; | |
| 2611 | 2657 | } |
| 2612 | 2658 | |
| 2613 | 2659 | return $ver; |
| 2614 | 2660 | } |
| @@ -2701,31 +2747,31 @@ | ||
| 2701 | 2747 | $column |
| 2702 | 2748 | ); |
| 2703 | 2749 | |
| 2704 | 2750 | // Create a unique field id if it has already been used. |
| 2705 | - if ( in_array( $key, $similar_keys, true ) ) { | |
| 2706 | - $key = self::maybe_truncate_key_before_appending( $column, $key ); | |
| 2751 | + if ( ! in_array( $key, $similar_keys, true ) ) { | |
| 2752 | + return $key; | |
| 2753 | + } | |
| 2707 | 2754 | |
| 2708 | - /** | |
| 2709 | - * Allow for a custom separator between the attempted key and the generated suffix. | |
| 2710 | - * | |
| 2711 | - * @since 5.2.03 | |
| 2712 | - * | |
| 2713 | - * @param string $separator. Default empty. | |
| 2714 | - * @param string $key the key without the added suffix. | |
| 2715 | - */ | |
| 2716 | - $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key ); | |
| 2755 | + $key = self::maybe_truncate_key_before_appending( $column, $key ); | |
| 2717 | 2756 | |
| 2718 | - $suffix = 2; | |
| 2719 | - do { | |
| 2720 | - $key_check = $key . $separator . $suffix; | |
| 2721 | - ++$suffix; | |
| 2722 | - } while ( in_array( $key_check, $similar_keys, true ) ); | |
| 2757 | + /** | |
| 2758 | + * Allow for a custom separator between the attempted key and the generated suffix. | |
| 2759 | + * | |
| 2760 | + * @since 5.2.03 | |
| 2761 | + * | |
| 2762 | + * @param string $separator. Default empty. | |
| 2763 | + * @param string $key the key without the added suffix. | |
| 2764 | + */ | |
| 2765 | + $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key ); | |
| 2723 | 2766 | |
| 2724 | - $key = $key_check; | |
| 2725 | - }//end if | |
| 2767 | + $suffix = 2; | |
| 2768 | + do { | |
| 2769 | + $key_check = $key . $separator . $suffix; | |
| 2770 | + ++$suffix; | |
| 2771 | + } while ( in_array( $key_check, $similar_keys, true ) ); | |
| 2726 | 2772 | |
| 2727 | - return $key; | |
| 2773 | + return $key_check; | |
| 2728 | 2774 | } |
| 2729 | 2775 | |
| 2730 | 2776 | /** |
| 2731 | 2777 | * Avoid trying to append to a really long key, |
| @@ -2736,17 +2782,19 @@ | ||
| 2736 | 2782 | * |
| 2737 | 2783 | * @return string |
| 2738 | 2784 | */ |
| 2739 | 2785 | private static function maybe_truncate_key_before_appending( $column, $key ) { |
| 2740 | - if ( in_array( $column, array( 'form_key', 'field_key' ), true ) ) { | |
| 2741 | - $max_key_length_before_truncating = 60; | |
| 2786 | + if ( ! in_array( $column, array( 'form_key', 'field_key' ), true ) ) { | |
| 2787 | + return $key; | |
| 2788 | + } | |
| 2742 | 2789 | |
| 2743 | - if ( strlen( $key ) > $max_key_length_before_truncating ) { | |
| 2744 | - $key = substr( $key, 0, $max_key_length_before_truncating ); | |
| 2790 | + $max_key_length_before_truncating = 60; | |
| 2745 | 2791 | |
| 2746 | - if ( is_numeric( $key ) ) { | |
| 2747 | - $key .= 'a'; | |
| 2748 | - } | |
| 2792 | + if ( strlen( $key ) > $max_key_length_before_truncating ) { | |
| 2793 | + $key = substr( $key, 0, $max_key_length_before_truncating ); | |
| 2794 | + | |
| 2795 | + if ( is_numeric( $key ) ) { | |
| 2796 | + $key .= 'a'; | |
| 2749 | 2797 | } |
| 2750 | 2798 | } |
| 2751 | 2799 | |
| 2752 | 2800 | return $key; |
| @@ -2761,9 +2809,9 @@ | ||
| 2761 | 2809 | * @return string either the original key value, or an empty string if the key was too long. |
| 2762 | 2810 | */ |
| 2763 | 2811 | private static function maybe_clear_long_key( $key, $column ) { |
| 2764 | 2812 | if ( 'field_key' === $column && strlen( $key ) >= 70 ) { |
| 2765 | - $key = ''; | |
| 2813 | + return ''; | |
| 2766 | 2814 | } |
| 2767 | 2815 | return $key; |
| 2768 | 2816 | } |
| 2769 | 2817 | |
| @@ -2864,17 +2912,20 @@ | ||
| 2864 | 2912 | * |
| 2865 | 2913 | * @return void |
| 2866 | 2914 | */ |
| 2867 | 2915 | private static function prepare_field_arrays( $fields, $record, array &$values, $args ) { |
| 2868 | - if ( $fields ) { | |
| 2869 | - foreach ( (array) $fields as $field ) { | |
| 2870 | - if ( ! self::is_admin_page() ) { | |
| 2871 | - // Don't prep default values on the form settings page. | |
| 2872 | - $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true ); | |
| 2873 | - } | |
| 2874 | - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id; | |
| 2875 | - self::fill_field_defaults( $field, $record, $values, $args ); | |
| 2916 | + if ( ! $fields ) { | |
| 2917 | + return; | |
| 2918 | + } | |
| 2919 | + | |
| 2920 | + foreach ( (array) $fields as $field ) { | |
| 2921 | + if ( ! self::is_admin_page() ) { | |
| 2922 | + // Don't prep default values on the form settings page. | |
| 2923 | + $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true ); | |
| 2876 | 2924 | } |
| 2925 | + | |
| 2926 | + $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id; | |
| 2927 | + self::fill_field_defaults( $field, $record, $values, $args ); | |
| 2877 | 2928 | } |
| 2878 | 2929 | } |
| 2879 | 2930 | |
| 2880 | 2931 | /** |
| @@ -2894,19 +2945,19 @@ | ||
| 2894 | 2945 | if ( ! isset( $field->field_options['custom_field'] ) ) { |
| 2895 | 2946 | $field->field_options['custom_field'] = ''; |
| 2896 | 2947 | } |
| 2897 | 2948 | |
| 2898 | - $meta_value = FrmProEntryMetaHelper::get_post_value( | |
| 2899 | - $record->post_id, | |
| 2900 | - $field->field_options['post_field'], | |
| 2901 | - $field->field_options['custom_field'], | |
| 2902 | - array( | |
| 2903 | - 'truncate' => false, | |
| 2904 | - 'type' => $field->type, | |
| 2905 | - 'form_id' => $field->form_id, | |
| 2906 | - 'field' => $field, | |
| 2907 | - ) | |
| 2908 | - ); | |
| 2949 | + $meta_value = FrmProEntryMetaHelper::get_post_value( | |
| 2950 | + $record->post_id, | |
| 2951 | + $field->field_options['post_field'], | |
| 2952 | + $field->field_options['custom_field'], | |
| 2953 | + array( | |
| 2954 | + 'truncate' => false, | |
| 2955 | + 'type' => $field->type, | |
| 2956 | + 'form_id' => $field->form_id, | |
| 2957 | + 'field' => $field, | |
| 2958 | + ) | |
| 2959 | + ); | |
| 2909 | 2960 | } else { |
| 2910 | 2961 | $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id ); |
| 2911 | 2962 | }//end if |
| 2912 | 2963 | |
| @@ -3043,30 +3094,43 @@ | ||
| 3043 | 3094 | return $frm_settings->load_style !== 'none'; |
| 3044 | 3095 | } |
| 3045 | 3096 | |
| 3046 | 3097 | /** |
| 3098 | + * Truncate a string. | |
| 3099 | + * | |
| 3100 | + * Note: By default, this function will allow for a few additional characters more than $length. | |
| 3101 | + * If a string has no spaces, it allows up to 50 additional characters. To force a true length limit, | |
| 3102 | + * use $force_length_limit = true. | |
| 3103 | + * | |
| 3047 | 3104 | * @param mixed $original_string |
| 3048 | 3105 | * @param int|string $length |
| 3049 | 3106 | * @param int $minword |
| 3050 | 3107 | * @param string $continue |
| 3108 | + * @param bool $force_length_limit Force the final string to never exceed the length limit. | |
| 3051 | 3109 | * |
| 3052 | 3110 | * @return string |
| 3053 | 3111 | */ |
| 3054 | - public static function truncate( $original_string, $length, $minword = 3, $continue = '...' ) { | |
| 3112 | + public static function truncate( $original_string, $length, $minword = 3, $continue = '...', $force_length_limit = false ) { | |
| 3055 | 3113 | if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) { |
| 3056 | 3114 | return ''; |
| 3057 | 3115 | } |
| 3058 | 3116 | |
| 3059 | - $length = (int) $length; | |
| 3060 | - $str = wp_strip_all_tags( (string) $original_string ); | |
| 3061 | - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) ); | |
| 3117 | + $length = (int) $length; | |
| 3062 | 3118 | |
| 3063 | 3119 | if ( $length === 0 ) { |
| 3064 | 3120 | return ''; |
| 3065 | 3121 | } |
| 3066 | 3122 | |
| 3123 | + $str = wp_strip_all_tags( (string) $original_string ); | |
| 3124 | + $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) ); | |
| 3125 | + | |
| 3067 | 3126 | if ( $length <= 10 ) { |
| 3068 | 3127 | $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) ); |
| 3128 | + | |
| 3129 | + if ( $force_length_limit ) { | |
| 3130 | + return $sub; | |
| 3131 | + } | |
| 3132 | + | |
| 3069 | 3133 | return $sub . ( $length < $original_len ? $continue : '' ); |
| 3070 | 3134 | } |
| 3071 | 3135 | |
| 3072 | 3136 | $sub = ''; |
| @@ -3094,10 +3158,21 @@ | ||
| 3094 | 3158 | |
| 3095 | 3159 | unset( $total_len, $word ); |
| 3096 | 3160 | } |
| 3097 | 3161 | |
| 3098 | - $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length ); | |
| 3162 | + $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit ); | |
| 3099 | 3163 | |
| 3164 | + if ( $force_length_limit ) { | |
| 3165 | + // Ensure the final string doesn't exceed the length limit. | |
| 3166 | + $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) ); | |
| 3167 | + | |
| 3168 | + if ( $final_len > $length ) { | |
| 3169 | + return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) ); | |
| 3170 | + } | |
| 3171 | + | |
| 3172 | + return $sub; | |
| 3173 | + } | |
| 3174 | + | |
| 3100 | 3175 | return $sub . ( $len < $original_len ? $continue : '' ); |
| 3101 | 3176 | } |
| 3102 | 3177 | |
| 3103 | 3178 | /** |
| @@ -3104,27 +3179,39 @@ | ||
| 3104 | 3179 | * If the string is still too long because there may not have been any spaces, force truncate. |
| 3105 | 3180 | * |
| 3106 | 3181 | * @since 6.5.4 |
| 3107 | 3182 | * |
| 3108 | - * @param string $sub Current substring. | |
| 3109 | - * @param int $length The length limit. | |
| 3183 | + * @param string $sub Current substring. | |
| 3184 | + * @param int $length The length limit. | |
| 3185 | + * @param bool $force_length_limit Force the string to not exceed the length limit. | |
| 3110 | 3186 | * |
| 3111 | 3187 | * @return string |
| 3112 | 3188 | */ |
| 3113 | - private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) { | |
| 3114 | - if ( strlen( $sub ) < $length + 50 ) { | |
| 3115 | - // If the string isn't way over the limit, leave it. | |
| 3116 | - return $sub; | |
| 3189 | + private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit = false ) { | |
| 3190 | + if ( ! $force_length_limit ) { | |
| 3191 | + if ( strlen( $sub ) < $length + 50 ) { | |
| 3192 | + // If the string isn't way over the limit, leave it. | |
| 3193 | + return $sub; | |
| 3194 | + } | |
| 3195 | + | |
| 3196 | + $first_space = strpos( $sub, ' ', $length ); | |
| 3197 | + | |
| 3198 | + if ( false !== $first_space ) { | |
| 3199 | + // Ignore anything with spaces. | |
| 3200 | + return $sub; | |
| 3201 | + } | |
| 3202 | + | |
| 3203 | + return substr( $sub, 0, $length + 10 ); | |
| 3117 | 3204 | } |
| 3118 | 3205 | |
| 3119 | - $first_space = strpos( $sub, ' ', $length ); | |
| 3206 | + // When force_length_limit is true, ensure the string doesn't exceed the length. | |
| 3207 | + $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) ); | |
| 3120 | 3208 | |
| 3121 | - if ( false !== $first_space ) { | |
| 3122 | - // Ignore anything with spaces. | |
| 3123 | - return $sub; | |
| 3209 | + if ( $final_len > $length ) { | |
| 3210 | + return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) ); | |
| 3124 | 3211 | } |
| 3125 | 3212 | |
| 3126 | - return substr( $sub, 0, $length + 10 ); | |
| 3213 | + return $sub; | |
| 3127 | 3214 | } |
| 3128 | 3215 | |
| 3129 | 3216 | /** |
| 3130 | 3217 | * @param array $function_names |
| @@ -3213,12 +3300,12 @@ | ||
| 3213 | 3300 | * @param int $from In seconds. |
| 3214 | 3301 | * @param int|string $to In seconds. |
| 3215 | 3302 | * @param int|string $levels Number of time units to include or a specific unit. |
| 3216 | 3303 | * |
| 3217 | - * @return string $time_ago | |
| 3304 | + * @return string Time ago. | |
| 3218 | 3305 | */ |
| 3219 | 3306 | public static function human_time_diff( $from, $to = '', $levels = 1 ) { |
| 3220 | - $now = empty( $to ) && 0 !== $to ? new DateTime() : new DateTime( '@' . $to ); | |
| 3307 | + $now = ! $to && 0 !== $to ? new DateTime() : new DateTime( '@' . $to ); | |
| 3221 | 3308 | $ago = new DateTime( '@' . $from ); |
| 3222 | 3309 | |
| 3223 | 3310 | // Get the time difference |
| 3224 | 3311 | $diff_object = $now->diff( $ago ); |
| @@ -3397,9 +3484,9 @@ | ||
| 3397 | 3484 | * |
| 3398 | 3485 | * @return int |
| 3399 | 3486 | */ |
| 3400 | 3487 | public static function get_last_record_num( $r_count, $current_p, $p_size ) { |
| 3401 | - return ( $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size ); | |
| 3488 | + return $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size; | |
| 3402 | 3489 | } |
| 3403 | 3490 | |
| 3404 | 3491 | /** |
| 3405 | 3492 | * @param int $r_count |
| @@ -3581,9 +3668,9 @@ | ||
| 3581 | 3668 | |
| 3582 | 3669 | // Add extra slashes for \r\n since WP strips them. |
| 3583 | 3670 | $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content ); |
| 3584 | 3671 | |
| 3585 | - // allow for " | |
| 3672 | + // Allow for " | |
| 3586 | 3673 | return str_replace( '"', '\\"', $post_content ); |
| 3587 | 3674 | } |
| 3588 | 3675 | |
| 3589 | 3676 | /** |
| @@ -3602,15 +3689,17 @@ | ||
| 3602 | 3689 | foreach ( $val as $k1 => $v1 ) { |
| 3603 | 3690 | self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] ); |
| 3604 | 3691 | unset( $k1, $v1 ); |
| 3605 | 3692 | } |
| 3606 | - } else { | |
| 3607 | - // Strip all slashes so everything is the same, no matter where the value is coming from | |
| 3608 | - $val = stripslashes( $val ); | |
| 3609 | 3693 | |
| 3610 | - // Add backslashes before double quotes and forward slashes only | |
| 3611 | - $post_content[ $key ] = addcslashes( $val, '"\\/' ); | |
| 3694 | + return; | |
| 3612 | 3695 | } |
| 3696 | + | |
| 3697 | + // Strip all slashes so everything is the same, no matter where the value is coming from | |
| 3698 | + $val = stripslashes( $val ); | |
| 3699 | + | |
| 3700 | + // Add backslashes before double quotes and forward slashes only | |
| 3701 | + $post_content[ $key ] = addcslashes( $val, '"\\/' ); | |
| 3613 | 3702 | } |
| 3614 | 3703 | |
| 3615 | 3704 | /** |
| 3616 | 3705 | * Check for either json or serialized data. This is temporary while transitioning |
| @@ -3651,13 +3740,9 @@ | ||
| 3651 | 3740 | } |
| 3652 | 3741 | |
| 3653 | 3742 | $parsed = FrmSerializedStringParserHelper::get()->parse( $value ); |
| 3654 | 3743 | |
| 3655 | - if ( is_array( $parsed ) ) { | |
| 3656 | - $value = $parsed; | |
| 3657 | - } | |
| 3658 | - | |
| 3659 | - return $value; | |
| 3744 | + return is_array( $parsed ) ? $parsed : $value; | |
| 3660 | 3745 | } |
| 3661 | 3746 | |
| 3662 | 3747 | /** |
| 3663 | 3748 | * Decode a JSON string. |
| @@ -3680,9 +3765,9 @@ | ||
| 3680 | 3765 | $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] ); |
| 3681 | 3766 | } |
| 3682 | 3767 | |
| 3683 | 3768 | if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) { |
| 3684 | - $string = $new_string; | |
| 3769 | + return $new_string; | |
| 3685 | 3770 | } |
| 3686 | 3771 | |
| 3687 | 3772 | return $string; |
| 3688 | 3773 | } |
| @@ -3736,16 +3821,17 @@ | ||
| 3736 | 3821 | } |
| 3737 | 3822 | |
| 3738 | 3823 | $key = $input['name']; |
| 3739 | 3824 | |
| 3740 | - if ( isset( $formatted[ $key ] ) ) { | |
| 3741 | - if ( is_array( $formatted[ $key ] ) ) { | |
| 3742 | - $formatted[ $key ][] = $input['value']; | |
| 3743 | - } else { | |
| 3744 | - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] ); | |
| 3745 | - } | |
| 3825 | + if ( ! isset( $formatted[ $key ] ) ) { | |
| 3826 | + $formatted[ $key ] = $input['value']; | |
| 3827 | + continue; | |
| 3828 | + } | |
| 3829 | + | |
| 3830 | + if ( is_array( $formatted[ $key ] ) ) { | |
| 3831 | + $formatted[ $key ][] = $input['value']; | |
| 3746 | 3832 | } else { |
| 3747 | - $formatted[ $key ] = $input['value']; | |
| 3833 | + $formatted[ $key ] = array( $formatted[ $key ], $input['value'] ); | |
| 3748 | 3834 | } |
| 3749 | 3835 | } |
| 3750 | 3836 | |
| 3751 | 3837 | parse_str( http_build_query( $formatted ), $form ); |
| @@ -3758,12 +3844,9 @@ | ||
| 3758 | 3844 | * |
| 3759 | 3845 | * @return string |
| 3760 | 3846 | */ |
| 3761 | 3847 | public static function maybe_json_encode( $value ) { |
| 3762 | - if ( is_array( $value ) ) { | |
| 3763 | - $value = wp_json_encode( $value ); | |
| 3764 | - } | |
| 3765 | - return $value; | |
| 3848 | + return is_array( $value ) ? wp_json_encode( $value ) : $value; | |
| 3766 | 3849 | } |
| 3767 | 3850 | |
| 3768 | 3851 | /** |
| 3769 | 3852 | * Echo The javascript to open and highlight the Formidable menu |
| @@ -3798,10 +3881,9 @@ | ||
| 3798 | 3881 | * |
| 3799 | 3882 | * @return void |
| 3800 | 3883 | */ |
| 3801 | 3884 | public static function load_admin_wide_js( $load = true ) { |
| 3802 | - $version = self::plugin_version(); | |
| 3803 | - wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version ); | |
| 3885 | + wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), self::plugin_version() ); | |
| 3804 | 3886 | |
| 3805 | 3887 | $global_strings = array( |
| 3806 | 3888 | 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ), |
| 3807 | 3889 | 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ), |
| @@ -3899,8 +3981,10 @@ | ||
| 3899 | 3981 | 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ), |
| 3900 | 3982 | /* translators: %d is the number of allowed actions per form */ |
| 3901 | 3983 | 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ), |
| 3902 | 3984 | 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ), |
| 3985 | + 'only_one_payment_action' => __( 'This form already has a payment action, and is currently limited to a single payment action.', 'formidable' ), | |
| 3986 | + 'only_one_stripe_action' => __( 'This form already has a payment action. Multiple Stripe actions are available when using the Stripe add-on, available for Formidable Business licenses and higher.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong | |
| 3903 | 3987 | 'unsafe_params' => FrmFormsHelper::reserved_words(), |
| 3904 | 3988 | /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/ |
| 3905 | 3989 | 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong |
| 3906 | 3990 | /* Translators: %s is the name of a parameter that is a reserved word. More than one word could be listed here, though that would not be common. */ |
| @@ -3926,11 +4010,14 @@ | ||
| 3926 | 4010 | 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ), |
| 3927 | 4011 | 'noTitleText' => FrmFormsHelper::get_no_title_text(), |
| 3928 | 4012 | |
| 3929 | 4013 | // In older versions this event listener causes the section to immediately close again |
| 3930 | - // when the h3 element is clicked. It's only required in WP 6.7+. | |
| 4014 | + // When the h3 element is clicked. It's only required in WP 6.7+. | |
| 3931 | 4015 | 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ), |
| 3932 | 4016 | ); |
| 4017 | + | |
| 4018 | + self::add_form_builder_modal_data( $admin_script_strings ); | |
| 4019 | + | |
| 3933 | 4020 | /** |
| 3934 | 4021 | * @param array $admin_script_strings |
| 3935 | 4022 | */ |
| 3936 | 4023 | $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings ); |
| @@ -3943,8 +4030,80 @@ | ||
| 3943 | 4030 | }//end if |
| 3944 | 4031 | } |
| 3945 | 4032 | |
| 3946 | 4033 | /** |
| 4034 | + * @param array $admin_script_strings | |
| 4035 | + * | |
| 4036 | + * @return void | |
| 4037 | + */ | |
| 4038 | + private static function add_form_builder_modal_data( &$admin_script_strings ) { | |
| 4039 | + if ( ! self::is_form_builder_page() || self::pro_is_installed() ) { | |
| 4040 | + return; | |
| 4041 | + } | |
| 4042 | + | |
| 4043 | + $stripe_connected = FrmStrpLiteConnectHelper::at_least_one_mode_is_setup(); | |
| 4044 | + $square_connected = FrmSquareLiteConnectHelper::at_least_one_mode_is_setup(); | |
| 4045 | + $paypal_connected = FrmPayPalLiteConnectHelper::at_least_one_mode_is_setup(); | |
| 4046 | + $gateway_connected = $stripe_connected || $square_connected || $paypal_connected; | |
| 4047 | + $payments_settings_url = FrmStrpLiteAppController::get_payments_settings_url(); | |
| 4048 | + | |
| 4049 | + if ( ! $gateway_connected ) { | |
| 4050 | + // This modal shows when user clicks on one of the pricing fields and no payment gateways configured. | |
| 4051 | + $admin_script_strings['paymentsSettingsModal'] = array( | |
| 4052 | + 'title' => __( 'Setup a Payment Gateway first', 'formidable' ), | |
| 4053 | + 'msg' => __( 'To use the payment fields, please install and configure a payment gateway in your account settings.', 'formidable' ), | |
| 4054 | + 'closeText' => __( 'Close', 'formidable' ), | |
| 4055 | + 'actionUrl' => $payments_settings_url, | |
| 4056 | + 'actionText' => __( 'Go to Payment Settings', 'formidable' ), | |
| 4057 | + 'noCenter' => true, | |
| 4058 | + ); | |
| 4059 | + } | |
| 4060 | + | |
| 4061 | + // This modal shows on load once after upgrading the plugin. | |
| 4062 | + $show_pricing_fields_modal = get_option( 'frm_show_pricing_fields_modal' ); | |
| 4063 | + | |
| 4064 | + if ( ! $show_pricing_fields_modal ) { | |
| 4065 | + return; | |
| 4066 | + } | |
| 4067 | + | |
| 4068 | + $admin_script_strings['pricingFieldsModal'] = array( | |
| 4069 | + 'title' => esc_html__( 'Start Accepting Payments Today!', 'formidable' ), | |
| 4070 | + 'img' => esc_url( self::plugin_url() . '/images/upsell/pricing-fields.png' ), | |
| 4071 | + 'noCenter' => true, | |
| 4072 | + ); | |
| 4073 | + | |
| 4074 | + if ( $gateway_connected ) { | |
| 4075 | + $gateway_texts = array(); | |
| 4076 | + | |
| 4077 | + if ( $stripe_connected ) { | |
| 4078 | + $gateway_texts['stripe'] = esc_html__( 'Stripe', 'formidable' ); | |
| 4079 | + } | |
| 4080 | + | |
| 4081 | + if ( $square_connected ) { | |
| 4082 | + $gateway_texts['square'] = esc_html__( 'Square', 'formidable' ); | |
| 4083 | + } | |
| 4084 | + | |
| 4085 | + if ( $paypal_connected ) { | |
| 4086 | + $gateway_texts['paypal'] = esc_html__( 'PayPal', 'formidable' ); | |
| 4087 | + } | |
| 4088 | + | |
| 4089 | + $admin_script_strings['pricingFieldsModal']['msg'] = sprintf( | |
| 4090 | + // translators: %s: Stripe, Square, or PayPal. | |
| 4091 | + esc_html__( 'You already have %s connected, so these have already been unlocked.', 'formidable' ), | |
| 4092 | + esc_html( implode( ' ' . esc_html__( 'and', 'formidable' ) . ' ', $gateway_texts ) ) | |
| 4093 | + ); | |
| 4094 | + } else { | |
| 4095 | + $admin_script_strings['pricingFieldsModal']['closeText'] = __( 'I\'ll do it later!', 'formidable' ); | |
| 4096 | + $admin_script_strings['pricingFieldsModal']['actionText'] = __( 'Setup Payments Now', 'formidable' ); | |
| 4097 | + $admin_script_strings['pricingFieldsModal']['actionUrl'] = $payments_settings_url; | |
| 4098 | + // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong | |
| 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' ); | |
| 4100 | + }//end if | |
| 4101 | + | |
| 4102 | + delete_option( 'frm_show_pricing_fields_modal' ); | |
| 4103 | + } | |
| 4104 | + | |
| 4105 | + /** | |
| 3947 | 4106 | * Get the no label text. |
| 3948 | 4107 | * |
| 3949 | 4108 | * @since 6.25.1 |
| 3950 | 4109 | * |
| @@ -4010,10 +4169,10 @@ | ||
| 4010 | 4169 | } |
| 4011 | 4170 | |
| 4012 | 4171 | $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' ); |
| 4013 | 4172 | echo '<tr class="plugin-update-tr active"><th colspan="' . absint( $wp_list_table->get_column_count() ) . '" class="check-column plugin-update colspanchange"><div class="update-message">' . // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong |
| 4014 | - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) . | |
| 4015 | - '</div></td></tr>'; | |
| 4173 | + esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) . | |
| 4174 | + '</div></td></tr>'; | |
| 4016 | 4175 | } |
| 4017 | 4176 | |
| 4018 | 4177 | /** |
| 4019 | 4178 | * If Pro is far outdated, show a message. |
| @@ -4067,8 +4226,9 @@ | ||
| 4067 | 4226 | if ( version_compare( phpversion(), '7.0', '<' ) ) { |
| 4068 | 4227 | $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong |
| 4069 | 4228 | } |
| 4070 | 4229 | |
| 4230 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 4071 | 4231 | foreach ( $message as $m ) { |
| 4072 | 4232 | ?> |
| 4073 | 4233 | <div class="frm-banner-alert frm_error_style frm_previous_install"> |
| 4074 | 4234 | <?php echo esc_html( $m ); ?> |
| @@ -4074,8 +4234,9 @@ | ||
| 4074 | 4234 | <?php echo esc_html( $m ); ?> |
| 4075 | 4235 | </div> |
| 4076 | 4236 | <?php |
| 4077 | 4237 | } |
| 4238 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 4078 | 4239 | } |
| 4079 | 4240 | |
| 4080 | 4241 | /** |
| 4081 | 4242 | * @param string $type |
| @@ -4174,12 +4335,12 @@ | ||
| 4174 | 4335 | 'zu' => __( 'Zulu', 'formidable' ), |
| 4175 | 4336 | ); |
| 4176 | 4337 | |
| 4177 | 4338 | if ( $type === 'captcha' ) { |
| 4178 | - // remove the languages unavailable for the captcha | |
| 4339 | + // Remove the languages unavailable for the captcha | |
| 4179 | 4340 | $unset = array( 'sq', 'bs', 'eo', 'fo', 'fr-CH', 'sr-SR', 'ar-DZ', 'be', 'cy-GB', 'kk', 'km', 'ky', 'lb', 'mk', 'nb', 'nn', 'rm', 'tj' ); |
| 4180 | 4341 | } else { |
| 4181 | - // remove the languages unavailable for the datepicker | |
| 4342 | + // Remove the languages unavailable for the datepicker | |
| 4182 | 4343 | $unset = array( 'fil', 'fr-CA', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419', 'mr', 'lo', 'kn', 'si', 'gu', 'bn', 'zu', 'ur', 'te', 'sw', 'am' ); |
| 4183 | 4344 | } |
| 4184 | 4345 | |
| 4185 | 4346 | $locales = array_diff_key( $locales, array_flip( $unset ) ); |
| @@ -4465,11 +4626,9 @@ | ||
| 4465 | 4626 | * |
| 4466 | 4627 | * @return array |
| 4467 | 4628 | */ |
| 4468 | 4629 | public static function maybe_filter_array( $values, $keys ) { |
| 4469 | - $allow_unfiltered_html = self::allow_unfiltered_html(); | |
| 4470 | - | |
| 4471 | - if ( $allow_unfiltered_html ) { | |
| 4630 | + if ( self::allow_unfiltered_html() ) { | |
| 4472 | 4631 | return $values; |
| 4473 | 4632 | } |
| 4474 | 4633 | |
| 4475 | 4634 | foreach ( $keys as $key ) { |
| @@ -4493,9 +4652,9 @@ | ||
| 4493 | 4652 | * @return string |
| 4494 | 4653 | */ |
| 4495 | 4654 | public static function maybe_kses( $value, $allowed = 'all' ) { |
| 4496 | 4655 | if ( self::should_never_allow_unfiltered_html() ) { |
| 4497 | - $value = self::kses( $value, $allowed ); | |
| 4656 | + return self::kses( $value, $allowed ); | |
| 4498 | 4657 | } |
| 4499 | 4658 | return $value; |
| 4500 | 4659 | } |
| 4501 | 4660 | |
| @@ -4582,14 +4741,9 @@ | ||
| 4582 | 4741 | * @return bool |
| 4583 | 4742 | */ |
| 4584 | 4743 | public static function show_new_feature( $feature ) { |
| 4585 | 4744 | $link = FrmAddonsController::install_link( $feature ); |
| 4586 | - | |
| 4587 | - if ( array_key_exists( 'status', $link ) || array_key_exists( 'class', $link ) ) { | |
| 4588 | - return true; | |
| 4589 | - } | |
| 4590 | - | |
| 4591 | - return 'coupons' === $feature && class_exists( 'FrmCouponsAppController' ); | |
| 4745 | + return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link ); | |
| 4592 | 4746 | } |
| 4593 | 4747 | |
| 4594 | 4748 | /** |
| 4595 | 4749 | * Enhances upgrade data parameters with installation link and plan requirement information. |
| @@ -4664,9 +4818,9 @@ | ||
| 4664 | 4818 | * Shows pill text. |
| 4665 | 4819 | * |
| 4666 | 4820 | * @since 5.2.02 |
| 4667 | 4821 | * |
| 4668 | - * @param string $text Text in the pill. Default is NEW. | |
| 4822 | + * @param string|null $text Text in the pill. Default is NEW. | |
| 4669 | 4823 | */ |
| 4670 | 4824 | public static function show_pill_text( $text = null ) { |
| 4671 | 4825 | if ( null === $text ) { |
| 4672 | 4826 | $text = __( 'NEW', 'formidable' ); |
| @@ -4856,9 +5010,9 @@ | ||
| 4856 | 5010 | self::permission_check( 'frm_change_settings' ); |
| 4857 | 5011 | check_ajax_referer( 'frm_ajax', 'nonce' ); |
| 4858 | 5012 | |
| 4859 | 5013 | if ( $option ) { |
| 4860 | - update_option( $option, true, 'no' ); | |
| 5014 | + update_option( $option, true, false ); | |
| 4861 | 5015 | } |
| 4862 | 5016 | |
| 4863 | 5017 | wp_send_json_success(); |
| 4864 | 5018 | } |
| @@ -4905,13 +5059,15 @@ | ||
| 4905 | 5059 | $atts['class'] .= ' frm_help'; |
| 4906 | 5060 | } else { |
| 4907 | 5061 | $atts['class'] = 'frm_help'; |
| 4908 | 5062 | } |
| 5063 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 4909 | 5064 | ?> |
| 4910 | 5065 | <span <?php self::array_to_html_params( $atts, true ); ?>> |
| 4911 | 5066 | <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?> |
| 4912 | 5067 | </span> |
| 4913 | 5068 | <?php |
| 5069 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 4914 | 5070 | } |
| 4915 | 5071 | |
| 4916 | 5072 | /** |
| 4917 | 5073 | * Prints errors for settings in onboarding wizard or template settings. |
| @@ -4932,8 +5088,10 @@ | ||
| 4932 | 5088 | ) |
| 4933 | 5089 | ); |
| 4934 | 5090 | |
| 4935 | 5091 | $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden'; |
| 5092 | + | |
| 5093 | + // phpcs:disable Generic.WhiteSpace.ScopeIndent | |
| 4936 | 5094 | ?> |
| 4937 | 5095 | <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>"> |
| 4938 | 5096 | <?php |
| 4939 | 5097 | if ( is_array( $args['errors'] ) ) { |
| @@ -4947,8 +5105,9 @@ | ||
| 4947 | 5105 | } |
| 4948 | 5106 | ?> |
| 4949 | 5107 | </span> |
| 4950 | 5108 | <?php |
| 5109 | + // phpcs:enable Generic.WhiteSpace.ScopeIndent | |
| 4951 | 5110 | } |
| 4952 | 5111 | |
| 4953 | 5112 | /** |
| 4954 | 5113 | * Check if GDPR is enabled. |
| @@ -4978,13 +5137,18 @@ | ||
| 4978 | 5137 | * Check if a string is valid UTF-8. |
| 4979 | 5138 | * |
| 4980 | 5139 | * @since 6.24 |
| 4981 | 5140 | * |
| 4982 | - * @param string $string The string to check. | |
| 5141 | + * @param string|null $string The string to check. | |
| 4983 | 5142 | * |
| 4984 | 5143 | * @return bool |
| 4985 | 5144 | */ |
| 4986 | 5145 | public static function is_valid_utf8( $string ) { |
| 5146 | + if ( is_null( $string ) ) { | |
| 5147 | + // Return true so we do not attempt to change encoding on a null value. | |
| 5148 | + return true; | |
| 5149 | + } | |
| 5150 | + | |
| 4987 | 5151 | // wp_is_valid_utf8 is added in WP 6.9. |
| 4988 | 5152 | if ( function_exists( 'wp_is_valid_utf8' ) ) { |
| 4989 | 5153 | return wp_is_valid_utf8( $string ); |
| 4990 | 5154 | } |