PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.7
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.7
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 +191 -68 6.36.7 View file →
@@ -3,9 +3,9 @@
3 3 die( 'You are not allowed to call this page directly.' );
4 4 }
5 5
6 6 class FrmAppHelper {
7 - public static $db_version = 98; // Version of the database we are moving to.
7 + public static $db_version = 100; // Version of the database we are moving to.
8 8 public static $pro_db_version = 37; //deprecated
9 9 public static $font_version = 7;
10 10
11 11 /**
@@ -14,12 +14,19 @@
14 14 private static $added_gmt_offset_filter = false;
15 15
16 16 /**
17 17 * @since 2.0
18 + *
19 + * @var string
18 20 */
19 - public static $plug_version = '6.3';
21 + public static $plug_version = '6.7';
20 22
21 23 /**
24 + * @var bool
25 + */
26 + private static $included_svg = false;
27 +
28 + /**
22 29 * @since 1.07.02
23 30 *
24 31 * @param none
25 32 *
@@ -148,12 +155,28 @@
148 155
149 156 public static function get_menu_name() {
150 157 $frm_settings = self::get_settings();
151 158
152 - return $frm_settings->menu;
159 + return FrmAddonsController::is_license_expired() ? 'Formidable' : $frm_settings->menu;
153 160 }
154 161
155 162 /**
163 + * Determine if the current branding is set to 'formidable'.
164 + *
165 + * Checks the menu title, retrieved through get_menu_name,
166 + * and verifies if it matches the 'formidable' branding.
167 + *
168 + * @since 6.4.2
169 + *
170 + * @return bool True if the menu title is 'formidable', false otherwise.
171 + */
172 + public static function is_formidable_branding() {
173 + $menu_title = self::get_menu_name();
174 +
175 + return 'formidable' === strtolower( trim( $menu_title ) );
176 + }
177 +
178 + /**
156 179 * @since 3.05
157 180 */
158 181 public static function svg_logo( $atts = array() ) {
159 182 $defaults = array(
@@ -376,8 +399,28 @@
376 399 return isset( $_SERVER[ $value ] ) ? wp_strip_all_tags( wp_unslash( $_SERVER[ $value ] ) ) : '';
377 400 }
378 401
379 402 /**
403 + * Get the server OS
404 + *
405 + * @since 6.4.2
406 + *
407 + * @return string
408 + */
409 + public static function get_server_os() {
410 + if ( function_exists( 'php_uname' ) ) {
411 + return php_uname( 's' );
412 + }
413 +
414 + if ( ! defined( 'PHP_OS' ) ) {
415 + return '';
416 + }
417 +
418 + // match the same response for Windows server as php_uname('s')
419 + return in_array( PHP_OS, array( 'WIN32', 'WINNT', 'Windows_NT' ), true ) ? 'Windows NT' : PHP_OS;
420 + }
421 +
422 + /**
380 423 * Check for the IP address in several places (when custom headers are enabled).
381 424 * Used by [ip] shortcode.
382 425 *
383 426 * @return string The IP address of the current user
@@ -537,14 +580,14 @@
537 580 );
538 581 $args = wp_parse_args( $args, $defaults );
539 582
540 583 $value = $args['default'];
541 - if ( $args['type'] == 'get' ) {
584 + if ( $args['type'] === 'get' ) {
542 585 if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
543 586 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
544 587 $value = wp_unslash( $_GET[ $args['param'] ] );
545 588 }
546 - } elseif ( $args['type'] == 'post' ) {
589 + } elseif ( $args['type'] === 'post' ) {
547 590 if ( isset( $_POST[ $args['param'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
548 591 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
549 592 $value = wp_unslash( $_POST[ $args['param'] ] );
550 593 if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) {
@@ -1073,11 +1116,18 @@
1073 1116 /**
1074 1117 * Include svg images.
1075 1118 *
1076 1119 * @since 4.0.02
1120 + * @return void
1077 1121 */
1078 1122 public static function include_svg() {
1079 - include_once self::plugin_path() . '/images/icons.svg';
1123 + if ( self::$included_svg ) {
1124 + return;
1125 + }
1126 +
1127 + // Use readfile instead of include_once because of a default security rule in Snuffleupagus.
1128 + readfile( self::plugin_path() . '/images/icons.svg' );
1129 + self::$included_svg = true;
1080 1130 }
1081 1131
1082 1132 /**
1083 1133 * Convert an associative array to HTML values.
@@ -1207,9 +1257,9 @@
1207 1257 do_action( $atts['link_hook']['hook'], $atts['link_hook']['param'] );
1208 1258 return;
1209 1259 }
1210 1260
1211 - if ( empty( $atts['new_link'] ) && empty( $atts['trigger_new_form_modal'] ) && empty( $atts['class'] ) ) {
1261 + if ( empty( $atts['new_link'] ) && empty( $atts['create_form'] ) && empty( $atts['class'] ) ) {
1212 1262 // Do not render a button if none of these attributes are set.
1213 1263 return;
1214 1264 }
1215 1265
@@ -1215,12 +1265,8 @@
1215 1265
1216 1266 $href = ! empty( $atts['new_link'] ) ? esc_url( $atts['new_link'] ) : '#';
1217 1267 $class = 'button button-primary frm-button-primary';
1218 1268
1219 - if ( ! empty( $atts['trigger_new_form_modal'] ) ) {
1220 - $class .= ' frm-trigger-new-form-modal';
1221 - }
1222 -
1223 1269 if ( ! empty( $atts['class'] ) ) {
1224 1270 $class .= ' ' . $atts['class'];
1225 1271 }
1226 1272
@@ -1285,11 +1331,14 @@
1285 1331 }
1286 1332 }
1287 1333
1288 1334 /**
1289 - * Save all front-end js scripts into a single file
1335 + * Save all front-end js scripts into a single file.
1336 + * And save an additional single file of all front-end Stripe JS scripts.
1290 1337 *
1291 1338 * @since 3.0
1339 + *
1340 + * @return void
1292 1341 */
1293 1342 public static function save_combined_js() {
1294 1343 $file_atts = apply_filters(
1295 1344 'frm_js_location',
@@ -1302,10 +1351,34 @@
1302 1351
1303 1352 $files = array(
1304 1353 self::plugin_path() . '/js/formidable.min.js',
1305 1354 );
1355 + /**
1356 + * @param array $files
1357 + */
1306 1358 $files = apply_filters( 'frm_combined_js_files', $files );
1307 1359 $new_file->combine_files( $files );
1360 +
1361 + // Create the minified Stripe Script.
1362 + $file_atts = apply_filters(
1363 + 'frm_stripe_js_location',
1364 + array(
1365 + 'file_name' => 'frmstrp.min.js',
1366 + 'new_file_path' => self::plugin_path() . '/js',
1367 + )
1368 + );
1369 + $new_file = new FrmCreateFile( $file_atts );
1370 + $files = array(
1371 + FrmStrpLiteAppHelper::plugin_path() . 'js/frmstrp.min.js',
1372 + );
1373 +
1374 + /**
1375 + * @since 6.5
1376 + *
1377 + * @param array $files
1378 + */
1379 + $files = apply_filters( 'frm_stripe_combined_js_files', $files );
1380 + $new_file->combine_files( $files );
1308 1381 }
1309 1382
1310 1383 /**
1311 1384 * Check a value from a shortcode to see if true or false.
@@ -1602,9 +1675,8 @@
1602 1675 $pro_cap = array(
1603 1676 'frm_create_entries' => __( 'Add Entries from Admin Area', 'formidable' ),
1604 1677 'frm_edit_entries' => __( 'Edit Entries from Admin Area', 'formidable' ),
1605 1678 'frm_view_reports' => __( 'View Reports', 'formidable' ),
1606 - 'frm_edit_displays' => __( 'Add/Edit Views', 'formidable' ),
1607 1679 );
1608 1680 /**
1609 1681 * @since 5.3.1
1610 1682 *
@@ -1611,8 +1683,14 @@
1611 1683 * @param array<string,string> $pro_cap
1612 1684 */
1613 1685 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
1614 1686
1687 + if ( ! array_key_exists( 'frm_edit_displays', $pro_cap ) && is_callable( 'FrmProAppHelper::views_is_installed' ) && FrmProAppHelper::views_is_installed() ) {
1688 + // For backward compatibility, add the Add/Edit Views permission if Pro is not up to date.
1689 + // This was added in 6.5.4. Remove this in the future.
1690 + $pro_cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
1691 + }
1692 +
1615 1693 if ( 'pro_only' === $type ) {
1616 1694 return $pro_cap;
1617 1695 }
1618 1696
@@ -1838,9 +1916,9 @@
1838 1916 foreach ( $array as $key => $value ) {
1839 1917 if ( is_array( $value ) ) {
1840 1918 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
1841 1919 } else {
1842 - if ( $keys == 'keep' ) {
1920 + if ( $keys === 'keep' ) {
1843 1921 $return[ $key ] = $value;
1844 1922 } else {
1845 1923 $return[] = $value;
1846 1924 }
@@ -1924,9 +2002,9 @@
1924 2002 return $user_id;
1925 2003 }
1926 2004
1927 2005 $user_id = sanitize_text_field( $user_id );
1928 - if ( $user_id == 'current' ) {
2006 + if ( $user_id === 'current' ) {
1929 2007 $user_id = get_current_user_id();
1930 2008 } else {
1931 2009 if ( is_email( $user_id ) ) {
1932 2010 $user = get_user_by( 'email', $user_id );
@@ -2325,11 +2403,37 @@
2325 2403
2326 2404 unset( $total_len, $word );
2327 2405 }
2328 2406
2407 + $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length );
2408 +
2329 2409 return $sub . ( ( $len < $original_len ) ? $continue : '' );
2330 2410 }
2331 2411
2412 + /**
2413 + * If the string is still too long because there may not have been any spaces, force truncate.
2414 + *
2415 + * @since 6.5.4
2416 + *
2417 + * @param string $sub Current substring.
2418 + * @param int $length The length limit.
2419 + * @return string
2420 + */
2421 + private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) {
2422 + if ( strlen( $sub ) < $length + 50 ) {
2423 + // If the string isn't way over the limit, leave it.
2424 + return $sub;
2425 + }
2426 +
2427 + $first_space = strpos( $sub, ' ', $length );
2428 + if ( false !== $first_space ) {
2429 + // Ignore anything with spaces.
2430 + return $sub;
2431 + }
2432 +
2433 + return substr( $sub, 0, $length + 10 );
2434 + }
2435 +
2332 2436 public static function mb_function( $function_names, $args ) {
2333 2437 $mb_function_name = $function_names[0];
2334 2438 $function_name = $function_names[1];
2335 2439 if ( function_exists( $mb_function_name ) ) {
@@ -2647,8 +2751,9 @@
2647 2751 'reply_to' => __( 'If you would like a different reply to address than the "from" address, add a single address here. FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
2648 2752 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
2649 2753 /* translators: %1$s: Form name, %2$s: Date */
2650 2754 'email_subject' => esc_attr( sprintf( __( 'If you leave the subject blank, the default will be used: %1$s Form submitted on %2$s', 'formidable' ), $form_name, self::site_name() ) ),
2755 + 'new_tab' => __( 'This option will open the link in a new browser tab. Please note that some popup blockers may prevent this from happening, in which case the link will be displayed.', 'formidable' ),
2651 2756 );
2652 2757
2653 2758 if ( ! isset( $tooltips[ $name ] ) ) {
2654 2759 return;
@@ -2938,13 +3043,10 @@
2938 3043 */
2939 3044 public static function localize_script( $location ) {
2940 3045 global $wp_scripts;
2941 3046
2942 - $ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
2943 - $ajax_url = apply_filters( 'frm_ajax_url', $ajax_url );
2944 -
2945 3047 $script_strings = array(
2946 - 'ajax_url' => $ajax_url,
3048 + 'ajax_url' => esc_url_raw( self::get_ajax_url() ),
2947 3049 'images_url' => self::plugin_url() . '/images',
2948 3050 'loading' => __( 'Loading&hellip;', 'formidable' ),
2949 3051 'remove' => __( 'Remove', 'formidable' ),
2950 3052 'offset' => apply_filters( 'frm_scroll_offset', 4 ),
@@ -2958,72 +3060,93 @@
2958 3060 'include_alert_role' => self::should_include_alert_role_on_field_errors(),
2959 3061 );
2960 3062
2961 3063 $data = $wp_scripts->get_data( 'formidable', 'data' );
2962 - if ( empty( $data ) ) {
3064 + if ( ! $data ) {
2963 3065 wp_localize_script( 'formidable', 'frm_js', $script_strings );
2964 3066 }
2965 3067
2966 - if ( $location == 'admin' ) {
3068 + if ( $location === 'admin' ) {
2967 3069 $frm_settings = self::get_settings();
2968 3070 $admin_script_strings = array(
2969 - 'desc' => __( '(Click to add description)', 'formidable' ),
2970 - 'blank' => __( '(Blank)', 'formidable' ),
2971 - 'no_label' => __( '(no label)', 'formidable' ),
2972 - 'saving' => '', // Deprecated in 6.0.
2973 - 'saved' => '', // Deprecated in 6.0.
2974 - 'ok' => __( 'OK', 'formidable' ),
2975 - 'cancel' => __( 'Cancel', 'formidable' ),
2976 - 'default_label' => __( 'Default', 'formidable' ),
2977 - 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
2978 - 'no_clear_default' => __( 'Do not clear default value when typing', 'formidable' ),
2979 - 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
2980 - 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
2981 - 'confirm' => __( 'Are you sure?', 'formidable' ),
2982 - 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
2983 - 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ),
2984 - 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
2985 - 'default_unique' => $frm_settings->unique_msg,
2986 - 'default_conf' => __( 'The entered values do not match', 'formidable' ),
2987 - 'enter_email' => __( 'Enter Email', 'formidable' ),
2988 - 'confirm_email' => __( 'Confirm Email', 'formidable' ),
2989 - 'conditional_text' => __( 'Conditional content here', 'formidable' ),
2990 - 'new_option' => __( 'New Option', 'formidable' ),
2991 - 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ),
2992 - 'enter_password' => __( 'Enter Password', 'formidable' ),
2993 - 'confirm_password' => __( 'Confirm Password', 'formidable' ),
2994 - 'import_complete' => __( 'Import Complete', 'formidable' ),
2995 - 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
2996 - 'no_save_warning' => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
2997 - 'private_label' => __( 'Private', 'formidable' ),
2998 - 'jquery_ui_url' => '',
2999 - 'pro_url' => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '',
3000 - 'no_licenses' => __( 'No new licenses were found', 'formidable' ),
3001 - 'unmatched_parens' => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ),
3002 - 'view_shortcodes' => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ),
3003 - 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
3004 - 'only_one_action' => __( 'This form action is limited to one per form. Please edit the existing form action.', 'formidable' ),
3005 - 'unsafe_params' => FrmFormsHelper::reserved_words(),
3071 + 'desc' => __( '(Click to add description)', 'formidable' ),
3072 + 'blank' => __( '(Blank)', 'formidable' ),
3073 + 'no_label' => __( '(no label)', 'formidable' ),
3074 + 'ok' => __( 'OK', 'formidable' ),
3075 + 'cancel' => __( 'Cancel', 'formidable' ),
3076 + 'default_label' => __( 'Default', 'formidable' ),
3077 + 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
3078 + 'no_clear_default' => __( 'Do not clear default value when typing', 'formidable' ),
3079 + 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3080 + 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3081 + 'confirm' => __( 'Are you sure?', 'formidable' ),
3082 + 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3083 + 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ),
3084 + 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3085 + 'default_unique' => $frm_settings->unique_msg,
3086 + 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3087 + 'enter_email' => __( 'Enter Email', 'formidable' ),
3088 + 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3089 + 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3090 + 'new_option' => __( 'New Option', 'formidable' ),
3091 + 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ),
3092 + 'enter_password' => __( 'Enter Password', 'formidable' ),
3093 + 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3094 + 'import_complete' => __( 'Import Complete', 'formidable' ),
3095 + 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
3096 + 'no_save_warning' => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
3097 + 'private_label' => __( 'Private', 'formidable' ),
3098 + 'jquery_ui_url' => '',
3099 + 'pro_url' => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '',
3100 + 'no_licenses' => __( 'No new licenses were found', 'formidable' ),
3101 + 'unmatched_parens' => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ),
3102 + 'view_shortcodes' => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ),
3103 + 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
3104 + 'only_one_action' => __( 'This form action is limited to one per form. Please edit the existing form action.', 'formidable' ),
3105 + 'unsafe_params' => FrmFormsHelper::reserved_words(),
3006 3106 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
3007 - 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
3107 + 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
3008 3108 /* 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. */
3009 - 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
3010 - 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3011 - 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3012 - 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3013 - 'install' => __( 'Install', 'formidable' ),
3014 - 'active' => __( 'Active', 'formidable' ),
3015 - 'select_a_field' => __( 'Select a Field', 'formidable' ),
3016 - 'no_items_found' => __( 'No items found.', 'formidable' ),
3109 + 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
3110 + 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3111 + 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3112 + 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3113 + 'install' => __( 'Install', 'formidable' ),
3114 + 'active' => __( 'Active', 'formidable' ),
3115 + 'select_a_field' => __( 'Select a Field', 'formidable' ),
3116 + 'no_items_found' => __( 'No items found.', 'formidable' ),
3017 3117 'field_already_used' => __( 'Oops. You have already used that field.', 'formidable' ),
3118 + 'saving' => '', // Deprecated in 6.0.
3119 + 'saved' => '', // Deprecated in 6.0.
3120 + // translators: %1$s: HTML open tag, %2$s: HTML end tag.
3121 + 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
3018 3122 );
3123 + /**
3124 + * @param array $admin_script_strings
3125 + */
3019 3126 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3020 3127
3021 3128 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
3022 - if ( empty( $data ) ) {
3129 + if ( ! $data ) {
3023 3130 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
3024 3131 }
3025 3132 }
3133 + }
3134 +
3135 + /**
3136 + * @since 6.5
3137 + *
3138 + * @return string
3139 + */
3140 + public static function get_ajax_url() {
3141 + $ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
3142 +
3143 + /**
3144 + * @since 2.0.13
3145 + *
3146 + * @param string $ajax_url
3147 + */
3148 + return apply_filters( 'frm_ajax_url', $ajax_url );
3026 3149 }
3027 3150
3028 3151 /**
3029 3152 * Returns whether or not the first errored input should be auto-focused (default true).