PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.0.01
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.0.01
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 +284 -1267 6.4.25.0.01 View file →
@@ -3,21 +3,16 @@
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 = 98; // Version of the database we are moving to.
8 8 public static $pro_db_version = 37; //deprecated
9 - public static $font_version = 7;
9 + public static $font_version = 7;
10 10
11 11 /**
12 - * @var bool $added_gmt_offset_filter
13 - */
14 - private static $added_gmt_offset_filter = false;
15 -
16 - /**
17 12 * @since 2.0
18 13 */
19 - public static $plug_version = '6.4.2';
14 + public static $plug_version = '5.0.01';
20 15
21 16 /**
22 17 * @since 1.07.02
23 18 *
@@ -152,24 +147,8 @@
152 147 return $frm_settings->menu;
153 148 }
154 149
155 150 /**
156 - * Determine if the current branding is set to 'formidable'.
157 - *
158 - * Checks the menu title, retrieved through get_menu_name,
159 - * and verifies if it matches the 'formidable' branding.
160 - *
161 - * @since x.x
162 - *
163 - * @return bool True if the menu title is 'formidable', false otherwise.
164 - */
165 - public static function is_formidable_branding() {
166 - $menu_title = self::get_menu_name();
167 -
168 - return 'formidable' === strtolower( trim( $menu_title ) );
169 - }
170 -
171 - /**
172 151 * @since 3.05
173 152 */
174 153 public static function svg_logo( $atts = array() ) {
175 154 $defaults = array(
@@ -189,9 +168,9 @@
189 168 /**
190 169 * @since 4.0
191 170 */
192 171 public static function show_logo( $atts = array() ) {
193 - echo self::kses( self::svg_logo( $atts ), 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
172 + echo self::kses( self::svg_logo( $atts ), 'all' ); // WPCS: XSS ok.
194 173 }
195 174
196 175 /**
197 176 * @since 4.03.02
@@ -212,9 +191,9 @@
212 191 // Show nothing if it isn't an SVG.
213 192 $icon = '<div style="height:39px"></div>';
214 193 }
215 194 }
216 - echo self::kses( $icon, 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
195 + echo self::kses( $icon, 'all' ); // WPCS: XSS ok.
217 196 }
218 197
219 198 /**
220 199 * @since 2.02.04
@@ -268,15 +247,15 @@
268 247 global $pagenow;
269 248 $get_page = self::simple_get( 'page', 'sanitize_title' );
270 249 if ( $pagenow ) {
271 250 // allow this to be true during ajax load i.e. ajax form builder loading
272 - $is_page = ( $pagenow === 'admin.php' || $pagenow === 'admin-ajax.php' ) && $get_page === $page;
251 + $is_page = ( $pagenow == 'admin.php' || $pagenow == 'admin-ajax.php' ) && $get_page == $page;
273 252 if ( $is_page ) {
274 253 return true;
275 254 }
276 255 }
277 256
278 - return is_admin() && $get_page === $page;
257 + return is_admin() && $get_page == $page;
279 258 }
280 259
281 260 /**
282 261 * If the current page is for editing or creating a view.
@@ -348,18 +327,14 @@
348 327 * Check if on an admin page
349 328 *
350 329 * @since 2.0
351 330 *
331 + * @param None
332 + *
352 333 * @return boolean
353 334 */
354 335 public static function is_admin() {
355 - $is_admin = is_admin() && ! wp_doing_ajax();
356 -
357 - /**
358 - * @since 6.0
359 - * @param bool $is_admin
360 - */
361 - return apply_filters( 'frm_is_admin', $is_admin );
336 + return is_admin() && ! wp_doing_ajax();
362 337 }
363 338
364 339 /**
365 340 * Check if value contains blank value or empty array
@@ -392,38 +367,26 @@
392 367 return isset( $_SERVER[ $value ] ) ? wp_strip_all_tags( wp_unslash( $_SERVER[ $value ] ) ) : '';
393 368 }
394 369
395 370 /**
396 - * Get the server OS
371 + * Check for the IP address in several places
372 + * Used by [ip] shortcode
397 373 *
398 - * @since 6.4.x
399 - *
400 - * @return string
401 - */
402 - public static function get_server_os() {
403 -
404 - if ( function_exists( 'php_uname' ) ) {
405 - return php_uname( 's' );
406 - }
407 -
408 - if ( ! defined( 'PHP_OS' ) ) {
409 - return '';
410 - }
411 -
412 - // match the same response for Windows server as php_uname('s')
413 - return in_array( PHP_OS, array( 'WIN32', 'WINNT', 'Windows_NT' ), true ) ? 'Windows NT' : PHP_OS;
414 - }
415 -
416 - /**
417 - * Check for the IP address in several places (when custom headers are enabled).
418 - * Used by [ip] shortcode.
419 - *
420 374 * @return string The IP address of the current user
421 375 */
422 376 public static function get_ip_address() {
423 - $ip_options = self::should_use_custom_header_ip() ? self::get_custom_header_keys_for_ip() : array( 'REMOTE_ADDR' );
424 - $ip = '';
425 -
377 + $ip_options = array(
378 + 'HTTP_CLIENT_IP',
379 + 'HTTP_CF_CONNECTING_IP',
380 + 'HTTP_X_FORWARDED_FOR',
381 + 'HTTP_X_FORWARDED',
382 + 'HTTP_X_CLUSTER_CLIENT_IP',
383 + 'HTTP_X_REAL_IP',
384 + 'HTTP_FORWARDED_FOR',
385 + 'HTTP_FORWARDED',
386 + 'REMOTE_ADDR',
387 + );
388 + $ip = '';
426 389 foreach ( $ip_options as $key ) {
427 390 if ( ! isset( $_SERVER[ $key ] ) ) {
428 391 continue;
429 392 }
@@ -429,9 +392,9 @@
429 392 }
430 393
431 394 $key = self::get_server_value( $key );
432 395 foreach ( explode( ',', $key ) as $ip ) {
433 - $ip = trim( $ip ); // Just to be safe.
396 + $ip = trim( $ip ); // just to be safe.
434 397
435 398 if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) {
436 399 return sanitize_text_field( $ip );
437 400 }
@@ -440,52 +403,8 @@
440 403
441 404 return sanitize_text_field( $ip );
442 405 }
443 406
444 - /**
445 - * @since 6.1
446 - *
447 - * @return array
448 - */
449 - public static function get_custom_header_keys_for_ip() {
450 - return array(
451 - 'HTTP_CLIENT_IP',
452 - 'HTTP_CF_CONNECTING_IP',
453 - 'HTTP_X_FORWARDED_FOR',
454 - 'HTTP_X_FORWARDED',
455 - 'HTTP_X_CLUSTER_CLIENT_IP',
456 - 'HTTP_X_REAL_IP',
457 - 'HTTP_FORWARDED_FOR',
458 - 'HTTP_FORWARDED',
459 - 'REMOTE_ADDR',
460 - );
461 - }
462 -
463 - /**
464 - * Check if we should check every HTTP header or just $_SERVER['REMOTE_ADDR'].
465 - * The other HTTP headers can be spoofed so this isn't recommended.
466 - * But in some cases (like reverse proxies), the IP may be empty if you use $_SERVER['REMOTE_ADDR'].
467 - *
468 - * @since 6.1
469 - *
470 - * @return bool
471 - */
472 - private static function should_use_custom_header_ip() {
473 - $settings = self::get_settings();
474 - $should_use_custom_header_ip = ! $settings->no_ips && $settings->custom_header_ip;
475 -
476 - /**
477 - * Filter whether to check spoofable HTTP headers.
478 - * This uses the custom_header_ip setting, but it is hidden if the GDPR option is also on.
479 - * As the IP is still checked for blacklist checks, someone with the GDPR option may still want to enable this when behind a reverse proxy.
480 - *
481 - * @since 6.1
482 - *
483 - * @param bool $should_use_custom_header_ip
484 - */
485 - return apply_filters( 'frm_use_custom_header_ip', $should_use_custom_header_ip );
486 - }
487 -
488 407 public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
489 408 if ( strpos( $param, '[' ) ) {
490 409 $params = explode( '[', $param );
491 410 $param = $params[0];
@@ -490,11 +409,12 @@
490 409 $params = explode( '[', $param );
491 410 $param = $params[0];
492 411 }
493 412
494 - if ( $src === 'get' ) {
495 - $value = isset( $_POST[ $param ] ) ? wp_unslash( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? wp_unslash( $_GET[ $param ] ) : $default ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
496 - if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
413 + if ( $src == 'get' ) {
414 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
415 + $value = isset( $_POST[ $param ] ) ? wp_unslash( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? wp_unslash( $_GET[ $param ] ) : $default );
416 + if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) {
497 417 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
498 418 $value = htmlspecialchars_decode( wp_unslash( $_GET[ $param ] ) );
499 419 }
500 420 self::sanitize_value( $sanitize, $value );
@@ -576,14 +496,14 @@
576 496
577 497 $value = $args['default'];
578 498 if ( $args['type'] == 'get' ) {
579 499 if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
580 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
500 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
581 501 $value = wp_unslash( $_GET[ $args['param'] ] );
582 502 }
583 503 } elseif ( $args['type'] == 'post' ) {
584 - if ( isset( $_POST[ $args['param'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
585 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
504 + if ( isset( $_POST[ $args['param'] ] ) ) {
505 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
586 506 $value = wp_unslash( $_POST[ $args['param'] ] );
587 507 if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) {
588 508 self::unserialize_or_decode( $value );
589 509 }
@@ -588,9 +508,9 @@
588 508 self::unserialize_or_decode( $value );
589 509 }
590 510 }
591 511 } else {
592 - if ( isset( $_REQUEST[ $args['param'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
512 + if ( isset( $_REQUEST[ $args['param'] ] ) ) {
593 513 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
594 514 $value = wp_unslash( $_REQUEST[ $args['param'] ] );
595 515 }
596 516 }
@@ -725,80 +645,14 @@
725 645 return wp_kses( $value, $allowed_html );
726 646 }
727 647
728 648 /**
729 - * The regular kses function strips [button_action] from submit button HTML.
730 - *
731 - * @since 5.0.13
732 - *
733 - * @param string $html
734 - * @return string
735 - */
736 - public static function kses_submit_button( $html ) {
737 - $included_button_action = false !== strpos( $html, '[button_action]' );
738 - $included_back_hook = false !== strpos( $html, '[back_hook]' );
739 - $included_draft_hook = false !== strpos( $html, '[draft_hook]' );
740 - add_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
741 - add_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
742 - $html = self::kses( $html, 'all' );
743 - remove_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
744 - remove_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
745 - if ( $included_button_action ) {
746 - if ( false !== strpos( $html, '<input type="submit"' ) ) {
747 - $pattern = '/(<input type="submit")([^>]*)(\/>)/';
748 - $html = preg_replace( $pattern, '$1$2[button_action] $3', $html, 1 );
749 - } else {
750 - $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
751 - $html = preg_replace( $pattern, '$1$2$3$4$5$6$7 [button_action]$8$9$10', $html, 1 );
752 - }
753 - }
754 - if ( $included_back_hook ) {
755 - $html = str_replace( 'class="frm_prev_page"', 'class="frm_prev_page" [back_hook]', $html );
756 - }
757 - if ( $included_draft_hook ) {
758 - $html = str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html );
759 - }
760 - return $html;
761 - }
762 -
763 - /**
764 - * @since 5.0.13
765 - *
766 - * @param array $allowed_attr
767 - * @return array
768 - */
769 - public static function allow_visibility_style( $allowed_attr ) {
770 - $allowed_attr[] = 'visibility';
771 - return $allowed_attr;
772 - }
773 -
774 - /**
775 - * @since 5.0.13
776 - *
777 - * @param array $allowed_html
778 - * @return array
779 - */
780 - public static function add_allowed_submit_button_tags( $allowed_html ) {
781 - $allowed_html['input'] = array(
782 - 'type' => true,
783 - 'value' => true,
784 - 'formnovalidate' => true,
785 - 'name' => true,
786 - 'class' => true,
787 - );
788 - $allowed_html['button']['formnovalidate'] = true;
789 - $allowed_html['button']['name'] = true;
790 - $allowed_html['img']['style'] = true;
791 - return $allowed_html;
792 - }
793 -
794 - /**
795 649 * @since 2.05.03
796 650 */
797 651 private static function allowed_html( $allowed ) {
798 652 $html = self::safe_html();
799 653 $allowed_html = array();
800 - if ( $allowed === 'all' ) {
654 + if ( $allowed == 'all' ) {
801 655 $allowed_html = $html;
802 656 } elseif ( ! empty( $allowed ) ) {
803 657 foreach ( (array) $allowed as $a ) {
804 658 $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
@@ -817,16 +671,15 @@
817 671 'id' => true,
818 672 );
819 673
820 674 return array(
821 - 'a' => array(
822 - 'class' => true,
823 - 'href' => true,
824 - 'id' => true,
825 - 'rel' => true,
826 - 'target' => true,
827 - 'title' => true,
828 - 'tabindex' => true,
675 + 'a' => array(
676 + 'class' => true,
677 + 'href' => true,
678 + 'id' => true,
679 + 'rel' => true,
680 + 'target' => true,
681 + 'title' => true,
829 682 ),
830 683 'abbr' => array(
831 684 'title' => true,
832 685 ),
@@ -850,9 +703,8 @@
850 703 'class' => true,
851 704 'id' => true,
852 705 'title' => true,
853 706 'style' => true,
854 - 'role' => true,
855 707 ),
856 708 'dl' => array(),
857 709 'dt' => array(),
858 710 'em' => array(),
@@ -901,13 +753,12 @@
901 753 'stroke-width' => true,
902 754 ),
903 755 'section' => $allow_class,
904 756 'span' => array(
905 - 'class' => true,
906 - 'id' => true,
907 - 'title' => true,
908 - 'style' => true,
909 - 'aria-hidden' => true,
757 + 'class' => true,
758 + 'id' => true,
759 + 'title' => true,
760 + 'style' => true,
910 761 ),
911 762 'strike' => array(),
912 763 'strong' => array(),
913 764 'symbol' => array(
@@ -915,36 +766,22 @@
915 766 'id' => true,
916 767 'viewbox' => true,
917 768 ),
918 769 'svg' => array(
919 - 'class' => true,
920 - 'id' => true,
921 - 'xmlns' => true,
922 - 'viewbox' => true,
923 - 'width' => true,
924 - 'height' => true,
925 - 'style' => true,
926 - 'fill' => true,
927 - 'aria-label' => true,
928 - 'aria-hidden' => true,
770 + 'class' => true,
771 + 'id' => true,
772 + 'xmlns' => true,
773 + 'viewbox' => true,
774 + 'width' => true,
775 + 'height' => true,
776 + 'style' => true,
777 + 'fill' => true,
929 778 ),
930 779 'use' => array(
931 - 'href' => true,
780 + 'href' => true,
932 781 'xlink:href' => true,
933 782 ),
934 783 'ul' => $allow_class,
935 - 'label' => array(
936 - 'for' => true,
937 - 'class' => true,
938 - 'id' => true,
939 - ),
940 - 'button' => array(
941 - 'class' => true,
942 - 'type' => true,
943 - ),
944 - 'legend' => array(
945 - 'class' => true,
946 - ),
947 784 );
948 785 }
949 786
950 787 /**
@@ -1002,18 +839,8 @@
1002 839
1003 840 $html_atts = self::array_to_html_params( $atts );
1004 841
1005 842 $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1006 -
1007 - // Replace icons that have been removed.
1008 - $deprecated = array(
1009 - 'frm_clone_solid_icon' => 'frm_clone_icon',
1010 - );
1011 - if ( isset( $deprecated[ $icon ] ) ) {
1012 - $icon = $deprecated[ $icon ];
1013 - $class = str_replace( $icon, $deprecated[ $icon ], $class );
1014 - }
1015 -
1016 843 if ( $icon === $class ) {
1017 844 $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
1018 845 } else {
1019 846 $class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
@@ -1020,15 +847,15 @@
1020 847 if ( strpos( $icon, ' ' ) ) {
1021 848 $icon = explode( ' ', $icon );
1022 849 $icon = reset( $icon );
1023 850 }
1024 - $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '>
851 + $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '>
1025 852 <use xlink:href="#' . esc_attr( $icon ) . '" />
1026 853 </svg>';
1027 854 }
1028 855
1029 856 if ( $echo ) {
1030 - echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
857 + echo $icon; // WPCS: XSS ok.
1031 858 } else {
1032 859 return $icon;
1033 860 }
1034 861 }
@@ -1033,88 +860,14 @@
1033 860 }
1034 861 }
1035 862
1036 863 /**
1037 - * Run kses for icons. It needs to add a few filters first in order to preserve some custom style values.
1038 - *
1039 - * @since 5.0.13
1040 - *
1041 - * @param string $icon
1042 - * @return string
1043 - */
1044 - public static function kses_icon( $icon ) {
1045 - add_filter( 'safe_style_css', 'FrmAppHelper::allow_vars_in_styles' );
1046 - add_filter( 'safecss_filter_attr_allow_css', 'FrmAppHelper::allow_style', 10, 2 );
1047 - add_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_icon_tags' );
1048 - $icon = self::kses( $icon, 'all' );
1049 - remove_filter( 'safe_style_css', 'FrmAppHelper::allow_vars_in_styles' );
1050 - remove_filter( 'safecss_filter_attr_allow_css', 'FrmAppHelper::allow_style' );
1051 - remove_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_icon_tags' );
1052 - return $icon;
1053 - }
1054 -
1055 - /**
1056 - * @since 5.0.13.1
1057 - *
1058 - * @param array $allowed_html
1059 - * @return array
1060 - */
1061 - public static function add_allowed_icon_tags( $allowed_html ) {
1062 - $allowed_html['svg']['data-open'] = true;
1063 - $allowed_html['svg']['title'] = true;
1064 - return $allowed_html;
1065 - }
1066 -
1067 - /**
1068 - * @since 5.0.13
1069 - *
1070 - * @param array $allowed_attr
1071 - * @return array
1072 - */
1073 - public static function allow_vars_in_styles( $allowed_attr ) {
1074 - $allowed_attr[] = '--primary-700';
1075 - return $allowed_attr;
1076 - }
1077 -
1078 - /**
1079 - * @since 5.0.13
1080 - *
1081 - * @param bool $allow_css
1082 - * @param string $css_string
1083 - */
1084 - public static function allow_style( $allow_css, $css_string ) {
1085 - if ( ! $allow_css && 0 === strpos( $css_string, '--primary-700:' ) ) {
1086 - $split = explode( ':', $css_string, 2 );
1087 - $allow_css = 2 === count( $split ) && self::is_a_valid_color( $split[1] );
1088 - }
1089 - return $allow_css;
1090 - }
1091 -
1092 - /**
1093 - * @since 5.0.13
1094 - *
1095 - * @param string $value
1096 - * @return bool
1097 - */
1098 - private static function is_a_valid_color( $value ) {
1099 - $match = 0;
1100 - if ( 0 === strpos( $value, 'rgba(' ) ) {
1101 - $match = preg_match( '/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/', $value );
1102 - } elseif ( 0 === strpos( $value, 'rgb(' ) ) {
1103 - $match = preg_match( '/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/', $value );
1104 - } elseif ( 0 === strpos( $value, '#' ) ) {
1105 - $match = preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})\b$/', $value );
1106 - }
1107 - return (bool) $match;
1108 - }
1109 -
1110 - /**
1111 864 * Include svg images.
1112 865 *
1113 866 * @since 4.0.02
1114 867 */
1115 868 public static function include_svg() {
1116 - include_once self::plugin_path() . '/images/icons.svg';
869 + include_once( self::plugin_path() . '/images/icons.svg' );
1117 870 }
1118 871
1119 872 /**
1120 873 * Convert an associative array to HTML values.
@@ -1119,48 +872,19 @@
1119 872 /**
1120 873 * Convert an associative array to HTML values.
1121 874 *
1122 875 * @since 4.0.02
1123 - * @since 5.0.13 added $echo parameter.
1124 - *
1125 876 * @param array $atts
1126 - * @param bool $echo
1127 - * @return string|void
877 + * @return string
1128 878 */
1129 - public static function array_to_html_params( $atts, $echo = false ) {
1130 - $callback = function() use ( $atts ) {
1131 - if ( $atts ) {
1132 - foreach ( $atts as $key => $value ) {
1133 - echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1134 - }
879 + public static function array_to_html_params( $atts ) {
880 + $html = '';
881 + if ( ! empty( $atts ) ) {
882 + foreach ( $atts as $key => $value ) {
883 + $html .= ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1135 884 }
1136 - };
1137 - return self::clip( $callback, $echo );
1138 - }
1139 -
1140 - /**
1141 - * Call an echo function and either echo it or return the result as a string.
1142 - *
1143 - * @since 5.0.13
1144 - *
1145 - * @param Closure $echo_function
1146 - * @param bool $echo
1147 - * @return string|void
1148 - */
1149 - public static function clip( $echo_function, $echo = false ) {
1150 - if ( ! $echo ) {
1151 - ob_start();
1152 885 }
1153 -
1154 - if ( is_callable( $echo_function ) ) {
1155 - $echo_function();
1156 - }
1157 -
1158 - if ( ! $echo ) {
1159 - $return = ob_get_contents();
1160 - ob_end_clean();
1161 - return $return;
1162 - }
886 + return $html;
1163 887 }
1164 888
1165 889 /**
1166 890 * @since 3.0
@@ -1177,94 +901,31 @@
1177 901 include( self::plugin_path() . '/classes/views/shared/admin-header.php' );
1178 902 }
1179 903
1180 904 /**
1181 - * @since 6.0
1182 - *
1183 - * @param string $type
1184 - * @return void
1185 - */
1186 - public static function import_link( $type = 'secondary' ) {
1187 - ?>
1188 - <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">
1189 - <?php esc_html_e( 'Import', 'formidable' ); ?>
1190 - </a>
1191 - <?php
1192 - }
1193 -
1194 - /**
1195 - * Print applicable admin banner.
1196 - *
1197 - * @since 5.4.2
1198 - *
1199 - * @param bool $should_show_lite_upgrade
1200 - * @return void
1201 - */
1202 - public static function print_admin_banner( $should_show_lite_upgrade ) {
1203 - if ( ! current_user_can( 'administrator' ) ) {
1204 - FrmInbox::maybe_show_banner();
1205 - return;
1206 - }
1207 -
1208 - if ( self::maybe_show_license_warning() || FrmInbox::maybe_show_banner() || ! $should_show_lite_upgrade || self::pro_is_installed() ) {
1209 - // Print license warning or inbox banner and exit if either prints.
1210 - // And exit before printing the upgrade bar if it shouldn't be shown.
1211 - return;
1212 - }
1213 - ?>
1214 - <div class="frm-upgrade-bar">
1215 - <span>You're using Formidable Forms Lite. To unlock more features consider</span>
1216 - <a href="<?php echo esc_url( self::admin_upgrade_link( 'top-bar' ) ); ?>" target="_blank" rel="noopener">upgrading to Pro</a>.
1217 - </div>
1218 - <?php
1219 - }
1220 -
1221 - /**
1222 - * @since 5.4.2
1223 - *
1224 - * @return bool True if a banner is available and shown.
1225 - */
1226 - private static function maybe_show_license_warning() {
1227 - return is_callable( 'FrmProAddonsController::admin_banner' ) && FrmProAddonsController::admin_banner();
1228 - }
1229 -
1230 - /**
1231 - * Render a button for a new item (Form, Application, etc).
1232 - *
1233 905 * @since 3.0
1234 - * @param array $atts {
1235 - * @type array $link_hook Custom link hook, calls do_action and exits early.
1236 - * @type string $new_link Href value, default #.
1237 - * @type string $class Custom class names, space separated.
1238 - * @type string $button_text Button text. Default "Add New".
1239 - * }
1240 - * @return void
906 + * @param array $atts
1241 907 */
1242 908 public static function add_new_item_link( $atts ) {
1243 - if ( isset( $atts['link_hook'] ) ) {
909 + if ( ! empty( $atts['new_link'] ) ) {
910 + ?>
911 + <a href="<?php echo esc_url( $atts['new_link'] ); ?>" class="button button-primary frm-button-primary frm-with-plus">
912 + <?php self::icon_by_class( 'frmfont frm_plus_icon frm_svg15' ); ?>
913 + <?php esc_html_e( 'Add New', 'formidable' ); ?>
914 + </a>
915 + <?php
916 + } elseif ( ! empty( $atts['trigger_new_form_modal'] ) ) {
917 + ?>
918 + <a href="#" class="button button-primary frm-button-primary frm-with-plus frm-trigger-new-form-modal">
919 + <?php
920 + self::icon_by_class( 'frmfont frm_plus_icon frm_svg15' );
921 + esc_html_e( 'Add New', 'formidable' );
922 + ?>
923 + </a>
924 + <?php
925 + } elseif ( isset( $atts['link_hook'] ) ) {
1244 926 do_action( $atts['link_hook']['hook'], $atts['link_hook']['param'] );
1245 - return;
1246 927 }
1247 -
1248 - if ( empty( $atts['new_link'] ) && empty( $atts['trigger_new_form_modal'] ) && empty( $atts['class'] ) ) {
1249 - // Do not render a button if none of these attributes are set.
1250 - return;
1251 - }
1252 -
1253 - $href = ! empty( $atts['new_link'] ) ? esc_url( $atts['new_link'] ) : '#';
1254 - $class = 'button button-primary frm-button-primary';
1255 -
1256 - if ( ! empty( $atts['trigger_new_form_modal'] ) ) {
1257 - $class .= ' frm-trigger-new-form-modal';
1258 - }
1259 -
1260 - if ( ! empty( $atts['class'] ) ) {
1261 - $class .= ' ' . $atts['class'];
1262 - }
1263 -
1264 - $button_text = ! empty( $atts['button_text'] ) ? $atts['button_text'] : __( 'Add New', 'formidable' );
1265 -
1266 - require self::plugin_path() . '/classes/views/shared/add-button.php';
1267 928 }
1268 929
1269 930 /**
1270 931 * @since 3.06
@@ -1337,8 +998,9 @@
1337 998 );
1338 999 $new_file = new FrmCreateFile( $file_atts );
1339 1000
1340 1001 $files = array(
1002 + self::plugin_path() . '/js/jquery/jquery.placeholder.min.js',
1341 1003 self::plugin_path() . '/js/formidable.min.js',
1342 1004 );
1343 1005 $files = apply_filters( 'frm_combined_js_files', $files );
1344 1006 $new_file->combine_files( $files );
@@ -1359,9 +1021,8 @@
1359 1021 }
1360 1022
1361 1023 /**
1362 1024 * Gets all post from a specific post type.
1363 - * This gets the entire WP_Post object so it can require a lot of memory. When only id and title are needed, consider using FrmAppHelper::get_post_ids_and_titles instead.
1364 1025 *
1365 1026 * @since 4.10.01 Add `$post_type` argument.
1366 1027 *
1367 1028 * @param string $post_type Post type to query. Default is `page`.
@@ -1379,30 +1040,8 @@
1379 1040 return get_posts( $query );
1380 1041 }
1381 1042
1382 1043 /**
1383 - * Gets post ids and titles for a specific post type.
1384 - *
1385 - * @since 5.0.09
1386 - *
1387 - * @param string $post_type Post type to query. Default is `page`.
1388 - * @return array
1389 - */
1390 - public static function get_post_ids_and_titles( $post_type = 'page' ) {
1391 - return FrmDb::get_results(
1392 - 'posts',
1393 - array(
1394 - 'post_type' => $post_type,
1395 - 'post_status' => array( 'publish', 'private' ),
1396 - ),
1397 - 'ID, post_title',
1398 - array(
1399 - 'order_by' => 'post_title ASC',
1400 - )
1401 - );
1402 - }
1403 -
1404 - /**
1405 1044 * Renders an autocomplete page selection or a regular dropdown depending on
1406 1045 * the total page count
1407 1046 *
1408 1047 * @since 4.03.06
@@ -1447,9 +1086,9 @@
1447 1086 */
1448 1087 public static function wp_pages_dropdown( $args = array(), $page_id = '', $truncate = false ) {
1449 1088 self::prep_page_dropdown_params( $page_id, $truncate, $args );
1450 1089
1451 - $pages = self::get_post_ids_and_titles( $args['post_type'] );
1090 + $pages = self::get_pages( $args['post_type'] );
1452 1091 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
1453 1092
1454 1093 ?>
1455 1094 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
@@ -1503,8 +1142,9 @@
1503 1142 public static function post_edit_link( $post_id ) {
1504 1143 $post = get_post( $post_id );
1505 1144 if ( $post ) {
1506 1145 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1146 + $post_url = self::maybe_full_screen_link( $post_url );
1507 1147
1508 1148 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
1509 1149 }
1510 1150
@@ -1514,64 +1154,25 @@
1514 1154 /**
1515 1155 * Hide the WordPress menus on some pages.
1516 1156 *
1517 1157 * @since 4.0
1518 - *
1519 - * @return bool
1520 1158 */
1521 1159 public static function is_full_screen() {
1522 - return self::is_form_builder_page() ||
1523 - self::is_style_editor_page() ||
1524 - self::is_full_screen_view_builder_page();
1525 - }
1160 + $full_builder = self::is_form_builder_page();
1161 + $styler = self::is_admin_page( 'formidable-styles' ) || self::is_admin_page( 'formidable-styles2' );
1162 + $full_entries = self::simple_get( 'frm-full', 'absint' );
1526 1163
1527 - /**
1528 - * Check if user is on the style editor or its alternative URL.
1529 - * The first URL is a submenu "Styles" in the Formidable menu /wp-admin/admin.php?page=formidable-styles.
1530 - * The alternative URL is linked as a submenu "Forms" item of the Appearance menu /wp-admin/themes.php?page=formidable-styles2.
1531 - *
1532 - * @since 5.5.3
1533 - * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
1534 - *
1535 - * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
1536 - * @return bool
1537 - */
1538 - public static function is_style_editor_page( $view = '' ) {
1539 - if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
1540 - return false;
1541 - }
1542 -
1543 - if ( ! in_array( $view, array( 'list', 'edit' ), true ) ) {
1544 - return true;
1545 - }
1546 -
1547 - $action = self::simple_get( 'frm_action' );
1548 - $is_edit_mode = 'edit' === $action || ( ! $action && ! self::simple_get( 'id' ) && ! self::simple_get( 'form' ) );
1549 -
1550 - if ( ! $is_edit_mode && class_exists( 'FrmProStylesController' ) && in_array( $action, array( 'new_style', 'duplicate' ), true ) ) {
1551 - $is_edit_mode = true;
1552 - }
1553 -
1554 - $checking_for_edit_mode = 'edit' === $view;
1555 -
1556 - return $is_edit_mode === $checking_for_edit_mode;
1164 + return $full_builder || $full_entries || $styler || self::is_view_builder_page();
1557 1165 }
1558 1166
1559 1167 /**
1560 - * @since 5.5.3
1561 - *
1562 - * @return bool
1563 - */
1564 - private static function is_full_screen_view_builder_page() {
1565 - return self::is_admin_page( 'formidable-views-editor' );
1566 - }
1567 -
1568 - /**
1569 1168 * @since 4.0
1570 - * @deprecated 5.5.3
1571 1169 */
1572 1170 public static function maybe_full_screen_link( $link ) {
1573 - _deprecated_function( __METHOD__, '5.5.3' );
1171 + $is_full = self::simple_get( 'frm-full', 'absint' );
1172 + if ( $is_full && ! empty( $link ) && $link !== '#' ) {
1173 + $link .= '&frm-full=1';
1174 + }
1574 1175 return $link;
1575 1176 }
1576 1177
1577 1178 /**
@@ -1631,10 +1232,19 @@
1631 1232 * @param string $type Supports `auto`, `pro`, or `pro_only`.
1632 1233 * @return array
1633 1234 */
1634 1235 public static function frm_capabilities( $type = 'auto' ) {
1635 - if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
1636 - return self::get_lite_capabilities();
1236 + $cap = array(
1237 + 'frm_view_forms' => __( 'View Forms', 'formidable' ),
1238 + 'frm_edit_forms' => __( 'Add and Edit Forms', 'formidable' ),
1239 + 'frm_delete_forms' => __( 'Delete Forms', 'formidable' ),
1240 + 'frm_change_settings' => __( 'Access this Settings Page', 'formidable' ),
1241 + 'frm_view_entries' => __( 'View Entries from Admin Area', 'formidable' ),
1242 + 'frm_delete_entries' => __( 'Delete Entries from Admin Area', 'formidable' ),
1243 + );
1244 +
1245 + if ( ! self::pro_is_installed() && 'pro' !== $type && 'pro_only' !== $type ) {
1246 + return $cap;
1637 1247 }
1638 1248
1639 1249 $pro_cap = array(
1640 1250 'frm_create_entries' => __( 'Add Entries from Admin Area', 'formidable' ),
@@ -1641,41 +1251,17 @@
1641 1251 'frm_edit_entries' => __( 'Edit Entries from Admin Area', 'formidable' ),
1642 1252 'frm_view_reports' => __( 'View Reports', 'formidable' ),
1643 1253 'frm_edit_displays' => __( 'Add/Edit Views', 'formidable' ),
1644 1254 );
1645 - /**
1646 - * @since 5.3.1
1647 - *
1648 - * @param array<string,string> $pro_cap
1649 - */
1650 - $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
1651 1255
1652 1256 if ( 'pro_only' === $type ) {
1653 1257 return $pro_cap;
1654 1258 }
1655 1259
1656 - return self::get_lite_capabilities() + $pro_cap;
1260 + return $cap + $pro_cap;
1657 1261 }
1658 1262
1659 1263 /**
1660 - * Get the list of lite plugin capabilities.
1661 - *
1662 - * @since 5.3.1
1663 - *
1664 - * @return array<string,string>
1665 - */
1666 - private static function get_lite_capabilities() {
1667 - return array(
1668 - 'frm_view_forms' => __( 'View Forms', 'formidable' ),
1669 - 'frm_edit_forms' => __( 'Add and Edit Forms', 'formidable' ),
1670 - 'frm_delete_forms' => __( 'Delete Forms', 'formidable' ),
1671 - 'frm_change_settings' => __( 'Access this Settings Page', 'formidable' ),
1672 - 'frm_view_entries' => __( 'View Entries from Admin Area', 'formidable' ),
1673 - 'frm_delete_entries' => __( 'Delete Entries from Admin Area', 'formidable' ),
1674 - );
1675 - }
1676 -
1677 - /**
1678 1264 * Call the WordPress current_user_can but also validate empty strings as true for any logged in user
1679 1265 *
1680 1266 * @since 4.06.03
1681 1267 *
@@ -1920,8 +1506,19 @@
1920 1506 return $val;
1921 1507 }
1922 1508
1923 1509 /**
1510 + * @since 2.0
1511 + * @return string The base Google APIS url for the current version of jQuery UI
1512 + */
1513 + public static function jquery_ui_base_url() {
1514 + $url = 'http' . ( is_ssl() ? 's' : '' ) . '://ajax.googleapis.com/ajax/libs/jqueryui/' . self::script_version( 'jquery-ui-core', '1.11.4' );
1515 + $url = apply_filters( 'frm_jquery_ui_base_url', $url );
1516 +
1517 + return $url;
1518 + }
1519 +
1520 + /**
1924 1521 * @param string $handle
1925 1522 */
1926 1523 public static function script_version( $handle, $default = 0 ) {
1927 1524 global $wp_scripts;
@@ -1941,20 +1538,10 @@
1941 1538
1942 1539 return $ver;
1943 1540 }
1944 1541
1945 - /**
1946 - * @since 5.0.13 added $echo param.
1947 - *
1948 - * @param string $url
1949 - * @param bool $echo
1950 - * @return string|void
1951 - */
1952 - public static function js_redirect( $url, $echo = false ) {
1953 - $callback = function() use ( $url ) {
1954 - echo '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>';
1955 - };
1956 - return self::clip( $callback, $echo );
1542 + public static function js_redirect( $url ) {
1543 + return '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>';
1957 1544 }
1958 1545
1959 1546 public static function get_user_id_param( $user_id ) {
1960 1547 if ( ! $user_id || is_numeric( $user_id ) ) {
@@ -2013,38 +1600,21 @@
2013 1600 }
2014 1601
2015 1602 $key = self::prevent_numeric_and_reserved_keys( $key );
2016 1603
2017 - $similar_keys = FrmDb::get_col(
1604 + $key_check = FrmDb::get_var(
2018 1605 $table_name,
2019 1606 array(
2020 - $column . ' like%' => $key,
2021 - 'ID !' => $id,
1607 + $column => $key,
1608 + 'ID !' => $id,
2022 1609 ),
2023 1610 $column
2024 1611 );
2025 1612
2026 - // Create a unique field id if it has already been used.
2027 - if ( in_array( $key, $similar_keys, true ) ) {
1613 + if ( $key_check || is_numeric( $key_check ) ) {
2028 1614 $key = self::maybe_truncate_key_before_appending( $column, $key );
2029 -
2030 - /**
2031 - * Allow for a custom separator between the attempted key and the generated suffix.
2032 - *
2033 - * @since 5.2.03
2034 - *
2035 - * @param string $separator. Default empty.
2036 - * @param string $key the key without the added suffix.
2037 - */
2038 - $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2039 -
2040 - $suffix = 2;
2041 - do {
2042 - $key_check = $key . $separator . $suffix;
2043 - ++$suffix;
2044 - } while ( in_array( $key_check, $similar_keys, true ) );
2045 -
2046 - $key = $key_check;
1615 + // Create a unique field id if it has already been used.
1616 + $key = $key . substr( md5( microtime() . rand() ), 0, 10 );
2047 1617 }
2048 1618
2049 1619 return $key;
2050 1620 }
@@ -2061,11 +1631,8 @@
2061 1631 if ( in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2062 1632 $max_key_length_before_truncating = 60;
2063 1633 if ( strlen( $key ) > $max_key_length_before_truncating ) {
2064 1634 $key = substr( $key, 0, $max_key_length_before_truncating );
2065 - if ( is_numeric( $key ) ) {
2066 - $key .= 'a';
2067 - }
2068 1635 }
2069 1636 }
2070 1637 return $key;
2071 1638 }
@@ -2130,9 +1697,9 @@
2130 1697 return false;
2131 1698 }
2132 1699
2133 1700 if ( empty( $post_values ) ) {
2134 - $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1701 + $post_values = wp_unslash( $_POST );
2135 1702 }
2136 1703
2137 1704 $values = array(
2138 1705 'id' => $record->id,
@@ -2150,11 +1717,11 @@
2150 1717 self::fill_form_opts( $record, $table, $post_values, $values );
2151 1718
2152 1719 self::prepare_field_arrays( $fields, $record, $values, array_merge( $args, compact( 'default', 'post_values' ) ) );
2153 1720
2154 - if ( $table === 'entries' ) {
1721 + if ( $table == 'entries' ) {
2155 1722 $values = FrmEntriesHelper::setup_edit_vars( $values, $record );
2156 - } elseif ( $table === 'forms' ) {
1723 + } elseif ( $table == 'forms' ) {
2157 1724 $values = FrmFormsHelper::setup_edit_vars( $values, $record, $post_values );
2158 1725 }
2159 1726
2160 1727 return $values;
@@ -2431,9 +1998,9 @@
2431 1998 *
2432 1999 * @return string $time_ago
2433 2000 */
2434 2001 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
2435 - if ( empty( $to ) && 0 !== $to ) {
2002 + if ( empty( $to ) ) {
2436 2003 $now = new DateTime();
2437 2004 } else {
2438 2005 $now = new DateTime( '@' . $to );
2439 2006 }
@@ -2684,9 +2251,8 @@
2684 2251 'reply_to' => __( 'If you would like a different reply to address than the "from" address, add a single address here. FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
2685 2252 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <[email protected]> or [email protected].', 'formidable' ),
2686 2253 /* translators: %1$s: Form name, %2$s: Date */
2687 2254 '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() ) ),
2688 - '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' ),
2689 2255 );
2690 2256
2691 2257 if ( ! isset( $tooltips[ $name ] ) ) {
2692 2258 return;
@@ -2713,12 +2279,8 @@
2713 2279 return;
2714 2280 }
2715 2281
2716 2282 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
2717 - if ( 'lite-reports' === $frm_action ) {
2718 - $frm_action = 'reports';
2719 - }
2720 -
2721 2283 if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
2722 2284 echo ' class="current_page"';
2723 2285 }
2724 2286 }
@@ -2775,15 +2337,12 @@
2775 2337 }
2776 2338 }
2777 2339
2778 2340 /**
2779 - * Check for either json or serialized data. This is temporary while transitioning
2341 + * Check for either json or serilized data. This is temporary while transitioning
2780 2342 * all data to json.
2781 2343 *
2782 2344 * @since 4.02.03
2783 - *
2784 - * @param array|string $value
2785 - * @return void
2786 2345 */
2787 2346 public static function unserialize_or_decode( &$value ) {
2788 2347 if ( is_array( $value ) ) {
2789 2348 return;
@@ -2789,9 +2348,9 @@
2789 2348 return;
2790 2349 }
2791 2350
2792 2351 if ( is_serialized( $value ) ) {
2793 - $value = self::maybe_unserialize_array( $value );
2352 + $value = maybe_unserialize( $value );
2794 2353 } else {
2795 2354 $value = self::maybe_json_decode( $value, false );
2796 2355 }
2797 2356 }
@@ -2796,44 +2355,13 @@
2796 2355 }
2797 2356 }
2798 2357
2799 2358 /**
2800 - * Safely unserialize an array if necessary.
2801 - * This function doesn't actually use unserialize. The string is parsed instead.
2802 - *
2803 - * @since 6.2
2804 - *
2805 - * @param mixed $value
2806 - * @return mixed
2807 - */
2808 - public static function maybe_unserialize_array( $value ) {
2809 - if ( ! is_string( $value ) ) {
2810 - return $value;
2811 - }
2812 -
2813 - // Since we only expect an array, skip anything that doesn't start with a:.
2814 - if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
2815 - return $value;
2816 - }
2817 -
2818 - $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
2819 - if ( is_array( $parsed ) ) {
2820 - $value = $parsed;
2821 - }
2822 -
2823 - return $value;
2824 - }
2825 -
2826 - /**
2827 2359 * Decode a JSON string.
2828 2360 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
2829 - *
2830 - * @param mixed $string
2831 - * @param bool $single_to_array
2832 - * @return mixed
2833 2361 */
2834 2362 public static function maybe_json_decode( $string, $single_to_array = true ) {
2835 - if ( is_array( $string ) || is_null( $string ) ) {
2363 + if ( is_array( $string ) ) {
2836 2364 return $string;
2837 2365 }
2838 2366
2839 2367 $new_string = json_decode( $string, true );
@@ -2851,36 +2379,8 @@
2851 2379 return $string;
2852 2380 }
2853 2381
2854 2382 /**
2855 - * @since 6.2.3
2856 - *
2857 - * @param string $value
2858 - * @return string
2859 - */
2860 - public static function maybe_utf8_encode( $value ) {
2861 - $from_format = 'ISO-8859-1';
2862 - $to_format = 'UTF-8';
2863 -
2864 - if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
2865 - if ( mb_check_encoding( $value, $from_format ) ) {
2866 - return mb_convert_encoding( $value, $to_format, $from_format );
2867 - }
2868 - return $value;
2869 - }
2870 -
2871 - if ( function_exists( 'iconv' ) ) {
2872 - $converted = iconv( $from_format, $to_format, $value );
2873 - // Value is false if $value is not ISO-8859-1.
2874 - if ( false !== $converted ) {
2875 - return $converted;
2876 - }
2877 - }
2878 -
2879 - return $value;
2880 - }
2881 -
2882 - /**
2883 2383 * Reformat the json serialized array in name => value array.
2884 2384 *
2885 2385 * @since 4.02.03
2886 2386 */
@@ -2946,17 +2446,14 @@
2946 2446 $version = self::plugin_version();
2947 2447 wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
2948 2448
2949 2449 $global_strings = array(
2950 - 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
2951 - 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
2952 - 'url' => self::plugin_url(),
2953 - 'app_url' => 'https://formidableforms.com/',
2954 - 'applicationsUrl' => admin_url( 'admin.php?page=formidable-applications' ),
2955 - 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ),
2956 - 'loading' => __( 'Loading&hellip;', 'formidable' ),
2957 - 'nonce' => wp_create_nonce( 'frm_ajax' ),
2958 - 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
2450 + 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
2451 + 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
2452 + 'url' => self::plugin_url(),
2453 + 'app_url' => 'https://formidableforms.com/',
2454 + 'loading' => __( 'Loading&hellip;', 'formidable' ),
2455 + 'nonce' => wp_create_nonce( 'frm_ajax' ),
2959 2456 );
2960 2457 wp_localize_script( 'formidable_admin_global', 'frmGlobal', $global_strings );
2961 2458
2962 2459 if ( $load ) {
@@ -2980,21 +2477,19 @@
2980 2477 $ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
2981 2478 $ajax_url = apply_filters( 'frm_ajax_url', $ajax_url );
2982 2479
2983 2480 $script_strings = array(
2984 - 'ajax_url' => $ajax_url,
2985 - 'images_url' => self::plugin_url() . '/images',
2986 - 'loading' => __( 'Loading&hellip;', 'formidable' ),
2987 - 'remove' => __( 'Remove', 'formidable' ),
2988 - 'offset' => apply_filters( 'frm_scroll_offset', 4 ),
2989 - 'nonce' => wp_create_nonce( 'frm_ajax' ),
2990 - 'id' => __( 'ID', 'formidable' ),
2991 - 'no_results' => __( 'No results match', 'formidable' ),
2992 - 'file_spam' => __( 'That file looks like Spam.', 'formidable' ),
2993 - 'calc_error' => __( 'There is an error in the calculation in the field with key', 'formidable' ),
2994 - 'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ),
2995 - 'focus_first_error' => self::should_focus_first_error(),
2996 - 'include_alert_role' => self::should_include_alert_role_on_field_errors(),
2481 + 'ajax_url' => $ajax_url,
2482 + 'images_url' => self::plugin_url() . '/images',
2483 + 'loading' => __( 'Loading&hellip;', 'formidable' ),
2484 + 'remove' => __( 'Remove', 'formidable' ),
2485 + 'offset' => apply_filters( 'frm_scroll_offset', 4 ),
2486 + 'nonce' => wp_create_nonce( 'frm_ajax' ),
2487 + 'id' => __( 'ID', 'formidable' ),
2488 + 'no_results' => __( 'No results match', 'formidable' ),
2489 + 'file_spam' => __( 'That file looks like Spam.', 'formidable' ),
2490 + 'calc_error' => __( 'There is an error in the calculation in the field with key', 'formidable' ),
2491 + 'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ),
2997 2492 );
2998 2493
2999 2494 $data = $wp_scripts->get_data( 'formidable', 'data' );
3000 2495 if ( empty( $data ) ) {
@@ -3006,10 +2501,10 @@
3006 2501 $admin_script_strings = array(
3007 2502 'desc' => __( '(Click to add description)', 'formidable' ),
3008 2503 'blank' => __( '(Blank)', 'formidable' ),
3009 2504 'no_label' => __( '(no label)', 'formidable' ),
3010 - 'saving' => '', // Deprecated in 6.0.
3011 - 'saved' => '', // Deprecated in 6.0.
2505 + 'saving' => esc_attr( __( 'Saving', 'formidable' ) ),
2506 + 'saved' => esc_attr( __( 'Saved', 'formidable' ) ),
3012 2507 'ok' => __( 'OK', 'formidable' ),
3013 2508 'cancel' => __( 'Cancel', 'formidable' ),
3014 2509 'default_label' => __( 'Default', 'formidable' ),
3015 2510 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3015,8 +2510,9 @@
3015 2510 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
3016 2511 'no_clear_default' => __( 'Do not clear default value when typing', 'formidable' ),
3017 2512 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3018 2513 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
2514 + 'caution' => __( 'Heads up', 'formidable' ),
3019 2515 'confirm' => __( 'Are you sure?', 'formidable' ),
3020 2516 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3021 2517 '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' ),
3022 2518 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
@@ -3032,9 +2528,9 @@
3032 2528 'import_complete' => __( 'Import Complete', 'formidable' ),
3033 2529 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
3034 2530 'no_save_warning' => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
3035 2531 'private_label' => __( 'Private', 'formidable' ),
3036 - 'jquery_ui_url' => '',
2532 + 'jquery_ui_url' => self::jquery_ui_base_url(),
3037 2533 'pro_url' => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '',
3038 2534 'no_licenses' => __( 'No new licenses were found', 'formidable' ),
3039 2535 'unmatched_parens' => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ),
3040 2536 'view_shortcodes' => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ),
@@ -3051,9 +2547,8 @@
3051 2547 'install' => __( 'Install', 'formidable' ),
3052 2548 'active' => __( 'Active', 'formidable' ),
3053 2549 'select_a_field' => __( 'Select a Field', 'formidable' ),
3054 2550 'no_items_found' => __( 'No items found.', 'formidable' ),
3055 - 'field_already_used' => __( 'Oops. You have already used that field.', 'formidable' ),
3056 2551 );
3057 2552 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3058 2553
3059 2554 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
@@ -3063,30 +2558,8 @@
3063 2558 }
3064 2559 }
3065 2560
3066 2561 /**
3067 - * Returns whether or not the first errored input should be auto-focused (default true).
3068 - *
3069 - * @since 5.2.05
3070 - *
3071 - * @return bool
3072 - */
3073 - private static function should_focus_first_error() {
3074 - return (bool) apply_filters( 'frm_focus_first_error', true );
3075 - }
3076 -
3077 - /**
3078 - * Returns whether or not field errors should include role="alert" (default true).
3079 - *
3080 - * @since 5.2.05
3081 - *
3082 - * @return bool
3083 - */
3084 - public static function should_include_alert_role_on_field_errors() {
3085 - return (bool) apply_filters( 'frm_include_alert_role_on_field_errors', true );
3086 - }
3087 -
3088 - /**
3089 2562 * Echo the message on the plugins listing page
3090 2563 *
3091 2564 * @since 1.07.10
3092 2565 *
@@ -3109,10 +2582,8 @@
3109 2582 /**
3110 2583 * If Pro is far outdated, show a message.
3111 2584 *
3112 2585 * @since 4.0.01
3113 - *
3114 - * @return void
3115 2586 */
3116 2587 public static function min_pro_version_notice( $min_version ) {
3117 2588 if ( ! self::is_formidable_admin() ) {
3118 2589 // Don't show admin-wide.
@@ -3128,9 +2599,9 @@
3128 2599
3129 2600 $pro_version = FrmProDb::$plug_version;
3130 2601 $expired = FrmAddonsController::is_license_expired();
3131 2602 ?>
3132 - <div class="frm-banner-alert frm_error_style frm_previous_install">
2603 + <div class="error frm_previous_install">
3133 2604 <?php
3134 2605 esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
3135 2606 if ( empty( $expired ) ) {
3136 2607 echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
@@ -3169,9 +2640,9 @@
3169 2640 }
3170 2641
3171 2642 foreach ( $message as $m ) {
3172 2643 ?>
3173 - <div class="frm-banner-alert frm_error_style frm_previous_install">
2644 + <div class="error frm_previous_install">
3174 2645 <?php echo esc_html( $m ); ?>
3175 2646 </div>
3176 2647 <?php
3177 2648 }
@@ -3176,25 +2647,17 @@
3176 2647 <?php
3177 2648 }
3178 2649 }
3179 2650
3180 - /**
3181 - * @param string $type
3182 - * @return array<string,string>
3183 - */
3184 2651 public static function locales( $type = 'date' ) {
3185 2652 $locales = array(
3186 2653 'en' => __( 'English', 'formidable' ),
3187 2654 'af' => __( 'Afrikaans', 'formidable' ),
3188 2655 'sq' => __( 'Albanian', 'formidable' ),
3189 - 'ar-DZ' => __( 'Algerian Arabic', 'formidable' ),
3190 - 'am' => __( 'Amharic', 'formidable' ),
3191 2656 'ar' => __( 'Arabic', 'formidable' ),
3192 2657 'hy' => __( 'Armenian', 'formidable' ),
3193 2658 'az' => __( 'Azerbaijani', 'formidable' ),
3194 2659 'eu' => __( 'Basque', 'formidable' ),
3195 - 'be' => __( 'Belarusian', 'formidable' ),
3196 - 'bn' => __( 'Bengali', 'formidable' ),
3197 2660 'bs' => __( 'Bosnian', 'formidable' ),
3198 2661 'bg' => __( 'Bulgarian', 'formidable' ),
3199 2662 'ca' => __( 'Catalan', 'formidable' ),
3200 2663 'zh-HK' => __( 'Chinese Hong Kong', 'formidable' ),
@@ -3213,15 +2676,12 @@
3213 2676 'fi' => __( 'Finnish', 'formidable' ),
3214 2677 'fr' => __( 'French', 'formidable' ),
3215 2678 'fr-CA' => __( 'French/Canadian', 'formidable' ),
3216 2679 'fr-CH' => __( 'French/Swiss', 'formidable' ),
3217 - 'gl' => __( 'Galician', 'formidable' ),
3218 - 'ka' => __( 'Georgian', 'formidable' ),
3219 2680 'de' => __( 'German', 'formidable' ),
3220 2681 'de-AT' => __( 'German/Austria', 'formidable' ),
3221 2682 'de-CH' => __( 'German/Switzerland', 'formidable' ),
3222 2683 'el' => __( 'Greek', 'formidable' ),
3223 - 'gu' => __( 'Gujarati', 'formidable' ),
3224 2684 'he' => __( 'Hebrew', 'formidable' ),
3225 2685 'iw' => __( 'Hebrew', 'formidable' ),
3226 2686 'hi' => __( 'Hindi', 'formidable' ),
3227 2687 'hu' => __( 'Hungarian', 'formidable' ),
@@ -3228,720 +2688,277 @@
3228 2688 'is' => __( 'Icelandic', 'formidable' ),
3229 2689 'id' => __( 'Indonesian', 'formidable' ),
3230 2690 'it' => __( 'Italian', 'formidable' ),
3231 2691 'ja' => __( 'Japanese', 'formidable' ),
3232 - 'kn' => __( 'Kannada', 'formidable' ),
3233 - 'kk' => __( 'Kazakh', 'formidable' ),
3234 - 'km' => __( 'Khmer', 'formidable' ),
3235 2692 'ko' => __( 'Korean', 'formidable' ),
3236 - 'ky' => __( 'Kyrgyz', 'formidable' ),
3237 - 'lo' => __( 'Laothian', 'formidable' ),
3238 2693 'lv' => __( 'Latvian', 'formidable' ),
3239 2694 'lt' => __( 'Lithuanian', 'formidable' ),
3240 - 'lb' => __( 'Luxembourgish', 'formidable' ),
3241 - 'mk' => __( 'Macedonian', 'formidable' ),
3242 - 'ml' => __( 'Malayalam', 'formidable' ),
3243 2695 'ms' => __( 'Malaysian', 'formidable' ),
3244 - 'mr' => __( 'Marathi', 'formidable' ),
3245 2696 'no' => __( 'Norwegian', 'formidable' ),
3246 - 'nb' => __( 'Norwegian Bokmål', 'formidable' ),
3247 - 'nn' => __( 'Norwegian Nynorsk', 'formidable' ),
3248 2697 'pl' => __( 'Polish', 'formidable' ),
3249 2698 'pt' => __( 'Portuguese', 'formidable' ),
3250 2699 'pt-BR' => __( 'Portuguese/Brazilian', 'formidable' ),
3251 2700 'pt-PT' => __( 'Portuguese/Portugal', 'formidable' ),
3252 - 'rm' => __( 'Romansh', 'formidable' ),
3253 2701 'ro' => __( 'Romanian', 'formidable' ),
3254 2702 'ru' => __( 'Russian', 'formidable' ),
3255 2703 'sr' => __( 'Serbian', 'formidable' ),
3256 2704 'sr-SR' => __( 'Serbian', 'formidable' ),
3257 - 'si' => __( 'Sinhalese', 'formidable' ),
3258 2705 'sk' => __( 'Slovak', 'formidable' ),
3259 2706 'sl' => __( 'Slovenian', 'formidable' ),
3260 2707 'es' => __( 'Spanish', 'formidable' ),
3261 2708 'es-419' => __( 'Spanish/Latin America', 'formidable' ),
3262 - 'sw' => __( 'Swahili', 'formidable' ),
3263 2709 'sv' => __( 'Swedish', 'formidable' ),
3264 2710 'ta' => __( 'Tamil', 'formidable' ),
3265 - 'te' => __( 'Telugu', 'formidable' ),
3266 2711 'th' => __( 'Thai', 'formidable' ),
3267 - 'tj' => __( 'Tajiki', 'formidable' ),
3268 2712 'tr' => __( 'Turkish', 'formidable' ),
3269 - 'uk' => __( 'Ukrainian', 'formidable' ),
3270 - 'ur' => __( 'Urdu', 'formidable' ),
2713 + 'uk' => __( 'Ukranian', 'formidable' ),
3271 2714 'vi' => __( 'Vietnamese', 'formidable' ),
3272 - 'cy-GB' => __( 'Welsh', 'formidable' ),
3273 - 'zu' => __( 'Zulu', 'formidable' ),
3274 2715 );
3275 2716
3276 2717 if ( $type === 'captcha' ) {
3277 2718 // remove the languages unavailable for the captcha
3278 - $unset = array( 'sq', 'bs', 'eo', 'fo', 'fr-CH', 'sr-SR', 'ar-DZ', 'be', 'cy-GB', 'kk', 'km', 'ky', 'lb', 'mk', 'nb', 'nn', 'rm', 'tj' );
2719 + $unset = array( 'af', 'sq', 'hy', 'az', 'eu', 'bs', 'zh-HK', 'eo', 'et', 'fo', 'fr-CH', 'he', 'is', 'ms', 'sr-SR', 'ta' );
3279 2720 } else {
3280 2721 // remove the languages unavailable for the datepicker
3281 - $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' );
2722 + $unset = array( 'fil', 'fr-CA', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419' );
3282 2723 }
3283 2724
3284 2725 $locales = array_diff_key( $locales, array_flip( $unset ) );
2726 + $locales = apply_filters( 'frm_locales', $locales );
3285 2727
3286 - /**
3287 - * Filter available locale options.
3288 - *
3289 - * @since 5.4.5 Added $args parameter with type.
3290 - *
3291 - * @param array<string,string> $locales
3292 - * @param array $args {
3293 - * @type string $type
3294 - * }
3295 - */
3296 - $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3297 -
3298 2728 return $locales;
3299 2729 }
3300 2730
3301 2731 /**
3302 2732 * Output HTML containing reference text for accessibility
3303 - *
3304 - * @deprecated 5.1
3305 2733 */
3306 2734 public static function multiselect_accessibility() {
3307 - _deprecated_function( __METHOD__, '5.1' );
2735 + include_once self::plugin_path() . '/classes/views/frm-forms/multiselect-accessibility.php';
3308 2736 }
3309 2737
3310 - public static function get_menu_icon_class() {
3311 - if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
3312 - $settings = FrmProAppHelper::get_settings();
3313 - if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
3314 - return $settings->menu_icon;
3315 - }
3316 - }
3317 - return 'frmfont frm_logo_icon';
3318 - }
3319 -
3320 2738 /**
3321 - * Shows the images dropdown.
3322 - *
3323 - * @since 5.0.04
3324 - *
3325 - * @param array $args {
3326 - * Arguments.
3327 - *
3328 - * @type string $selected Selected value.
3329 - * @type array[] $options Array of options with keys are option values and values are array.
3330 - * The option array contains `text`, `svg` and `custom_atts`.
3331 - * @type string $classes Custom CSS classes for the wrapper element.
3332 - * @type array $input_attrs Attributes of value input.
3333 - * }
2739 + * @since 4.07
2740 + * @deprecated 4.09.01
3334 2741 */
3335 - public static function images_dropdown( $args ) {
3336 - $args = self::fill_default_images_dropdown_args( $args );
3337 -
3338 - $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
3339 - ob_start();
3340 - include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
3341 - $output = ob_get_clean();
3342 -
3343 - /**
3344 - * Allows modifying the output of FrmAppHelper::images_dropdown() method.
3345 - *
3346 - * @since 5.0.04
3347 - *
3348 - * @param string $output The output.
3349 - * @param array $args Passed arguments.
3350 - */
3351 - echo apply_filters( 'frm_images_dropdown_output', $output, $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
3352 - }
3353 -
3354 - /**
3355 - * Fills the default images_dropdown() arguments.
3356 - *
3357 - * @since 5.0.04
3358 - *
3359 - * @param array $args The arguments.
3360 - * @return array
3361 - */
3362 - private static function fill_default_images_dropdown_args( $args ) {
3363 - $defaults = array(
3364 - 'selected' => '',
3365 - 'options' => array(),
3366 - 'classes' => '',
3367 - 'input_attrs' => array(),
3368 - );
3369 - $new_args = wp_parse_args( $args, $defaults );
3370 -
3371 - $new_args['options'] = (array) $new_args['options'];
3372 - $new_args['input_attrs'] = (array) $new_args['input_attrs'];
3373 -
3374 - // Set the number of columns.
3375 - $new_args['col_class'] = ceil( 12 / count( $new_args['options'] ) );
3376 - if ( $new_args['col_class'] > 6 ) {
3377 - $new_args['col_class'] = ceil( $new_args['col_class'] / 2 );
2742 + public static function renewal_message() {
2743 + if ( is_callable( 'FrmProAddonsController::renewal_message' ) ) {
2744 + FrmProAddonsController::renewal_message();
2745 + return;
3378 2746 }
3379 2747
3380 - /**
3381 - * Allows modifying the arguments of images_dropdown() method.
3382 - *
3383 - * @since 5.0.04
3384 - *
3385 - * @param array $new_args Arguments after filling the defaults.
3386 - * @param array $args Arguments passed to the method, before filling the defaults.
3387 - */
3388 - return apply_filters( 'frm_images_dropdown_args', $new_args, $args );
3389 - }
3390 -
3391 - /**
3392 - * Gets HTML attributes of the input in images_dropdown() method.
3393 - *
3394 - * @since 5.0.04
3395 - *
3396 - * @param array $args The arguments.
3397 - * @return string
3398 - */
3399 - private static function get_images_dropdown_input_attrs( $args ) {
3400 - $input_attrs = $args['input_attrs'];
3401 - $input_attrs['type'] = 'radio';
3402 - $input_attrs['name'] = $args['name'];
3403 -
3404 - $input_attrs_str = '';
3405 - foreach ( $input_attrs as $key => $input_attr ) {
3406 - $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
2748 + if ( ! FrmAddonsController::is_license_expired() ) {
2749 + return;
3407 2750 }
3408 2751
3409 - /**
3410 - * Allows modifying the HTML attributes of the input in images_dropdown() method.
3411 - *
3412 - * @since 5.0.04
3413 - *
3414 - * @param string $input_attrs_str HTML attributes string.
3415 - * @param array $args The arguments of images_dropdown() method.
3416 - */
3417 - return apply_filters( 'frm_images_dropdown_input_attrs', $input_attrs_str, $args );
2752 + ?>
2753 + <div class="frm_error_style" style="text-align:left">
2754 + <?php self::icon_by_class( 'frmfont frm_alert_icon' ); ?>
2755 + &nbsp;
2756 + <?php esc_html_e( 'Your account has expired', 'formidable' ); ?>
2757 + <div style="float:right">
2758 + <a href="<?php echo esc_url( self::admin_upgrade_link( 'form-expired', 'account/downloads/' ) ); ?>">
2759 + <?php esc_html_e( 'Renew Now', 'formidable' ); ?>
2760 + </a>
2761 + </div>
2762 + </div>
2763 + <?php
3418 2764 }
3419 2765
3420 2766 /**
3421 - * Gets the image of each option in images_dropdown() method.
3422 - *
3423 - * @since 5.0.04
3424 - *
3425 - * @param array $option Option data.
3426 - * @param array $args The arguments of images_dropdown() method.
3427 - * @return string
2767 + * @since 4.08
2768 + * @deprecated 4.09.01
3428 2769 */
3429 - private static function get_images_dropdown_option_image( $option, $args ) {
3430 - $image = self::icon_by_class(
3431 - 'frmfont ' . $option['svg'],
3432 - array(
3433 - 'echo' => false,
3434 - )
3435 - );
3436 -
3437 - $args['option'] = $option;
3438 -
3439 - /**
3440 - * Allows modifying the image of each option in images_dropdown() method.
3441 - *
3442 - * @since 5.0.04
3443 - *
3444 - * @param string $image The image HTML.
3445 - * @param array $args The arguments of images_dropdown() method, with `option` array is added.
3446 - */
3447 - return apply_filters( 'frm_images_dropdown_option_image', $image, $args );
3448 - }
3449 -
3450 - /**
3451 - * Gets the HTML classes of each option in images_dropdown() method.
3452 - *
3453 - * @since 5.0.04
3454 - *
3455 - * @param array $option Option data.
3456 - * @param array $args The arguments of images_dropdown() method.
3457 - * @return string
3458 - */
3459 - private static function get_images_dropdown_option_classes( $option, $args ) {
3460 - $classes = '';
3461 -
3462 - if ( ! empty( $option['custom_attrs']['class'] ) ) {
3463 - $classes .= ' ' . $option['custom_attrs']['class'];
2770 + public static function expiring_message() {
2771 + _deprecated_function( __METHOD__, '4.09.01', 'FrmProAddonsController::expiring_message' );
2772 + if ( is_callable( 'FrmProAddonsController::expiring_message' ) ) {
2773 + FrmProAddonsController::expiring_message();
3464 2774 }
3465 -
3466 - $args['option'] = $option;
3467 -
3468 - /**
3469 - * Allows modifying the CSS classes of each option in images_dropdown() method.
3470 - *
3471 - * @since 5.0.04
3472 - *
3473 - * @param string $classes CSS classes.
3474 - * @param array $args The arguments of images_dropdown() method, with `option` array is added.
3475 - */
3476 - return apply_filters( 'frm_images_dropdown_option_classes', $classes, $args );
3477 2775 }
3478 2776
3479 2777 /**
3480 - * Gets the custom HTML attributes of each option in images_dropdown() method.
2778 + * Use the WP 4.7 wp_doing_ajax function
3481 2779 *
3482 - * @since 5.0.04
3483 - *
3484 - * @param array $option Option data.
3485 - * @param array $args The arguments of images_dropdown() method.
3486 - * @return string
2780 + * @since 2.05.07
2781 + * @deprecated 4.04.04
3487 2782 */
3488 - private static function get_images_dropdown_option_html_attrs( $option, $args ) {
3489 - $html_attrs = '';
3490 - if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
3491 - $html_attrs_arr = array();
3492 -
3493 - foreach ( $option['custom_attrs'] as $key => $value ) {
3494 - if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
3495 - continue;
3496 - }
3497 -
3498 - $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
3499 - }
3500 -
3501 - $html_attrs = implode( ' ', $html_attrs_arr );
3502 - }
3503 -
3504 - $args['option'] = $option;
3505 -
3506 - /**
3507 - * Allows modifying the custom HTML attributes of each option in images_dropdown() method.
3508 - *
3509 - * @since 5.0.04
3510 - *
3511 - * @param string $html_attrs The HTML attributes string.
3512 - * @param array $args The arguments of images_dropdown() method, with `option` array is added.
3513 - */
3514 - return apply_filters( 'frm_images_dropdown_option_html_attrs', $html_attrs, $args );
2783 + public static function wp_doing_ajax() {
2784 + _deprecated_function( __METHOD__, '4.04.04', 'wp_doing_ajax' );
2785 + return wp_doing_ajax();
3515 2786 }
3516 2787
3517 2788 /**
3518 - * @since 5.0.07
3519 - *
3520 - * @return bool true if the current user is allowed to save unfiltered HTML.
2789 + * @deprecated 4.0
3521 2790 */
3522 - public static function allow_unfiltered_html() {
3523 - if ( self::should_never_allow_unfiltered_html() ) {
3524 - return false;
3525 - }
3526 - return current_user_can( 'unfiltered_html' );
2791 + public static function insert_opt_html( $args ) {
2792 + _deprecated_function( __METHOD__, '4.0', 'FrmFormsHelper::insert_opt_html' );
2793 + FrmFormsHelper::insert_opt_html( $args );
3527 2794 }
3528 2795
3529 2796 /**
3530 - * @since 5.0.13
2797 + * Used to filter shortcode in text widgets
3531 2798 *
3532 - * @return bool
2799 + * @deprecated 2.5.4
2800 + * @codeCoverageIgnore
3533 2801 */
3534 - public static function should_never_allow_unfiltered_html() {
3535 - if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) {
3536 - return true;
3537 - }
3538 -
3539 - /**
3540 - * Formidable will check DISALLOW_UNFILTERED_HTML to determine if some form HTML should be filtered or not.
3541 - * In many cases, scripts are added intentionally to forms and will not be stripped if DISALLOW_UNFILTERED_HTML is not set.
3542 - * It is also possible to filter Formidable without defining DISALLOW_UNFILTERED_HTML, with add_filter( 'frm_disallow_unfiltered_html', '__return_true' );
3543 - *
3544 - * @since 5.0.13
3545 - */
3546 - return apply_filters( 'frm_disallow_unfiltered_html', false );
2802 + public static function widget_text_filter_callback( $matches ) {
2803 + return FrmDeprecated::widget_text_filter_callback( $matches );
3547 2804 }
3548 2805
3549 2806 /**
3550 - * @since 5.0.07
3551 - *
3552 - * @param array $values
3553 - * @param array $keys
3554 - * @return array
2807 + * @deprecated 3.01
2808 + * @codeCoverageIgnore
3555 2809 */
3556 - public static function maybe_filter_array( $values, $keys ) {
3557 - $allow_unfiltered_html = self::allow_unfiltered_html();
3558 -
3559 - if ( $allow_unfiltered_html ) {
3560 - return $values;
3561 - }
3562 -
3563 - foreach ( $keys as $key ) {
3564 - if ( isset( $values[ $key ] ) ) {
3565 - $values[ $key ] = self::kses( $values[ $key ], 'all' );
3566 - }
3567 - }
3568 -
3569 - return $values;
2810 + public static function sanitize_array( &$values ) {
2811 + FrmDeprecated::sanitize_array( $values );
3570 2812 }
3571 2813
3572 2814 /**
3573 - * Some back end fields allow privleged users to add scripts.
3574 - * A site that uses the DISALLOW_UNFILTERED_HTML always remove scripts on echo.
2815 + * @param array $settings
2816 + * @param string $group
3575 2817 *
3576 - * @since 5.0.13
3577 - *
3578 - * @param string $value
3579 - * @param array|string $allowed 'all' for everything included as defaults
3580 - * @return string
2818 + * @since 2.0.6
2819 + * @deprecated 2.05.06
2820 + * @codeCoverageIgnore
3581 2821 */
3582 - public static function maybe_kses( $value, $allowed = 'all' ) {
3583 - if ( self::should_never_allow_unfiltered_html() ) {
3584 - $value = self::kses( $value, $allowed );
3585 - }
3586 - return $value;
2822 + public static function save_settings( $settings, $group ) {
2823 + return FrmDeprecated::save_settings( $settings, $group );
3587 2824 }
3588 2825
3589 2826 /**
3590 - * @since 5.0.16
3591 - *
3592 - * @return bool
2827 + * @since 2.0.4
2828 + * @deprecated 2.05.06
2829 + * @codeCoverageIgnore
3593 2830 */
3594 - public static function show_landing_pages() {
3595 - return self::show_new_feature( 'landing' );
2831 + public static function save_json_post( $settings ) {
2832 + return FrmDeprecated::save_json_post( $settings );
3596 2833 }
3597 2834
3598 2835 /**
3599 - * @since 5.0.16
2836 + * @since 2.0
2837 + * @deprecated 2.05.06
2838 + * @codeCoverageIgnore
3600 2839 *
3601 - * @return array
3602 - */
3603 - public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
3604 - $params = array(
3605 - 'medium' => $medium,
3606 - 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
3607 - 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
3608 - 'screenshot' => 'landing.png',
3609 - );
3610 - return self::get_upgrade_data_params( 'landing', $params );
3611 - }
3612 -
3613 - /**
3614 - * @since 5.0.17
2840 + * @param string $cache_key The unique name for this cache
2841 + * @param string $group The name of the cache group
2842 + * @param string $query If blank, don't run a db call
2843 + * @param string $type The wpdb function to use with this query
3615 2844 *
3616 - * @param string $plugin
3617 - * @return string|false
2845 + * @return mixed $results The cache or query results
3618 2846 */
3619 - private static function get_plan_required( $plugin ) {
3620 - $link = FrmAddonsController::install_link( $plugin );
3621 - return FrmFormsHelper::get_plan_required( $link );
2847 + public static function check_cache( $cache_key, $group = '', $query = '', $type = 'get_var', $time = 300 ) {
2848 + return FrmDeprecated::check_cache( $cache_key, $group, $query, $type, $time );
3622 2849 }
3623 2850
3624 2851 /**
3625 - * @since 5.0.17
3626 - *
3627 - * @param string
3628 - * @return bool
2852 + * @deprecated 2.05.06
2853 + * @codeCoverageIgnore
3629 2854 */
3630 - public static function show_new_feature( $feature ) {
3631 - $link = FrmAddonsController::install_link( $feature );
3632 - return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
2855 + public static function set_cache( $cache_key, $results, $group = '', $time = 300 ) {
2856 + return FrmDeprecated::set_cache( $cache_key, $results, $group, $time );
3633 2857 }
3634 2858
3635 2859 /**
3636 - * @since 5.0.17
3637 - *
3638 - * @param string $plugin
3639 - * @param array $params
3640 - * @return array
2860 + * @deprecated 2.05.06
2861 + * @codeCoverageIgnore
3641 2862 */
3642 - public static function get_upgrade_data_params( $plugin, $params ) {
3643 - $link = FrmAddonsController::install_link( $plugin );
3644 - if ( ! $link ) {
3645 - return $params;
3646 - }
3647 -
3648 - if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
3649 - $params['oneclick'] = json_encode( $link );
3650 - unset( $params['message'] );
3651 - if ( ! isset( $params['medium'] ) ) {
3652 - $params['medium'] = $plugin;
3653 - }
3654 - } else {
3655 - $params['requires'] = FrmFormsHelper::get_plan_required( $link );
3656 - }
3657 -
3658 - return $params;
2863 + public static function add_key_to_group_cache( $key, $group ) {
2864 + FrmDeprecated::add_key_to_group_cache( $key, $group );
3659 2865 }
3660 2866
3661 2867 /**
3662 - * Returns true if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f], false otherwise.
3663 - * Not every server installs the ctype extension, so use a fallback if the function does not exist.
3664 - *
3665 - * @since 5.0.17
3666 - *
3667 - * @param string $text
3668 - * @return bool
2868 + * @deprecated 2.05.06
2869 + * @codeCoverageIgnore
3669 2870 */
3670 - public static function ctype_xdigit( $text ) {
3671 - if ( function_exists( 'ctype_xdigit' ) ) {
3672 - return ctype_xdigit( $text );
3673 - }
3674 - return is_string( $text ) && '' !== $text && ! preg_match( '/[^A-Fa-f0-9]/', $text );
2871 + public static function get_group_cached_keys( $group ) {
2872 + return FrmDeprecated::get_group_cached_keys( $group );
3675 2873 }
3676 2874
3677 2875 /**
3678 - * Set the current screen to avoid undefined notices.
3679 - *
3680 - * @since 5.2.01
2876 + * @since 2.0
2877 + * @deprecated 2.05.06
2878 + * @codeCoverageIgnore
2879 + * @return mixed The cached value or false
3681 2880 */
3682 - public static function set_current_screen_and_hook_suffix() {
3683 - global $hook_suffix;
3684 - if ( is_null( $hook_suffix ) ) {
3685 - // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
3686 - $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
3687 - }
3688 - set_current_screen();
2881 + public static function check_cache_and_transient( $cache_key ) {
2882 + return FrmDeprecated::check_cache( $cache_key );
3689 2883 }
3690 2884
3691 2885 /**
3692 - * Shows pill text.
2886 + * @since 2.0
2887 + * @deprecated 2.05.06
2888 + * @codeCoverageIgnore
3693 2889 *
3694 - * @since 5.2.02
3695 - *
3696 - * @param string $text Text in the pill. Default is NEW.
2890 + * @param string $cache_key
3697 2891 */
3698 - public static function show_pill_text( $text = null ) {
3699 - if ( null === $text ) {
3700 - $text = __( 'NEW', 'formidable' );
3701 - }
3702 - echo '<span class="frm-new-pill">' . esc_html( $text ) . '</span>';
2892 + public static function delete_cache_and_transient( $cache_key, $group = 'default' ) {
2893 + FrmDeprecated::delete_cache_and_transient( $cache_key, $group );
3703 2894 }
3704 2895
3705 2896 /**
3706 - * Count the number of decimals digits.
2897 + * @since 2.0
2898 + * @deprecated 2.05.06
2899 + * @codeCoverageIgnore
3707 2900 *
3708 - * @since 5.2.07
3709 - *
3710 - * @param mixed $num Number.
3711 - * @return int|false Returns `false` if the passed parameter is not number.
2901 + * @param string $group The name of the cache group
3712 2902 */
3713 - public static function count_decimals( $num ) {
3714 - if ( ! is_numeric( $num ) ) {
3715 - return false;
3716 - }
3717 -
3718 - $num = (string) $num;
3719 - $parts = explode( '.', $num );
3720 - if ( 1 === count( $parts ) ) {
3721 - return 0;
3722 - }
3723 -
3724 - return strlen( $parts[ count( $parts ) - 1 ] );
2903 + public static function cache_delete_group( $group ) {
2904 + FrmDeprecated::cache_delete_group( $group );
3725 2905 }
3726 2906
3727 2907 /**
3728 - * Prevent a fatal error in PHP8 if gmt_offset happens to be set an empty string.
3729 - * This is a bug in WordPress. It isn't safe to call current_time( 'timestamp' ) without this with an empty string offset.
3730 - * In the future this might be safe to remove. Keep an eye on the current_time function in functions.php.
2908 + * @since 1.07.10
2909 + * @deprecated 2.05.06
2910 + * @codeCoverageIgnore
3731 2911 *
3732 - * @since 5.3.1
2912 + * @param string $term The value to escape
3733 2913 *
3734 - * @return void
2914 + * @return string The escaped value
3735 2915 */
3736 - public static function filter_gmt_offset() {
3737 - if ( self::$added_gmt_offset_filter ) {
3738 - // Avoid adding twice.
3739 - return;
3740 - }
3741 -
3742 - add_filter(
3743 - 'option_gmt_offset',
3744 - function( $offset ) {
3745 - if ( ! is_string( $offset ) || is_numeric( $offset ) ) {
3746 - // Leave a valid value alone.
3747 - return $offset;
3748 - }
3749 -
3750 - return 0;
3751 - }
3752 - );
3753 - self::$added_gmt_offset_filter = true;
2916 + public static function esc_like( $term ) {
2917 + return FrmDeprecated::esc_like( $term );
3754 2918 }
3755 2919
3756 2920 /**
3757 - * @since 5.3.1
2921 + * @param string $order_query
3758 2922 *
3759 - * @return bool
2923 + * @deprecated 2.05.06
2924 + * @codeCoverageIgnore
3760 2925 */
3761 - public static function on_form_listing_page() {
3762 - if ( ! self::is_admin_page( 'formidable' ) ) {
3763 - return false;
3764 - }
3765 -
3766 - $action = self::simple_get( 'frm_action', 'sanitize_title' );
3767 - return ! $action || in_array( $action, self::get_form_listing_page_actions(), true );
2926 + public static function esc_order( $order_query ) {
2927 + return FrmDeprecated::esc_order( $order_query );
3768 2928 }
3769 2929
3770 2930 /**
3771 - * Get all actions that also display the forms list.
3772 - *
3773 - * @since 5.3.1
3774 - *
3775 - * @return array<string>
2931 + * @deprecated 2.05.06
2932 + * @codeCoverageIgnore
3776 2933 */
3777 - private static function get_form_listing_page_actions() {
3778 - return array( 'list', 'trash', 'untrash', 'destroy' );
2934 + public static function esc_order_by( &$order_by ) {
2935 + FrmDeprecated::esc_order_by( $order_by );
3779 2936 }
3780 2937
3781 2938 /**
3782 - * Safely call get_plugins, importing the required files if they are not yet loaded.
2939 + * @param string $limit
3783 2940 *
3784 - * @since 5.5
3785 - *
3786 - * @return array
3787 - */
3788 - public static function get_plugins() {
3789 - if ( ! function_exists( 'get_plugins' ) ) {
3790 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
3791 - }
3792 - return get_plugins();
3793 - }
3794 -
3795 - /**
3796 - * Make sure that the file we're trying to load is in fact the expected file type, and that it's coming from our S3 bucket.
3797 - * This is to make sure that the URL can't be exploited for a SSRF attack.
3798 - *
3799 - * @since 5.5.5
3800 - *
3801 - * @param string $url
3802 - * @param string $expected_extension
3803 - * @return bool
3804 - */
3805 - public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
3806 - $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
3807 - if ( ! $file_is_in_expected_s3_bucket ) {
3808 - return false;
3809 - }
3810 -
3811 - $parsed = parse_url( $url );
3812 - if ( ! is_array( $parsed ) ) {
3813 - // URL is malformed.
3814 - return false;
3815 - }
3816 -
3817 - $path = $parsed['path'];
3818 - $ext = pathinfo( $path, PATHINFO_EXTENSION );
3819 - if ( $expected_extension !== $ext ) {
3820 - // The URL isn't to an XML file.
3821 - return false;
3822 - }
3823 -
3824 - return true;
3825 - }
3826 -
3827 - /**
3828 - * @since 4.08
3829 - * @deprecated 4.09.01
3830 - */
3831 - public static function expiring_message() {
3832 - _deprecated_function( __METHOD__, '4.09.01', 'FrmProAddonsController::expiring_message' );
3833 - if ( is_callable( 'FrmProAddonsController::expiring_message' ) ) {
3834 - FrmProAddonsController::expiring_message();
3835 - }
3836 - }
3837 -
3838 - /**
3839 - * Use the WP 4.7 wp_doing_ajax function
3840 - *
3841 - * @since 2.05.07
3842 - * @deprecated 4.04.04
3843 - */
3844 - public static function wp_doing_ajax() {
3845 - _deprecated_function( __METHOD__, '4.04.04', 'wp_doing_ajax' );
3846 - return wp_doing_ajax();
3847 - }
3848 -
3849 - /**
3850 - * @deprecated 4.0
3851 - */
3852 - public static function insert_opt_html( $args ) {
3853 - _deprecated_function( __METHOD__, '4.0', 'FrmFormsHelper::insert_opt_html' );
3854 - FrmFormsHelper::insert_opt_html( $args );
3855 - }
3856 -
3857 - /**
3858 - * @deprecated 3.01
2941 + * @deprecated 2.05.06
3859 2942 * @codeCoverageIgnore
3860 2943 */
3861 - public static function sanitize_array( &$values ) {
3862 - FrmDeprecated::sanitize_array( $values );
2944 + public static function esc_limit( $limit ) {
2945 + return FrmDeprecated::esc_limit( $limit );
3863 2946 }
3864 2947
3865 2948 /**
3866 2949 * @since 2.0
3867 - * @deprecated 5.0.13
3868 - *
3869 - * @return string The base Google APIS url for the current version of jQuery UI
2950 + * @deprecated 2.05.06
2951 + * @codeCoverageIgnore
3870 2952 */
3871 - public static function jquery_ui_base_url() {
3872 - _deprecated_function( __FUNCTION__, '5.0.13', 'FrmProAppHelper::jquery_ui_base_url' );
3873 - return is_callable( 'FrmProAppHelper::jquery_ui_base_url' ) ? FrmProAppHelper::jquery_ui_base_url() : '';
2953 + public static function prepare_array_values( $array, $type = '%s' ) {
2954 + return FrmDeprecated::prepare_array_values( $array, $type );
3874 2955 }
3875 2956
3876 2957 /**
3877 - * @since 4.07
3878 - * @deprecated 6.0
2958 + * @deprecated 2.05.06
2959 + * @codeCoverageIgnore
3879 2960 */
3880 - public static function renewal_message() {
3881 - _deprecated_function( __METHOD__, '6.0', 'FrmProAddonsController::renewal_message' );
3882 - }
3883 -
3884 - /**
3885 - * Display a dismissable warning message and save its dismissal state.
3886 - *
3887 - * @since 6.3
3888 - *
3889 - * @param string $message The warning message to display.
3890 - * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
3891 - * @return void
3892 - */
3893 - public static function add_dismissable_warning_message( $message = '', $option = '' ) {
3894 - if ( ! $message || ! $option ) {
3895 - return;
3896 - }
3897 -
3898 - $ajax_callback = function() use ( $option ) {
3899 - self::dismiss_warning_message( $option );
3900 - };
3901 -
3902 - // We're handling JS codes with `doJsonPost` and it adds 'frm_' to the beginning of the action.
3903 - // To prevent any issues, we add 'frm_' from the beginning of the action.
3904 - add_action( 'wp_ajax_frm_' . $option, $ajax_callback );
3905 -
3906 - add_filter(
3907 - 'frm_message_list',
3908 - function( $show_messages ) use ( $message, $option ) {
3909 - if ( get_option( $option, false ) ) {
3910 - return $show_messages;
3911 - }
3912 -
3913 - $dismiss_icon = self::icon_by_class(
3914 - 'frmfont frm_close_icon',
3915 - array(
3916 - 'aria-label' => _x( 'Dismiss', 'warning message: close icon label', 'formidable' ),
3917 - 'echo' => false,
3918 - )
3919 - );
3920 -
3921 - $show_messages[] = $message;
3922 - $show_messages[] = '<span class="frm-warning-dismiss frmsvg" data-action="' . esc_attr( $option ) . '">' . $dismiss_icon . '</span>';
3923 -
3924 - return $show_messages;
3925 - }
3926 - );
3927 - }
3928 -
3929 - /**
3930 - * Dismiss a warning message and update the dismissal state.
3931 - *
3932 - * @since 6.3
3933 - *
3934 - * @param string $option The unique identifier for the dismissal state of the message.
3935 - * @return void
3936 - */
3937 - public static function dismiss_warning_message( $option = '' ) {
3938 - self::permission_check( 'frm_change_settings' );
3939 - check_ajax_referer( 'frm_ajax', 'nonce' );
3940 -
3941 - if ( $option ) {
3942 - update_option( $option, true, 'no' );
3943 - }
3944 -
3945 - wp_send_json_success();
2961 + public static function prepend_and_or_where( $starts_with = ' WHERE ', $where = '' ) {
2962 + return FrmDeprecated::prepend_and_or_where( $starts_with, $where );
3946 2963 }
3947 2964 }