PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.20
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.20
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 +428 -1103 6.306.20 View file →
@@ -9,9 +9,9 @@
9 9 * Version of the database we are moving to.
10 10 *
11 11 * @var int
12 12 */
13 - public static $db_version = 105;
13 + public static $db_version = 103;
14 14
15 15 /**
16 16 * Used by the API add-on.
17 17 *
@@ -28,9 +28,9 @@
28 28 * @since 2.0
29 29 *
30 30 * @var string
31 31 */
32 - public static $plug_version = '6.30';
32 + public static $plug_version = '6.20';
33 33
34 34 /**
35 35 * @var bool
36 36 */
@@ -55,9 +55,9 @@
55 55 /**
56 56 * @return string
57 57 */
58 58 public static function plugin_path() {
59 - return dirname( __DIR__, 2 );
59 + return dirname( dirname( __DIR__ ) );
60 60 }
61 61
62 62 /**
63 63 * @return string
@@ -85,9 +85,8 @@
85 85 * Get the name of this site
86 86 * Used for [sitename] shortcode
87 87 *
88 88 * @since 2.0
89 - *
90 89 * @return string
91 90 */
92 91 public static function site_name() {
93 92 return get_option( 'blogname' );
@@ -94,15 +93,13 @@
94 93 }
95 94
96 95 /**
97 96 * @param string $url
98 - *
99 97 * @return string
100 98 */
101 99 public static function make_affiliate_url( $url ) {
102 100 $affiliate_id = self::get_affiliate();
103 -
104 - if ( $affiliate_id ) {
101 + if ( ! empty( $affiliate_id ) ) {
105 102 $url = str_replace( array( 'http://', 'https://' ), '', $url );
106 103 $url = 'http://www.shareasale.com/r.cfm?u=' . absint( $affiliate_id ) . '&b=841990&m=64739&afftrack=plugin&urllink=' . urlencode( $url );
107 104 }
108 105
@@ -117,167 +114,65 @@
117 114 }
118 115
119 116 /**
120 117 * @since 3.04.02
121 - *
122 - * @param array|string $args If a string is passed, it is used for the utm_campaign attribute.
118 + * @param array|string $args
123 119 * @param string $page
124 120 */
125 121 public static function admin_upgrade_link( $args, $page = '' ) {
126 - if ( $page ) {
122 + if ( empty( $page ) ) {
123 + $page = 'https://formidableforms.com/lite-upgrade/';
124 + } else {
127 125 $page = str_replace( 'https://formidableforms.com/', '', $page );
128 126 $page = 'https://formidableforms.com/' . $page;
127 + }
128 +
129 + $anchor = '';
130 + if ( is_array( $args ) ) {
131 + $medium = $args['medium'];
132 + if ( isset( $args['content'] ) ) {
133 + $content = $args['content'];
134 + }
135 + if ( isset( $args['anchor'] ) ) {
136 + $anchor = '#' . $args['anchor'];
137 + }
129 138 } else {
130 - $page = 'https://formidableforms.com/lite-upgrade/';
139 + $medium = $args;
131 140 }
132 141
133 - $args = is_array( $args ) ? self::adjust_legacy_utm_args( $args ) : array( 'campaign' => $args );
134 -
135 142 $query_args = array(
136 - 'utm_source' => 'plugin',
137 - 'utm_medium' => self::get_utm_medium(),
143 + 'utm_source' => 'WordPress',
144 + 'utm_medium' => $medium,
145 + 'utm_campaign' => 'liteplugin',
138 146 );
139 - $query_args = self::maybe_add_utm_license( $query_args );
140 147
141 - if ( isset( $args['campaign'] ) ) {
142 - $query_args['utm_campaign'] = $args['campaign'];
148 + if ( isset( $content ) ) {
149 + $query_args['utm_content'] = $content;
143 150 }
144 151
145 - if ( isset( $args['content'] ) ) {
146 - $query_args['utm_content'] = $args['content'];
147 - }
148 -
149 - if ( isset( $args['param'] ) ) {
152 + if ( is_array( $args ) && isset( $args['param'] ) ) {
150 153 $query_args['f'] = $args['param'];
151 154 }
152 155
153 - if ( ! empty( $args['plan'] ) ) {
156 + if ( is_array( $args ) && ! empty( $args['plan'] ) ) {
154 157 $query_args['plan'] = $args['plan'];
155 158 }
156 159
157 - $link = add_query_arg( $query_args, $page );
158 -
159 - if ( isset( $args['anchor'] ) ) {
160 - $link .= '#' . $args['anchor'];
161 - }
162 -
160 + $link = add_query_arg( $query_args, $page ) . $anchor;
163 161 return self::make_affiliate_url( $link );
164 162 }
165 163
166 164 /**
167 - * If medium is "pro", add an additional utm_license param with their active license type.
168 - *
169 - * @since 6.25.1
170 - *
171 - * @param array $query_args
172 - * @param string $link
173 - *
174 - * @return array
175 - */
176 - private static function maybe_add_utm_license( $query_args, $link = '' ) {
177 - $medium = $query_args['utm_medium'] ?? self::pull_medium_from_link( $link );
178 -
179 - if ( 'pro' === $medium && is_callable( 'FrmProAddonsController::get_readable_license_type' ) ) {
180 - $query_args['utm_license'] = strtolower( FrmProAddonsController::get_readable_license_type() );
181 - }
182 -
183 - return $query_args;
184 - }
185 -
186 - /**
187 - * @since 6.26
188 - *
189 - * @param string $link
190 - *
191 - * @return string
192 - */
193 - private static function pull_medium_from_link( $link ) {
194 - if ( ! $link ) {
195 - return '';
196 - }
197 -
198 - $parsed = parse_url( $link );
199 -
200 - if ( ! is_array( $parsed ) || ! isset( $parsed['query'] ) ) {
201 - return '';
202 - }
203 -
204 - $query_args = wp_parse_args( $parsed['query'] );
205 -
206 - return ! empty( $query_args['utm_medium'] ) ? $query_args['utm_medium'] : '';
207 - }
208 -
209 - /**
210 - * @since 6.25.1
211 - *
212 - * @return string
213 - */
214 - private static function get_utm_medium() {
215 - return self::pro_is_connected() ? 'pro' : 'lite';
216 - }
217 -
218 - /**
219 - * Change campaign from "liteplugin" to what we're currently using for medium.
220 - *
221 - * @since 6.25.1
222 - *
223 - * @param array $args
224 - *
225 - * @return array
226 - */
227 - private static function adjust_legacy_utm_args( $args ) {
228 - if ( isset( $args['medium'] ) ) {
229 - $args['campaign'] = $args['medium'];
230 - unset( $args['medium'] );
231 - }
232 -
233 - return $args;
234 - }
235 -
236 - /**
237 - * @since 6.21
238 - *
239 - * @param string $cta_link
240 - * @param array $utm
241 - */
242 - public static function maybe_add_missing_utm( $cta_link, $utm ) {
243 - $utm = self::adjust_legacy_utm_args( $utm );
244 - $query_args = array();
245 -
246 - if ( ! str_contains( $cta_link, 'utm_source' ) ) {
247 - $query_args['utm_source'] = 'plugin';
248 - }
249 -
250 - if ( ! str_contains( $cta_link, 'utm_medium' ) ) {
251 - $query_args['utm_medium'] = self::get_utm_medium();
252 - }
253 -
254 - if ( ! str_contains( $cta_link, 'utm_campaign' ) && isset( $utm['campaign'] ) ) {
255 - $query_args['utm_campaign'] = $utm['campaign'];
256 - }
257 -
258 - if ( ! str_contains( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) {
259 - $query_args['utm_content'] = $utm['content'];
260 - }
261 -
262 - $query_args = self::maybe_add_utm_license( $query_args, $cta_link );
263 -
264 - return $query_args ? add_query_arg( $query_args, $cta_link ) : $cta_link;
265 - }
266 -
267 - /**
268 165 * Get the Formidable settings
269 166 *
270 167 * @since 2.0
271 168 *
272 169 * @param array $args - May include the form id when values need translation.
273 - *
274 - * @return FrmSettings
170 + * @return FrmSettings $frm_settings
275 171 */
276 172 public static function get_settings( $args = array() ) {
277 173 global $frm_settings;
278 -
279 - if ( ! $frm_settings ) {
174 + if ( empty( $frm_settings ) ) {
280 175 $frm_settings = new FrmSettings( $args );
281 176 } elseif ( isset( $args['current_form'] ) ) {
282 177 // If the global has already been set, allow strings to be filtered.
283 178 $frm_settings->maybe_filter_for_form( $args );
@@ -289,13 +184,11 @@
289 184 /**
290 185 * @return string
291 186 */
292 187 public static function get_menu_name() {
293 - if ( ! self::pro_is_installed() || FrmAddonsController::is_license_expired() ) {
294 - return 'Formidable';
295 - }
188 + $frm_settings = self::get_settings();
296 189
297 - return self::get_settings()->menu;
190 + return FrmAddonsController::is_license_expired() ? 'Formidable' : $frm_settings->menu;
298 191 }
299 192
300 193 /**
301 194 * Determine if the current branding is set to 'formidable'.
@@ -309,9 +202,10 @@
309 202 if ( ! self::pro_is_installed() ) {
310 203 return true;
311 204 }
312 205
313 - return str_contains( self::get_menu_icon_class(), 'frm_logo_icon' );
206 + $menu_icon = self::get_menu_icon_class();
207 + return strpos( $menu_icon, 'frm_logo_icon' ) !== false;
314 208 }
315 209
316 210 /**
317 211 * @since 3.05
@@ -316,9 +210,8 @@
316 210 /**
317 211 * @since 3.05
318 212 *
319 213 * @param array $atts
320 - *
321 214 * @return string
322 215 */
323 216 public static function svg_logo( $atts = array() ) {
324 217 $defaults = array(
@@ -328,14 +221,12 @@
328 221 'orange' => '#f05a24',
329 222 );
330 223 $atts = array_merge( $defaults, $atts );
331 224
332 - // phpcs:disable SlevomatCodingStandard.Files.LineLength.LineTooLong
333 225 return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 599.68 601.37" width="' . esc_attr( $atts['width'] ) . '" height="' . esc_attr( $atts['height'] ) . '">
334 226 <path fill="' . esc_attr( $atts['orange'] ) . '" d="M289.6 384h140v76h-140z"/>
335 227 <path fill="' . esc_attr( $atts['fill'] ) . '" d="M400.2 147h-200c-17 0-30.6 12.2-30.6 29.3V218h260v-71zM397.9 264H169.6v196h75V340H398a32.2 32.2 0 0 0 30.1-21.4 24.3 24.3 0 0 0 1.7-8.7V264zM299.8 601.4A300.3 300.3 0 0 1 0 300.7a299.8 299.8 0 1 1 511.9 212.6 297.4 297.4 0 0 1-212 88zm0-563A262 262 0 0 0 38.3 300.7a261.6 261.6 0 1 0 446.5-185.5 259.5 259.5 0 0 0-185-76.8z"/>
336 228 </svg>';
337 - // phpcs:enable SlevomatCodingStandard.Files.LineLength.LineTooLong
338 229 }
339 230
340 231 /**
341 232 * @since 4.0
@@ -340,13 +231,12 @@
340 231 /**
341 232 * @since 4.0
342 233 *
343 234 * @param array $atts
344 - *
345 235 * @return void
346 236 */
347 237 public static function show_logo( $atts = array() ) {
348 - self::kses_echo( self::svg_logo( $atts ), 'all' );
238 + echo self::kses( self::svg_logo( $atts ), 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
349 239 }
350 240
351 241 /**
352 242 * @since 4.03.02
@@ -361,11 +251,10 @@
361 251 )
362 252 );
363 253
364 254 $new_icon = apply_filters( 'frm_icon', $icon, true );
365 -
366 255 if ( $new_icon !== $icon ) {
367 - if ( str_starts_with( $new_icon, '<svg' ) ) {
256 + if ( strpos( $new_icon, '<svg' ) === 0 ) {
368 257 $icon = str_replace( 'viewBox="0 0 20', 'width="30" height="35" style="color:#929699" viewBox="0 0 20', $new_icon );
369 258 } else {
370 259 // Show nothing if it isn't an SVG.
371 260 $icon = '<div style="height:39px"></div>';
@@ -370,9 +259,9 @@
370 259 // Show nothing if it isn't an SVG.
371 260 $icon = '<div style="height:39px"></div>';
372 261 }
373 262 }
374 - self::kses_echo( $icon, 'all' );
263 + echo self::kses( $icon, 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
375 264 }
376 265
377 266 /**
378 267 * @since 2.02.04
@@ -422,13 +311,11 @@
422 311 */
423 312 public static function is_form_builder_page( $check_for_settings = true ) {
424 313 $action = self::simple_get( 'frm_action', 'sanitize_title' );
425 314 $check_actions = array( 'edit', 'duplicate' );
426 -
427 315 if ( $check_for_settings ) {
428 316 $check_actions[] = 'settings';
429 317 }
430 -
431 318 return self::is_admin_page( 'formidable' ) && in_array( $action, $check_actions, true );
432 319 }
433 320
434 321 /**
@@ -434,15 +321,15 @@
434 321 /**
435 322 * @return bool
436 323 */
437 324 public static function is_formidable_admin() {
438 - $page = self::simple_get( 'page', 'sanitize_title' );
439 -
440 - if ( ! $page ) {
441 - return self::is_view_builder_page();
325 + $page = self::simple_get( 'page', 'sanitize_title' );
326 + $is_formidable = strpos( $page, 'formidable' ) !== false;
327 + if ( empty( $page ) ) {
328 + $is_formidable = self::is_view_builder_page();
442 329 }
443 330
444 - return str_contains( $page, 'formidable' );
331 + return $is_formidable;
445 332 }
446 333
447 334 /**
448 335 * Checks if is a list page.
@@ -449,9 +336,8 @@
449 336 *
450 337 * @since 6.19
451 338 *
452 339 * @param string $page The name of the page to check.
453 - *
454 340 * @return bool
455 341 */
456 342 public static function is_admin_list_page( $page = 'formidable' ) {
457 343 if ( 'formidable' === $page ) {
@@ -463,9 +349,8 @@
463 349 }
464 350
465 351 if ( 'formidable-entries' === $page ) {
466 352 $action = self::simple_get( 'frm_action' );
467 -
468 353 if ( ! $action || in_array( $action, self::get_entries_listing_page_form_actions(), true ) ) {
469 354 return true;
470 355 }
471 356 }
@@ -494,13 +379,11 @@
494 379 */
495 380 public static function is_admin_page( $page = 'formidable' ) {
496 381 global $pagenow;
497 382 $get_page = self::simple_get( 'page', 'sanitize_title' );
498 -
499 383 if ( $pagenow ) {
500 - // Allow this to be true during ajax load i.e. ajax form builder loading
384 + // allow this to be true during ajax load i.e. ajax form builder loading
501 385 $is_page = ( $pagenow === 'admin.php' || $pagenow === 'admin-ajax.php' ) && $get_page === $page;
502 -
503 386 if ( $is_page ) {
504 387 return true;
505 388 }
506 389 }
@@ -518,15 +401,15 @@
518 401 */
519 402 public static function is_view_builder_page() {
520 403 global $pagenow;
521 404
522 - if ( ! in_array( $pagenow, array( 'post.php', 'post-new.php', 'edit.php' ), true ) ) {
405 + if ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' && $pagenow !== 'edit.php' ) {
523 406 return false;
524 407 }
525 408
526 409 $post_type = self::simple_get( 'post_type', 'sanitize_title' );
527 410
528 - if ( ! $post_type ) {
411 + if ( empty( $post_type ) ) {
529 412 $post_id = self::simple_get( 'post', 'absint' );
530 413 $post = get_post( $post_id );
531 414 $post_type = $post ? $post->post_type : '';
532 415 }
@@ -544,9 +427,9 @@
544 427 public static function is_preview_page() {
545 428 global $pagenow;
546 429 $action = self::simple_get( 'action', 'sanitize_title' );
547 430
548 - return $pagenow === 'admin-ajax.php' && $action === 'frm_forms_preview';
431 + return $pagenow && $pagenow === 'admin-ajax.php' && $action === 'frm_forms_preview';
549 432 }
550 433
551 434 /**
552 435 * Check for ajax except the form preview page
@@ -567,9 +450,8 @@
567 450 }
568 451
569 452 /**
570 453 * @since 2.0.8
571 - *
572 454 * @return bool
573 455 */
574 456 public static function prevent_caching() {
575 457 global $frm_vars;
@@ -587,9 +469,8 @@
587 469 $is_admin = is_admin() && ! wp_doing_ajax();
588 470
589 471 /**
590 472 * @since 6.0
591 - *
592 473 * @param bool $is_admin
593 474 */
594 475 return apply_filters( 'frm_is_admin', $is_admin );
595 476 }
@@ -604,15 +485,14 @@
604 485 *
605 486 * @return bool
606 487 */
607 488 public static function is_empty_value( $value, $empty = '' ) {
608 - return $value === array() || $value === $empty;
489 + return ( is_array( $value ) && empty( $value ) ) || $value === $empty;
609 490 }
610 491
611 492 /**
612 493 * @param mixed $value
613 494 * @param string $empty
614 - *
615 495 * @return bool
616 496 */
617 497 public static function is_not_empty_value( $value, $empty = '' ) {
618 498 return ! self::is_empty_value( $value, $empty );
@@ -666,9 +546,8 @@
666 546 continue;
667 547 }
668 548
669 549 $key = self::get_server_value( $key );
670 -
671 550 foreach ( explode( ',', $key ) as $ip ) {
672 551 // Just to be safe.
673 552 $ip = trim( $ip );
674 553
@@ -724,26 +603,16 @@
724 603 */
725 604 return apply_filters( 'frm_use_custom_header_ip', $should_use_custom_header_ip );
726 605 }
727 606
728 - /**
729 - * @param string $param
730 - * @param mixed $default
731 - * @param string $src
732 - * @param callable|string $sanitize
733 - *
734 - * @return mixed
735 - */
736 607 public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
737 - if ( str_contains( $param, '[' ) ) {
608 + if ( strpos( $param, '[' ) ) {
738 609 $params = explode( '[', $param );
739 610 $param = $params[0];
740 611 }
741 612
742 613 if ( $src === 'get' ) {
743 - // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
744 - $value = isset( $_POST[ $param ] ) ? wp_unslash( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? wp_unslash( $_GET[ $param ] ) : $default );
745 -
614 + $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
746 615 if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
747 616 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
748 617 $value = htmlspecialchars_decode( wp_unslash( $_GET[ $param ] ) );
749 618 }
@@ -758,19 +627,17 @@
758 627 )
759 628 );
760 629 }
761 630
762 - if ( ! isset( $params ) || ! is_array( $value ) || ! $value ) {
763 - return $value;
764 - }
631 + if ( isset( $params ) && is_array( $value ) && ! empty( $value ) ) {
632 + foreach ( $params as $k => $p ) {
633 + if ( ! $k || ! is_array( $value ) ) {
634 + continue;
635 + }
765 636
766 - foreach ( $params as $k => $p ) {
767 - if ( ! $k || ! is_array( $value ) ) {
768 - continue;
637 + $p = trim( $p, ']' );
638 + $value = isset( $value[ $p ] ) ? $value[ $p ] : $default;
769 639 }
770 -
771 - $p = trim( $p, ']' );
772 - $value = $value[ $p ] ?? $default;
773 640 }
774 641
775 642 return $value;
776 643 }
@@ -781,9 +648,8 @@
781 648 * @param string $param The key we are trying to access data from in $_POST.
782 649 * @param mixed $default The default if nothing is being sent.
783 650 * @param callable|string $sanitize Make sure to pass a sanitize method here. This function will NOT sanitize by default.
784 651 * @param bool $serialized
785 - *
786 652 * @return mixed
787 653 */
788 654 public static function get_post_param( $param, $default = '', $sanitize = '', $serialized = false ) {
789 655 return self::get_simple_request(
@@ -803,9 +669,9 @@
803 669 * @param string $param
804 670 * @param string $sanitize
805 671 * @param string $default
806 672 *
807 - * @return array|int|string
673 + * @return array|string
808 674 */
809 675 public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) {
810 676 return self::get_simple_request(
811 677 array(
@@ -834,10 +700,10 @@
834 700 'sanitize' => 'sanitize_text_field',
835 701 'serialized' => false,
836 702 );
837 703 $args = wp_parse_args( $args, $defaults );
838 - $value = $args['default'];
839 704
705 + $value = $args['default'];
840 706 if ( $args['type'] === 'get' ) {
841 707 if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
842 708 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
843 709 $value = wp_unslash( $_GET[ $args['param'] ] );
@@ -845,16 +711,16 @@
845 711 } elseif ( $args['type'] === 'post' ) {
846 712 if ( isset( $_POST[ $args['param'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
847 713 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
848 714 $value = wp_unslash( $_POST[ $args['param'] ] );
849 -
850 715 if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) {
851 716 self::unserialize_or_decode( $value );
852 717 }
853 718 }
854 719 } elseif ( isset( $_REQUEST[ $args['param'] ] ) ) {
855 - // phpcs:ignore phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
856 - $value = wp_unslash( $_REQUEST[ $args['param'] ] );
720 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
721 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
722 + $value = wp_unslash( $_REQUEST[ $args['param'] ] );
857 723 }
858 724
859 725 self::sanitize_value( $args['sanitize'], $value );
860 726
@@ -867,13 +733,17 @@
867 733 * @since 2.0.8
868 734 *
869 735 * @param string $value
870 736 *
871 - * @return string Value.
737 + * @return string $value
872 738 */
873 739 public static function preserve_backslashes( $value ) {
874 740 // If backslashes have already been added, don't add them again
875 - return str_contains( $value, '\\\\' ) ? $value : addslashes( $value );
741 + if ( strpos( $value, '\\\\' ) === false ) {
742 + $value = addslashes( $value );
743 + }
744 +
745 + return $value;
876 746 }
877 747
878 748 /**
879 749 * Sanitize a value in-place.
@@ -880,9 +750,8 @@
880 750 * If $value is an array, the sanitize function will get called for each item.
881 751 *
882 752 * @param callable $sanitize
883 753 * @param mixed $value
884 - *
885 754 * @return void
886 755 */
887 756 public static function sanitize_value( $sanitize, &$value ) {
888 757 if ( ! $sanitize ) {
@@ -895,13 +764,11 @@
895 764 }
896 765
897 766 if ( is_array( $value ) ) {
898 767 $temp_values = $value;
899 -
900 768 foreach ( $temp_values as $k => $v ) {
901 769 self::sanitize_value( $sanitize, $value[ $k ] );
902 770 }
903 -
904 771 return;
905 772 }
906 773
907 774 $value = call_user_func( $sanitize, $value );
@@ -906,17 +773,10 @@
906 773
907 774 $value = call_user_func( $sanitize, $value );
908 775 }
909 776
910 - /**
911 - * @param array $sanitize_method
912 - * @param array $values
913 - *
914 - * @return void
915 - */
916 777 public static function sanitize_request( $sanitize_method, &$values ) {
917 778 $temp_values = $values;
918 -
919 779 foreach ( $temp_values as $k => $val ) {
920 780 if ( isset( $sanitize_method[ $k ] ) ) {
921 781 $values[ $k ] = call_user_func( $sanitize_method[ $k ], $val );
922 782 }
@@ -926,9 +786,8 @@
926 786 /**
927 787 * @since 4.0.04
928 788 *
929 789 * @param mixed $value
930 - *
931 790 * @return void
932 791 */
933 792 public static function sanitize_with_html( &$value ) {
934 793 if ( current_user_can( 'frm_edit_entries' ) || current_user_can( 'administrator' ) ) {
@@ -947,12 +806,8 @@
947 806 *
948 807 * @param string $value
949 808 */
950 809 public static function strip_most_html( $value ) {
951 - if ( '' === $value ) {
952 - return $value;
953 - }
954 -
955 810 $allowed_html = array(
956 811 'b' => array(),
957 812 'br' => array(),
958 813 'strong' => array(),
@@ -977,15 +832,12 @@
977 832 * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&amp;'
978 833 * this MUST be done, else we'll be back to the '& entity' problem.
979 834 *
980 835 * @since 4.0.04
981 - *
982 - * @param mixed $value Value to decode, passed by reference.
983 836 */
984 837 public static function decode_specialchars( &$value ) {
985 838 if ( is_array( $value ) ) {
986 839 $temp_values = $value;
987 -
988 840 foreach ( $temp_values as $k => $v ) {
989 841 self::decode_specialchars( $value[ $k ] );
990 842 }
991 843 } else {
@@ -999,13 +851,13 @@
999 851 * Adapted from wp_specialchars_decode().
1000 852 *
1001 853 * @since 4.03.01
1002 854 *
1003 - * @param string $string The string to prep, passed by reference.
855 + * @param string $string The string to prep.
1004 856 */
1005 857 private static function decode_amp( &$string ) {
1006 858 // Don't bother if there are no entities - saves a lot of processing
1007 - if ( ! $string || ! str_contains( $string, '&' ) ) {
859 + if ( empty( $string ) || strpos( $string, '&' ) === false ) {
1008 860 return;
1009 861 }
1010 862
1011 863 $translation = array(
@@ -1043,15 +895,17 @@
1043 895 * Sanitize the value, and allow some HTML
1044 896 *
1045 897 * @since 2.0
1046 898 *
1047 - * @param string $value The value to sanitize.
1048 - * @param array|string $allowed Allowed HTML tags and attributes, or 'all' for defaults.
899 + * @param string $value
900 + * @param array|string $allowed 'all' for everything included as defaults.
1049 901 *
1050 902 * @return string
1051 903 */
1052 904 public static function kses( $value, $allowed = array() ) {
1053 - return wp_kses( $value, self::allowed_html( $allowed ) );
905 + $allowed_html = self::allowed_html( $allowed );
906 +
907 + return wp_kses( $value, $allowed_html );
1054 908 }
1055 909
1056 910 /**
1057 911 * Sanitizes and echoes a given value.
@@ -1059,9 +913,8 @@
1059 913 * @since 6.18
1060 914 *
1061 915 * @param string $value The value to sanitize and output.
1062 916 * @param array|string $allowed Allowed HTML tags and attributes.
1063 - *
1064 917 * @return void
1065 918 */
1066 919 public static function kses_echo( $value, $allowed = array() ) {
1067 920 echo self::kses( $value, $allowed ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -1072,23 +925,21 @@
1072 925 *
1073 926 * @since 5.0.13
1074 927 *
1075 928 * @param string $html
1076 - *
1077 929 * @return string
1078 930 */
1079 931 public static function kses_submit_button( $html ) {
1080 - $included_button_action = str_contains( $html, '[button_action]' );
1081 - $included_back_hook = str_contains( $html, '[back_hook]' );
1082 - $included_draft_hook = str_contains( $html, '[draft_hook]' );
932 + $included_button_action = false !== strpos( $html, '[button_action]' );
933 + $included_back_hook = false !== strpos( $html, '[back_hook]' );
934 + $included_draft_hook = false !== strpos( $html, '[draft_hook]' );
1083 935 add_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1084 936 add_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1085 937 $html = self::kses( $html, 'all' );
1086 938 remove_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1087 939 remove_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1088 -
1089 940 if ( $included_button_action ) {
1090 - if ( str_contains( $html, '<input type="submit"' ) ) {
941 + if ( false !== strpos( $html, '<input type="submit"' ) ) {
1091 942 $pattern = '/(<input type="submit")([^>]*)(\/>)/';
1092 943 $html = preg_replace( $pattern, '$1$2[button_action] $3', $html, 1 );
1093 944 } else {
1094 945 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
@@ -1094,17 +945,14 @@
1094 945 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
1095 946 $html = preg_replace( $pattern, '$1$2$3$4$5$6$7 [button_action]$8$9$10', $html, 1 );
1096 947 }
1097 948 }
1098 -
1099 949 if ( $included_back_hook ) {
1100 950 $html = str_replace( 'class="frm_prev_page"', 'class="frm_prev_page" [back_hook]', $html );
1101 951 }
1102 -
1103 952 if ( $included_draft_hook ) {
1104 - return str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html );
953 + $html = str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html );
1105 954 }
1106 -
1107 955 return $html;
1108 956 }
1109 957
1110 958 /**
@@ -1110,9 +958,8 @@
1110 958 /**
1111 959 * @since 5.0.13
1112 960 *
1113 961 * @param array $allowed_attr
1114 - *
1115 962 * @return array
1116 963 */
1117 964 public static function allow_visibility_style( $allowed_attr ) {
1118 965 $allowed_attr[] = 'visibility';
@@ -1122,9 +969,8 @@
1122 969 /**
1123 970 * @since 5.0.13
1124 971 *
1125 972 * @param array $allowed_html
1126 - *
1127 973 * @return array
1128 974 */
1129 975 public static function add_allowed_submit_button_tags( $allowed_html ) {
1130 976 $allowed_html['input'] = array(
@@ -1141,22 +987,17 @@
1141 987 }
1142 988
1143 989 /**
1144 990 * @since 2.05.03
1145 - *
1146 - * @param array|string $allowed
1147 - *
1148 - * @return array
1149 991 */
1150 992 private static function allowed_html( $allowed ) {
1151 993 $html = self::safe_html();
1152 994 $allowed_html = array();
1153 -
1154 995 if ( $allowed === 'all' ) {
1155 996 $allowed_html = $html;
1156 - } elseif ( $allowed ) {
997 + } elseif ( ! empty( $allowed ) ) {
1157 998 foreach ( (array) $allowed as $a ) {
1158 - $allowed_html[ $a ] = $html[ $a ] ?? array();
999 + $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
1159 1000 }
1160 1001 }
1161 1002
1162 1003 return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
@@ -1163,10 +1004,8 @@
1163 1004 }
1164 1005
1165 1006 /**
1166 1007 * @since 2.05.03
1167 - *
1168 - * @return array
1169 1008 */
1170 1009 private static function safe_html() {
1171 1010 $allow_class = array(
1172 1011 'class' => true,
@@ -1318,16 +1157,14 @@
1318 1157 return;
1319 1158 }
1320 1159
1321 1160 $action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' );
1322 -
1323 - if ( ! $action_name ) {
1161 + if ( empty( $action_name ) ) {
1324 1162 return;
1325 1163 }
1326 1164
1327 1165 $new_action = self::get_param( $action_name, '', 'get', 'sanitize_text_field' );
1328 -
1329 - if ( $new_action ) {
1166 + if ( ! empty( $new_action ) ) {
1330 1167 $_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', self::get_server_value( 'REQUEST_URI' ) );
1331 1168 }
1332 1169 }
1333 1170
@@ -1334,23 +1171,21 @@
1334 1171 /**
1335 1172 * Check the WP query for a parameter
1336 1173 *
1337 1174 * @since 2.0
1338 - *
1339 - * @param array|string $value
1340 - * @param string $param
1341 - *
1342 1175 * @return array|string
1343 1176 */
1344 1177 public static function get_query_var( $value, $param ) {
1345 - // phpcs:ignore Universal.Operators.StrictComparisons
1346 1178 if ( $value != '' ) {
1347 1179 return $value;
1348 1180 }
1349 1181
1350 1182 global $wp_query;
1183 + if ( isset( $wp_query->query_vars[ $param ] ) ) {
1184 + $value = $wp_query->query_vars[ $param ];
1185 + }
1351 1186
1352 - return $wp_query->query_vars[ $param ] ?? $value;
1187 + return $value;
1353 1188 }
1354 1189
1355 1190 /**
1356 1191 * Try to show the SVG if possible. Otherwise, use the font icon.
@@ -1358,21 +1193,20 @@
1358 1193 * @since 4.0.02
1359 1194 *
1360 1195 * @param string $class
1361 1196 * @param array $atts
1362 - *
1363 1197 * @return string|null
1364 1198 */
1365 1199 public static function icon_by_class( $class, $atts = array() ) {
1366 1200 $echo = ! isset( $atts['echo'] ) || $atts['echo'];
1367 -
1368 1201 if ( isset( $atts['echo'] ) ) {
1369 1202 unset( $atts['echo'] );
1370 1203 }
1371 1204
1372 1205 $html_atts = self::array_to_html_params( $atts );
1373 - $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1374 1206
1207 + $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1208 +
1375 1209 // Replace icons that have been removed or renamed.
1376 1210 $deprecated = array(
1377 1211 'frm_clone_solid_icon' => 'frm_clone_icon',
1378 1212 'frm_keyalt_icon' => 'frm_key_icon',
@@ -1377,9 +1211,8 @@
1377 1211 'frm_clone_solid_icon' => 'frm_clone_icon',
1378 1212 'frm_keyalt_icon' => 'frm_key_icon',
1379 1213 'frm_keyalt_solid_icon' => 'frm_key_solid_icon',
1380 1214 );
1381 -
1382 1215 if ( isset( $deprecated[ $icon ] ) ) {
1383 1216 $icon = $deprecated[ $icon ];
1384 1217 $class = str_replace( $icon, $deprecated[ $icon ], $class );
1385 1218 }
@@ -1386,24 +1219,21 @@
1386 1219
1387 1220 if ( $icon === $class ) {
1388 1221 $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
1389 1222 } else {
1390 - $class = str_contains( $icon, ' ' ) ? ' ' . $icon : '';
1391 -
1392 - if ( str_contains( $icon, ' ' ) ) {
1223 + $class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
1224 + if ( strpos( $icon, ' ' ) ) {
1393 1225 $icon = explode( ' ', $icon );
1394 1226 $icon = reset( $icon );
1395 1227 }
1396 -
1397 - $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use href="#' . esc_attr( $icon ) . '" /></svg>';
1228 + $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use xlink:href="#' . esc_attr( $icon ) . '" /></svg>';
1398 1229 }
1399 1230
1400 1231 if ( $echo ) {
1401 1232 echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1402 - return null;
1233 + } else {
1234 + return $icon;
1403 1235 }
1404 -
1405 - return $icon;
1406 1236 }
1407 1237
1408 1238 /**
1409 1239 * Run kses for icons. It needs to add a few filters first in order to preserve some custom style values.
@@ -1410,9 +1240,8 @@
1410 1240 *
1411 1241 * @since 5.0.13
1412 1242 *
1413 1243 * @param string $icon
1414 - *
1415 1244 * @return string
1416 1245 */
1417 1246 public static function kses_icon( $icon ) {
1418 1247 add_filter( 'safe_style_css', 'FrmAppHelper::allow_vars_in_styles' );
@@ -1428,15 +1257,13 @@
1428 1257 /**
1429 1258 * @since 5.0.13.1
1430 1259 *
1431 1260 * @param array $allowed_html
1432 - *
1433 1261 * @return array
1434 1262 */
1435 1263 public static function add_allowed_icon_tags( $allowed_html ) {
1436 1264 $allowed_html['svg']['data-open'] = true;
1437 1265 $allowed_html['svg']['title'] = true;
1438 - $allowed_html['svg']['tabindex'] = true;
1439 1266 return $allowed_html;
1440 1267 }
1441 1268
1442 1269 /**
@@ -1442,9 +1269,8 @@
1442 1269 /**
1443 1270 * @since 5.0.13
1444 1271 *
1445 1272 * @param array $allowed_attr
1446 - *
1447 1273 * @return array
1448 1274 */
1449 1275 public static function allow_vars_in_styles( $allowed_attr ) {
1450 1276 $allowed_attr[] = '--primary-700';
@@ -1457,9 +1283,9 @@
1457 1283 * @param bool $allow_css
1458 1284 * @param string $css_string
1459 1285 */
1460 1286 public static function allow_style( $allow_css, $css_string ) {
1461 - if ( ! $allow_css && str_starts_with( $css_string, '--primary-700:' ) ) {
1287 + if ( ! $allow_css && 0 === strpos( $css_string, '--primary-700:' ) ) {
1462 1288 $split = explode( ':', $css_string, 2 );
1463 1289 $allow_css = 2 === count( $split ) && self::is_a_valid_color( $split[1] );
1464 1290 }
1465 1291 return $allow_css;
@@ -1468,22 +1294,19 @@
1468 1294 /**
1469 1295 * @since 5.0.13
1470 1296 *
1471 1297 * @param string $value
1472 - *
1473 1298 * @return bool
1474 1299 */
1475 1300 private static function is_a_valid_color( $value ) {
1476 1301 $match = 0;
1477 -
1478 - if ( str_starts_with( $value, 'rgba(' ) ) {
1302 + if ( 0 === strpos( $value, 'rgba(' ) ) {
1479 1303 $match = preg_match( '/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/', $value );
1480 - } elseif ( str_starts_with( $value, 'rgb(' ) ) {
1304 + } elseif ( 0 === strpos( $value, 'rgb(' ) ) {
1481 1305 $match = preg_match( '/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/', $value );
1482 - } elseif ( str_starts_with( $value, '#' ) ) {
1306 + } elseif ( 0 === strpos( $value, '#' ) ) {
1483 1307 $match = preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})\b$/', $value );
1484 1308 }
1485 -
1486 1309 return (bool) $match;
1487 1310 }
1488 1311
1489 1312 /**
@@ -1489,9 +1312,8 @@
1489 1312 /**
1490 1313 * Include svg images.
1491 1314 *
1492 1315 * @since 4.0.02
1493 - *
1494 1316 * @return void
1495 1317 */
1496 1318 public static function include_svg() {
1497 1319 if ( self::$included_svg ) {
@@ -1510,20 +1332,17 @@
1510 1332 * @since 5.0.13 added $echo parameter.
1511 1333 *
1512 1334 * @param array $atts
1513 1335 * @param bool $echo
1514 - *
1515 1336 * @return string|void
1516 1337 */
1517 1338 public static function array_to_html_params( $atts, $echo = false ) {
1518 1339 $callback = function () use ( $atts ) {
1519 - if ( ! $atts ) {
1520 - return;
1340 + if ( $atts ) {
1341 + foreach ( $atts as $key => $value ) {
1342 + echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1343 + }
1521 1344 }
1522 -
1523 - foreach ( $atts as $key => $value ) {
1524 - echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1525 - }
1526 1345 };
1527 1346 return self::clip( $callback, $echo );
1528 1347 }
1529 1348
@@ -1533,9 +1352,8 @@
1533 1352 * @since 5.0.13
1534 1353 *
1535 1354 * @param Closure $echo_function
1536 1355 * @param bool $echo
1537 - *
1538 1356 * @return string|null
1539 1357 */
1540 1358 public static function clip( $echo_function, $echo = false ) {
1541 1359 if ( ! $echo ) {
@@ -1545,9 +1363,13 @@
1545 1363 if ( is_callable( $echo_function ) ) {
1546 1364 $echo_function();
1547 1365 }
1548 1366
1549 - return $echo ? null : ob_get_clean();
1367 + if ( ! $echo ) {
1368 + $return = ob_get_contents();
1369 + ob_end_clean();
1370 + return $return;
1371 + }
1550 1372 }
1551 1373
1552 1374 /**
1553 1375 * @since 3.0
@@ -1552,18 +1374,15 @@
1552 1374 /**
1553 1375 * @since 3.0
1554 1376 *
1555 1377 * @param array $atts
1556 - *
1557 1378 * @return void
1558 1379 */
1559 1380 public static function get_admin_header( $atts ) {
1560 1381 $has_nav = ! empty( $atts['form'] ) && empty( $atts['is_template'] );
1561 -
1562 1382 if ( empty( $atts['close'] ) ) {
1563 1383 $atts['close'] = admin_url( 'admin.php?page=formidable' );
1564 1384 }
1565 -
1566 1385 if ( ! isset( $atts['import_link'] ) ) {
1567 1386 $atts['import_link'] = false;
1568 1387 }
1569 1388
@@ -1573,19 +1392,16 @@
1573 1392 /**
1574 1393 * @since 6.0
1575 1394 *
1576 1395 * @param string $type
1577 - *
1578 1396 * @return void
1579 1397 */
1580 1398 public static function import_link( $type = 'secondary' ) {
1581 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1582 1399 ?>
1583 1400 <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">
1584 1401 <?php esc_html_e( 'Import', 'formidable' ); ?>
1585 1402 </a>
1586 1403 <?php
1587 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1588 1404 }
1589 1405
1590 1406 /**
1591 1407 * Print applicable admin banner.
@@ -1592,9 +1408,8 @@
1592 1408 *
1593 1409 * @since 5.4.2
1594 1410 *
1595 1411 * @param bool $should_show_lite_upgrade
1596 - *
1597 1412 * @return void
1598 1413 */
1599 1414 public static function print_admin_banner( $should_show_lite_upgrade ) {
1600 1415 if ( ! current_user_can( 'administrator' ) ) {
@@ -1601,32 +1416,32 @@
1601 1416 FrmInbox::maybe_show_banner();
1602 1417 return;
1603 1418 }
1604 1419
1605 - if ( FrmSalesApi::maybe_show_banner() || self::maybe_show_license_warning() || FrmInbox::maybe_show_banner() || ! $should_show_lite_upgrade || self::pro_is_installed() ) {
1420 + if ( self::maybe_show_license_warning() || FrmInbox::maybe_show_banner() || ! $should_show_lite_upgrade || self::pro_is_installed() ) {
1606 1421 // Print license warning or inbox banner and exit if either prints.
1607 1422 // And exit before printing the upgrade bar if it shouldn't be shown.
1608 1423 return;
1609 1424 }
1610 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1611 1425 ?>
1612 1426 <div class="frm-upgrade-bar">
1613 1427 <div class="frm-upgrade-bar-inner">
1614 1428 <?php
1615 1429 $cta_text = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_text' );
1616 -
1617 1430 if ( ! $cta_text ) {
1618 1431 $cta_text = __( 'upgrading to PRO', 'formidable' );
1619 1432 }
1620 1433
1621 1434 $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' );
1622 - $utm = array(
1623 - 'campaign' => 'settings-license',
1624 - 'content' => 'lite-banner',
1625 - );
1435 + if ( ! $upgrade_link ) {
1436 + $upgrade_link = self::admin_upgrade_link(
1437 + array(
1438 + 'medium' => 'settings-license',
1439 + 'content' => 'lite-banner',
1440 + )
1441 + );
1442 + }
1626 1443
1627 - $upgrade_link = $upgrade_link ? self::maybe_add_missing_utm( $upgrade_link, $utm ) : self::admin_upgrade_link( $utm );
1628 -
1629 1444 printf(
1630 1445 /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */
1631 1446 esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ),
1632 1447 '<a href="' . esc_url( $upgrade_link ) . '">',
@@ -1636,9 +1451,8 @@
1636 1451 ?>
1637 1452 </div>
1638 1453 </div>
1639 1454 <?php
1640 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1641 1455 }
1642 1456
1643 1457 /**
1644 1458 * @since 5.4.2
@@ -1652,9 +1466,8 @@
1652 1466 /**
1653 1467 * Render a button for a new item (Form, Application, etc).
1654 1468 *
1655 1469 * @since 3.0
1656 - *
1657 1470 * @param array $atts {
1658 1471 * Details about the button.
1659 1472 *
1660 1473 * @type array $link_hook Custom link hook, calls do_action and exits early.
@@ -1661,9 +1474,8 @@
1661 1474 * @type string $new_link Href value, default #.
1662 1475 * @type string $class Custom class names, space separated.
1663 1476 * @type string $button_text Button text. Default "Add New".
1664 1477 * }
1665 - *
1666 1478 * @return void
1667 1479 */
1668 1480 public static function add_new_item_link( $atts ) {
1669 1481 if ( isset( $atts['link_hook'] ) ) {
@@ -1689,12 +1501,8 @@
1689 1501 }
1690 1502
1691 1503 /**
1692 1504 * @since 3.06
1693 - *
1694 - * @param array $atts
1695 - *
1696 - * @return void
1697 1505 */
1698 1506 public static function show_search_box( $atts ) {
1699 1507 $defaults = array(
1700 1508 'placeholder' => '',
@@ -1701,9 +1509,8 @@
1701 1509 'tosearch' => '',
1702 1510 'text' => __( 'Search', 'formidable' ),
1703 1511 'input_id' => '',
1704 1512 'value' => false,
1705 - 'class' => '',
1706 1513 );
1707 1514 $atts = array_merge( $defaults, $atts );
1708 1515
1709 1516 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
@@ -1710,9 +1517,8 @@
1710 1517 $atts['tosearch'] = 'frm-card';
1711 1518 }
1712 1519
1713 1520 $class = 'frm-search-input';
1714 -
1715 1521 if ( ! empty( $atts['tosearch'] ) ) {
1716 1522 $class .= ' frm-auto-search';
1717 1523 }
1718 1524
@@ -1736,15 +1542,14 @@
1736 1542
1737 1543 if ( ! empty( $atts['tosearch'] ) ) {
1738 1544 $input_atts['autocomplete'] = 'off';
1739 1545 }
1740 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1741 1546 ?>
1742 - <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>">
1547 + <p class="frm-search">
1743 1548 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
1744 1549 <?php echo esc_html( $atts['text'] ); ?>:
1745 1550 </label>
1746 - <?php self::icon_by_class( 'frmfont frm_search_icon frm_svg20' ); ?>
1551 + <span class="frmfont frm_search_icon"></span>
1747 1552 <input <?php self::array_to_html_params( $input_atts, true ); ?> />
1748 1553 <?php
1749 1554 if ( empty( $atts['tosearch'] ) ) {
1750 1555 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
@@ -1751,21 +1556,17 @@
1751 1556 }
1752 1557 ?>
1753 1558 </p>
1754 1559 <?php
1755 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1756 1560 }
1757 1561
1758 1562 /**
1759 - * @param string $type Hook type slug.
1760 - * @param object|null $object Optional related object.
1761 - *
1563 + * @param string $type
1762 1564 * @return void
1763 1565 */
1764 1566 public static function trigger_hook_load( $type, $object = null ) {
1765 1567 // Only load the form hooks once.
1766 1568 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
1767 -
1768 1569 if ( ! $hooks_loaded ) {
1769 1570 do_action( 'frm_load_' . $type . '_hooks' );
1770 1571 }
1771 1572 }
@@ -1824,14 +1625,14 @@
1824 1625 * True when value is 1, true, 'true', 'yes'
1825 1626 *
1826 1627 * @since 1.07.10
1827 1628 *
1828 - * @param bool|int|string $value The value to compare.
1629 + * @param string $value The value to compare.
1829 1630 *
1830 1631 * @return bool
1831 1632 */
1832 1633 public static function is_true( $value ) {
1833 - return true === $value || '1' === (string) $value || 'true' === $value || 'yes' === $value;
1634 + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value;
1834 1635 }
1835 1636
1836 1637 /**
1837 1638 * Gets all post from a specific post type.
@@ -1839,9 +1640,8 @@
1839 1640 *
1840 1641 * @since 4.10.01 Add `$post_type` argument.
1841 1642 *
1842 1643 * @param string $post_type Post type to query. Default is `page`.
1843 - *
1844 1644 * @return WP_Post[]
1845 1645 */
1846 1646 public static function get_pages( $post_type = 'page' ) {
1847 1647 $query = array(
@@ -1860,9 +1660,8 @@
1860 1660 *
1861 1661 * @since 5.0.09
1862 1662 *
1863 1663 * @param string $post_type Post type to query. Default is `page`.
1864 - *
1865 1664 * @return array
1866 1665 */
1867 1666 public static function get_post_ids_and_titles( $post_type = 'page' ) {
1868 1667 return FrmDb::get_results(
@@ -1887,12 +1686,13 @@
1887 1686 *
1888 1687 * @param array $args Selection arguments.
1889 1688 */
1890 1689 public static function maybe_autocomplete_pages_options( $args ) {
1891 - $args = self::preformat_selection_args( $args );
1690 + $args = self::preformat_selection_args( $args );
1691 +
1892 1692 $pages_count = wp_count_posts( $args['post_type'] );
1893 1693
1894 - if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) {
1694 + if ( $pages_count->publish <= 50 ) {
1895 1695 self::wp_pages_dropdown( $args );
1896 1696 return;
1897 1697 }
1898 1698
@@ -1916,109 +1716,8 @@
1916 1716 <?php
1917 1717 }
1918 1718
1919 1719 /**
1920 - * Maybe show an HTML select or autocomplete input based on the number of options.
1921 - *
1922 - * @since 6.21
1923 - *
1924 - * @param array $args Args. See the method for details.
1925 - */
1926 - public static function maybe_autocomplete_options( $args ) {
1927 - $defaults = array(
1928 - 'truncate' => false,
1929 - 'placeholder' => ' ',
1930 - 'name' => '',
1931 - 'id' => '',
1932 - 'selected' => '',
1933 - 'source' => array(),
1934 - 'dropdown_limit' => 50,
1935 - 'autocomplete_placeholder' => __( 'Select an option', 'formidable' ),
1936 - 'value_key' => 'value',
1937 - 'label_key' => 'label',
1938 - );
1939 -
1940 - $args = wp_parse_args( $args, $defaults );
1941 - $html_attrs = array();
1942 -
1943 - if ( ! empty( $args['name'] ) ) {
1944 - $html_attrs['name'] = $args['name'];
1945 - }
1946 -
1947 - if ( ! empty( $args['id'] ) ) {
1948 - $html_attrs['id'] = $args['id'];
1949 - }
1950 -
1951 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1952 - if ( count( $args['source'] ) <= $args['dropdown_limit'] ) {
1953 - ?>
1954 - <select <?php self::array_to_html_params( $html_attrs, true ); ?>>
1955 - <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1956 - <?php
1957 - foreach ( $args['source'] as $key => $source ) :
1958 - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1959 -
1960 - if ( ! empty( $args['truncate'] ) ) {
1961 - $value_label['label'] = self::truncate( $value_label['label'], $args['truncate'] );
1962 - }
1963 - ?>
1964 - <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1965 - <?php endforeach; ?>
1966 - </select>
1967 - <?php
1968 - return;
1969 - }
1970 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1971 -
1972 - $options = array();
1973 - $autocomplete_value = '';
1974 -
1975 - foreach ( $args['source'] as $key => $source ) {
1976 - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1977 -
1978 - if ( $value_label['value'] === $args['selected'] ) {
1979 - $autocomplete_value = $value_label['label'];
1980 - }
1981 -
1982 - $options[] = $value_label;
1983 - }
1984 -
1985 - $html_attrs['type'] = 'hidden';
1986 - $html_attrs['class'] = 'frm_autocomplete_value_input';
1987 - $html_attrs['value'] = $args['selected'];
1988 - ?>
1989 - <input type="text" class="frm-custom-search"
1990 - data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
1991 - placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1992 - value="<?php echo esc_attr( $autocomplete_value ); ?>" />
1993 - <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
1994 - <?php
1995 - }
1996 -
1997 - /**
1998 - * Gets dropdown value and label from autodropdown option.
1999 - *
2000 - * @since 6.21
2001 - *
2002 - * @param array|string $option Autocomplete option.
2003 - * @param string $key Array key of the option.
2004 - * @param array $args See {@see FrmAppHelper::maybe_autocomplete_options()}.
2005 - *
2006 - * @return array
2007 - */
2008 - private static function get_dropdown_value_and_label_from_option( $option, $key, $args ) {
2009 - if ( is_array( $option ) ) {
2010 - $value = $option[ $args['value_key'] ] ?? '';
2011 - $label = $option[ $args['label_key'] ] ?? '';
2012 - } else {
2013 - $value = $key;
2014 - $label = $option;
2015 - }
2016 -
2017 - return compact( 'value', 'label' );
2018 - }
2019 -
2020 - /**
2021 1720 * @param array $args
2022 1721 * @param string $page_id Deprecated.
2023 1722 * @param bool $truncate Deprecated.
2024 1723 */
@@ -2026,9 +1725,9 @@
2026 1725 self::prep_page_dropdown_params( $page_id, $truncate, $args );
2027 1726
2028 1727 $pages = self::get_post_ids_and_titles( $args['post_type'] );
2029 1728 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
2030 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1729 +
2031 1730 ?>
2032 1731 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
2033 1732 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
2034 1733 <?php foreach ( $pages as $page ) { ?>
@@ -2037,9 +1736,8 @@
2037 1736 </option>
2038 1737 <?php } ?>
2039 1738 </select>
2040 1739 <?php
2041 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2042 1740 }
2043 1741
2044 1742 /**
2045 1743 * Fill in missing parameters passed to wp_pages_dropdown().
@@ -2045,14 +1743,8 @@
2045 1743 * Fill in missing parameters passed to wp_pages_dropdown().
2046 1744 * This is for reverse compatibility with switching 3 params to 1.
2047 1745 *
2048 1746 * @since 4.03.06
2049 - *
2050 - * @param string $page_id Deprecated.
2051 - * @param bool $truncate Deprecated.
2052 - * @param mixed $args
2053 - *
2054 - * @return void
2055 1747 */
2056 1748 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
2057 1749 if ( ! is_array( $args ) ) {
2058 1750 $args = array(
@@ -2069,12 +1761,8 @@
2069 1761 * Filter to format args for page dropdown or autocomplete
2070 1762 *
2071 1763 * @since 4.03.06
2072 1764 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
2073 - *
2074 - * @param array $args
2075 - *
2076 - * @return array
2077 1765 */
2078 1766 private static function preformat_selection_args( $args ) {
2079 1767 $defaults = array(
2080 1768 'truncate' => false,
@@ -2087,18 +1775,13 @@
2087 1775
2088 1776 return array_merge( $defaults, $args );
2089 1777 }
2090 1778
2091 - /**
2092 - * @param int $post_id
2093 - *
2094 - * @return string
2095 - */
2096 1779 public static function post_edit_link( $post_id ) {
2097 1780 $post = get_post( $post_id );
2098 -
2099 1781 if ( $post ) {
2100 1782 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1783 +
2101 1784 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
2102 1785 }
2103 1786
2104 1787 return '';
@@ -2111,9 +1794,11 @@
2111 1794 *
2112 1795 * @return bool
2113 1796 */
2114 1797 public static function is_full_screen() {
2115 - return self::is_form_builder_page() || self::is_style_editor_page() || self::is_full_screen_view_builder_page();
1798 + return self::is_form_builder_page() ||
1799 + self::is_style_editor_page() ||
1800 + self::is_full_screen_view_builder_page();
2116 1801 }
2117 1802
2118 1803 /**
2119 1804 * Check if user is on the style editor or its alternative URL.
@@ -2123,9 +1808,8 @@
2123 1808 * @since 5.5.3
2124 1809 * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
2125 1810 *
2126 1811 * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
2127 - *
2128 1812 * @return bool
2129 1813 */
2130 1814 public static function is_style_editor_page( $view = '' ) {
2131 1815 if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
@@ -2162,9 +1846,8 @@
2162 1846 * @param array|string $capability
2163 1847 * @param string $multiple 'single' and 'multiple'.
2164 1848 */
2165 1849 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
2166 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2167 1850 ?>
2168 1851 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
2169 1852 <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?>
2170 1853 class="frm_multiselect">
@@ -2170,14 +1853,12 @@
2170 1853 class="frm_multiselect">
2171 1854 <?php self::roles_options( $capability ); ?>
2172 1855 </select>
2173 1856 <?php
2174 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2175 1857 }
2176 1858
2177 1859 /**
2178 1860 * @since 4.07
2179 - *
2180 1861 * @param array|string $selected
2181 1862 * @param string $current
2182 1863 */
2183 1864 private static function selected( $selected, $current ) {
@@ -2192,9 +1873,8 @@
2192 1873 * @param array|string $capability
2193 1874 */
2194 1875 public static function roles_options( $capability ) {
2195 1876 global $frm_vars;
2196 -
2197 1877 if ( isset( $frm_vars['editable_roles'] ) ) {
2198 1878 $editable_roles = $frm_vars['editable_roles'];
2199 1879 } else {
2200 1880 $editable_roles = get_editable_roles();
@@ -2203,9 +1883,9 @@
2203 1883
2204 1884 foreach ( $editable_roles as $role => $details ) {
2205 1885 $name = translate_user_role( $details['name'] );
2206 1886 ?>
2207 - <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?></option>
1887 + <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?> </option>
2208 1888 <?php
2209 1889 unset( $role, $details );
2210 1890 }
2211 1891 }
@@ -2215,9 +1895,8 @@
2215 1895 *
2216 1896 * @since 5.0 Parameter `$type` supports `pro_only` value.
2217 1897 *
2218 1898 * @param string $type Supports `auto`, `pro`, or `pro_only`.
2219 - *
2220 1899 * @return array
2221 1900 */
2222 1901 public static function frm_capabilities( $type = 'auto' ) {
2223 1902 if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
@@ -2235,8 +1914,14 @@
2235 1914 * @param array<string,string> $pro_cap
2236 1915 */
2237 1916 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
2238 1917
1918 + if ( ! array_key_exists( 'frm_edit_displays', $pro_cap ) && is_callable( 'FrmProAppHelper::views_is_installed' ) && FrmProAppHelper::views_is_installed() ) {
1919 + // For backward compatibility, add the Add/Edit Views permission if Pro is not up to date.
1920 + // This was added in 6.5.4. Remove this in the future.
1921 + $pro_cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
1922 + }
1923 +
2239 1924 if ( 'pro_only' === $type ) {
2240 1925 return $pro_cap;
2241 1926 }
2242 1927
@@ -2282,18 +1967,21 @@
2282 1967 if ( $role === 'loggedin' || ! $role ) {
2283 1968 return is_user_logged_in();
2284 1969 }
2285 1970
2286 - if ( (int) $role === 1 ) {
1971 + if ( $role == 1 ) {
2287 1972 $role = 'administrator';
2288 1973 }
2289 1974
2290 - return is_user_logged_in() ? current_user_can( $role ) : false;
1975 + if ( ! is_user_logged_in() ) {
1976 + return false;
1977 + }
1978 +
1979 + return current_user_can( $role );
2291 1980 }
2292 1981
2293 1982 /**
2294 1983 * @param array|string $needed_role
2295 - *
2296 1984 * @return bool
2297 1985 */
2298 1986 public static function user_has_permission( $needed_role ) {
2299 1987 if ( is_array( $needed_role ) ) {
@@ -2307,20 +1995,18 @@
2307 1995 }
2308 1996
2309 1997 $can = self::current_user_can( $needed_role );
2310 1998
2311 - if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ), true ) ) {
1999 + if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
2312 2000 return $can;
2313 2001 }
2314 2002
2315 2003 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
2316 -
2317 2004 foreach ( $roles as $role ) {
2318 2005 if ( current_user_can( $role ) ) {
2319 2006 return true;
2320 2007 }
2321 -
2322 - if ( $role === $needed_role ) {
2008 + if ( $role == $needed_role ) {
2323 2009 break;
2324 2010 }
2325 2011 }
2326 2012
@@ -2338,11 +2024,11 @@
2338 2024 if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
2339 2025 return;
2340 2026 }
2341 2027
2342 - $user = new WP_User( get_current_user_id() );
2028 + $user_id = get_current_user_id();
2029 + $user = new WP_User( $user_id );
2343 2030 $frm_roles = self::frm_capabilities();
2344 -
2345 2031 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2346 2032 $user->add_cap( $frm_role );
2347 2033 unset( $frm_role, $frm_role_description );
2348 2034 }
@@ -2353,22 +2039,18 @@
2353 2039 *
2354 2040 * @since 2.0.6
2355 2041 *
2356 2042 * @param string $cap
2357 - *
2358 2043 * @return void
2359 2044 */
2360 2045 public static function force_capability( $cap = 'frm_change_settings' ) {
2361 - if ( ! current_user_can( 'administrator' ) || current_user_can( $cap ) ) {
2362 - return;
2046 + if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
2047 + $role = get_role( 'administrator' );
2048 + $frm_roles = self::frm_capabilities();
2049 + foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2050 + $role->add_cap( $frm_role );
2051 + }
2363 2052 }
2364 -
2365 - $role = get_role( 'administrator' );
2366 - $frm_roles = self::frm_capabilities();
2367 -
2368 - foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2369 - $role->add_cap( $frm_role );
2370 - }
2371 2053 }
2372 2054
2373 2055 /**
2374 2056 * Check if the user has permission for action.
@@ -2376,22 +2058,17 @@
2376 2058 *
2377 2059 * @since 2.0
2378 2060 *
2379 2061 * @param string $permission
2380 - * @param string $show_message
2381 2062 */
2382 2063 public static function permission_check( $permission, $show_message = 'show' ) {
2383 2064 $permission_error = self::permission_nonce_error( $permission );
2384 -
2385 - if ( $permission_error === false ) {
2386 - return;
2065 + if ( $permission_error !== false ) {
2066 + if ( 'hide' == $show_message ) {
2067 + $permission_error = '';
2068 + }
2069 + wp_die( esc_html( $permission_error ) );
2387 2070 }
2388 -
2389 - if ( 'hide' === $show_message ) {
2390 - $permission_error = '';
2391 - }
2392 -
2393 - wp_die( esc_html( $permission_error ) );
2394 2071 }
2395 2072
2396 2073 /**
2397 2074 * Check user permission and nonce
@@ -2398,27 +2075,24 @@
2398 2075 *
2399 2076 * @since 2.0
2400 2077 *
2401 2078 * @param string $permission
2402 - * @param string $nonce_name
2403 - * @param string $nonce
2404 2079 *
2405 2080 * @return false|string The permission message or false if allowed
2406 2081 */
2407 2082 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
2408 - if ( $permission && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2083 + if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2409 2084 $frm_settings = self::get_settings();
2085 +
2410 2086 return $frm_settings->admin_permission;
2411 2087 }
2412 2088
2413 2089 $error = false;
2414 -
2415 - if ( ! $nonce_name ) {
2090 + if ( empty( $nonce_name ) ) {
2416 2091 return $error;
2417 2092 }
2418 2093
2419 2094 $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
2420 -
2421 2095 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
2422 2096 $frm_settings = self::get_settings();
2423 2097 $error = $frm_settings->admin_permission;
2424 2098 }
@@ -2425,14 +2099,8 @@
2425 2099
2426 2100 return $error;
2427 2101 }
2428 2102
2429 - /**
2430 - * @param array|string $values
2431 - * @param string $current
2432 - *
2433 - * @return void
2434 - */
2435 2103 public static function checked( $values, $current ) {
2436 2104 if ( self::check_selected( $values, $current ) ) {
2437 2105 echo ' checked="checked"';
2438 2106 }
@@ -2437,47 +2105,38 @@
2437 2105 echo ' checked="checked"';
2438 2106 }
2439 2107 }
2440 2108
2441 - /**
2442 - * @param array|string $values
2443 - * @param string|null $current
2444 - *
2445 - * @return bool
2446 - */
2447 2109 public static function check_selected( $values, $current ) {
2448 - $values = self::recursive_function_map( $values, 'trim' );
2449 - $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2110 + $values = self::recursive_function_map( $values, 'trim' );
2111 + $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2112 +
2450 2113 $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) );
2451 2114
2452 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons
2453 - return is_array( $values ) ? in_array( $current, $values ) : $values == $current;
2115 + return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
2454 2116 }
2455 2117
2456 - /**
2457 - * @param array|string $value
2458 - * @param callable|string $function
2459 - *
2460 - * @return array|string
2461 - */
2462 2118 public static function recursive_function_map( $value, $function ) {
2463 2119 if ( is_array( $value ) ) {
2464 2120 $original_function = $function;
2465 - $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function );
2466 -
2467 - if ( self::is_assoc( $value ) ) {
2121 + if ( count( $value ) ) {
2122 + $function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
2123 + } else {
2124 + $function = array( $function );
2125 + }
2126 + if ( ! self::is_assoc( $value ) ) {
2127 + $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2128 + } else {
2468 2129 foreach ( $value as $k => $v ) {
2469 2130 if ( ! is_array( $v ) ) {
2470 2131 $value[ $k ] = call_user_func( $original_function, $v );
2471 2132 }
2472 2133 }
2473 - } else {
2474 - $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2475 2134 }
2476 2135 } else {
2477 2136 $value = self::maybe_update_value_if_null( $value, $function );
2478 2137 $value = call_user_func( $function, $value );
2479 - }//end if
2138 + }
2480 2139
2481 2140 return $value;
2482 2141 }
2483 2142
@@ -2484,27 +2143,20 @@
2484 2143 /**
2485 2144 * Updates value to empty string if it is null and being passed to a string function.
2486 2145 *
2487 2146 * @since 6.8.4
2488 - *
2489 2147 * @param mixed $value
2490 2148 * @param string $function
2491 - *
2492 2149 * @return mixed
2493 2150 */
2494 2151 private static function maybe_update_value_if_null( $value, $function ) {
2495 2152 if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) {
2496 - return '';
2153 + $value = '';
2497 2154 }
2498 2155
2499 2156 return $value;
2500 2157 }
2501 2158
2502 - /**
2503 - * @param array $array
2504 - *
2505 - * @return bool
2506 - */
2507 2159 public static function is_assoc( $array ) {
2508 2160 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
2509 2161 }
2510 2162
@@ -2509,22 +2161,16 @@
2509 2161 }
2510 2162
2511 2163 /**
2512 2164 * Flatten a multi-dimensional array
2513 - *
2514 - * @param array $array
2515 - * @param string $keys
2516 - *
2517 - * @return array
2518 2165 */
2519 2166 public static function array_flatten( $array, $keys = 'keep' ) {
2520 2167 $return = array();
2521 -
2522 2168 foreach ( $array as $key => $value ) {
2523 2169 if ( is_array( $value ) ) {
2524 2170 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
2525 2171 } elseif ( $keys === 'keep' ) {
2526 - $return[ $key ] = $value;
2172 + $return[ $key ] = $value;
2527 2173 } else {
2528 2174 $return[] = $value;
2529 2175 }
2530 2176 }
@@ -2538,9 +2184,8 @@
2538 2184 * @since 6.16.1
2539 2185 *
2540 2186 * @param string $sep
2541 2187 * @param array $array
2542 - *
2543 2188 * @return string
2544 2189 */
2545 2190 public static function safe_implode( $sep, $array ) {
2546 2191 $array = self::array_flatten( $array );
@@ -2549,18 +2194,15 @@
2549 2194
2550 2195 /**
2551 2196 * @param string $text
2552 2197 * @param bool $is_rich_text
2553 - *
2554 2198 * @return string
2555 2199 */
2556 2200 public static function esc_textarea( $text, $is_rich_text = false ) {
2557 2201 $safe_text = str_replace( '&quot;', '"', $text );
2558 -
2559 2202 if ( ! $is_rich_text ) {
2560 2203 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
2561 2204 }
2562 -
2563 2205 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
2564 2206
2565 2207 /**
2566 2208 * @param string $safe_text
@@ -2572,59 +2214,44 @@
2572 2214 /**
2573 2215 * Add auto paragraphs to text areas
2574 2216 *
2575 2217 * @since 2.0
2576 - *
2577 - * @param mixed $content
2578 - *
2579 - * @return mixed
2580 2218 */
2581 2219 public static function use_wpautop( $content ) {
2582 2220 if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) {
2583 - return wpautop( str_replace( '<br>', '<br />', $content ) );
2221 + $content = wpautop( str_replace( '<br>', '<br />', $content ) );
2584 2222 }
2585 2223
2586 2224 return $content;
2587 2225 }
2588 2226
2589 - /**
2590 - * Replace quotes with their HTML entities.
2591 - *
2592 - * @param string $val
2593 - *
2594 - * @return string
2595 - */
2596 2227 public static function replace_quotes( $val ) {
2597 2228 // Replace double quotes.
2598 2229 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
2599 2230
2600 2231 // Replace single quotes.
2601 - return str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2232 + $val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2233 +
2234 + return $val;
2602 2235 }
2603 2236
2604 2237 /**
2605 - * @param string $handle
2606 - * @param int|string $default
2607 - *
2608 - * @return int|string
2238 + * @param string $handle
2609 2239 */
2610 2240 public static function script_version( $handle, $default = 0 ) {
2611 2241 global $wp_scripts;
2612 -
2613 2242 if ( ! $wp_scripts ) {
2614 2243 return $default;
2615 2244 }
2616 2245
2617 2246 $ver = $default;
2618 -
2619 2247 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
2620 2248 return $ver;
2621 2249 }
2622 2250
2623 2251 $query = $wp_scripts->registered[ $handle ];
2624 -
2625 2252 if ( is_object( $query ) && ! empty( $query->ver ) ) {
2626 - return $query->ver;
2253 + $ver = $query->ver;
2627 2254 }
2628 2255
2629 2256 return $ver;
2630 2257 }
@@ -2633,9 +2260,8 @@
2633 2260 * @since 5.0.13 added $echo param.
2634 2261 *
2635 2262 * @param string $url
2636 2263 * @param bool $echo
2637 - *
2638 2264 * @return string|null
2639 2265 */
2640 2266 public static function js_redirect( $url, $echo = false ) {
2641 2267 $callback = function () use ( $url ) {
@@ -2643,13 +2269,8 @@
2643 2269 };
2644 2270 return self::clip( $callback, $echo );
2645 2271 }
2646 2272
2647 - /**
2648 - * @param int|string $user_id
2649 - *
2650 - * @return int|string
2651 - */
2652 2273 public static function get_user_id_param( $user_id ) {
2653 2274 if ( ! $user_id || is_numeric( $user_id ) ) {
2654 2275 return $user_id;
2655 2276 }
@@ -2654,13 +2275,16 @@
2654 2275 return $user_id;
2655 2276 }
2656 2277
2657 2278 $user_id = sanitize_text_field( $user_id );
2658 -
2659 2279 if ( $user_id === 'current' ) {
2660 2280 $user_id = get_current_user_id();
2661 2281 } else {
2662 - $user = is_email( $user_id ) ? get_user_by( 'email', $user_id ) : get_user_by( 'login', $user_id );
2282 + if ( is_email( $user_id ) ) {
2283 + $user = get_user_by( 'email', $user_id );
2284 + } else {
2285 + $user = get_user_by( 'login', $user_id );
2286 + }
2663 2287
2664 2288 if ( $user ) {
2665 2289 $user_id = $user->ID;
2666 2290 }
@@ -2672,9 +2296,8 @@
2672 2296
2673 2297 /**
2674 2298 * @param string $filename
2675 2299 * @param array $atts
2676 - *
2677 2300 * @return false|string
2678 2301 */
2679 2302 public static function get_file_contents( $filename, $atts = array() ) {
2680 2303 if ( ! is_file( $filename ) ) {
@@ -2683,9 +2306,12 @@
2683 2306
2684 2307 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
2685 2308 ob_start();
2686 2309 include $filename;
2687 - return ob_get_clean();
2310 + $contents = ob_get_contents();
2311 + ob_end_clean();
2312 +
2313 + return $contents;
2688 2314 }
2689 2315
2690 2316 /**
2691 2317 * @param string $name
@@ -2695,9 +2321,8 @@
2695 2321 * @param int $num_chars
2696 2322 */
2697 2323 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
2698 2324 $key = '';
2699 -
2700 2325 if ( $name ) {
2701 2326 $key = sanitize_key( $name );
2702 2327 $key = self::maybe_clear_long_key( $key, $column );
2703 2328 }
@@ -2717,31 +2342,31 @@
2717 2342 $column
2718 2343 );
2719 2344
2720 2345 // Create a unique field id if it has already been used.
2721 - if ( ! in_array( $key, $similar_keys, true ) ) {
2722 - return $key;
2723 - }
2346 + if ( in_array( $key, $similar_keys, true ) ) {
2347 + $key = self::maybe_truncate_key_before_appending( $column, $key );
2724 2348
2725 - $key = self::maybe_truncate_key_before_appending( $column, $key );
2349 + /**
2350 + * Allow for a custom separator between the attempted key and the generated suffix.
2351 + *
2352 + * @since 5.2.03
2353 + *
2354 + * @param string $separator. Default empty.
2355 + * @param string $key the key without the added suffix.
2356 + */
2357 + $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2726 2358
2727 - /**
2728 - * Allow for a custom separator between the attempted key and the generated suffix.
2729 - *
2730 - * @since 5.2.03
2731 - *
2732 - * @param string $separator. Default empty.
2733 - * @param string $key the key without the added suffix.
2734 - */
2735 - $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2359 + $suffix = 2;
2360 + do {
2361 + $key_check = $key . $separator . $suffix;
2362 + ++$suffix;
2363 + } while ( in_array( $key_check, $similar_keys, true ) );
2736 2364
2737 - $suffix = 2;
2738 - do {
2739 - $key_check = $key . $separator . $suffix;
2740 - ++$suffix;
2741 - } while ( in_array( $key_check, $similar_keys, true ) );
2365 + $key = $key_check;
2366 + }//end if
2742 2367
2743 - return $key_check;
2368 + return $key;
2744 2369 }
2745 2370
2746 2371 /**
2747 2372 * Avoid trying to append to a really long key,
@@ -2748,26 +2373,20 @@
2748 2373 * The database limit is 100 for form and field keys so we want to avoid getting too close.
2749 2374 *
2750 2375 * @param string $column
2751 2376 * @param string $key
2752 - *
2753 2377 * @return string
2754 2378 */
2755 2379 private static function maybe_truncate_key_before_appending( $column, $key ) {
2756 - if ( ! in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2757 - return $key;
2758 - }
2759 -
2760 - $max_key_length_before_truncating = 60;
2761 -
2762 - if ( strlen( $key ) > $max_key_length_before_truncating ) {
2763 - $key = substr( $key, 0, $max_key_length_before_truncating );
2764 -
2765 - if ( is_numeric( $key ) ) {
2766 - $key .= 'a';
2380 + if ( in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2381 + $max_key_length_before_truncating = 60;
2382 + if ( strlen( $key ) > $max_key_length_before_truncating ) {
2383 + $key = substr( $key, 0, $max_key_length_before_truncating );
2384 + if ( is_numeric( $key ) ) {
2385 + $key .= 'a';
2386 + }
2767 2387 }
2768 2388 }
2769 -
2770 2389 return $key;
2771 2390 }
2772 2391
2773 2392 /**
@@ -2774,36 +2393,31 @@
2774 2393 * Possibly reset a key to avoid conflicts with column size limits.
2775 2394 *
2776 2395 * @param string $key
2777 2396 * @param string $column
2778 - *
2779 2397 * @return string either the original key value, or an empty string if the key was too long.
2780 2398 */
2781 2399 private static function maybe_clear_long_key( $key, $column ) {
2782 2400 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
2783 - return '';
2401 + $key = '';
2784 2402 }
2785 2403 return $key;
2786 2404 }
2787 2405
2788 2406 /**
2789 - * @since 6.21 This is changed from `private` to `public`.
2790 - *
2791 2407 * @param int $num_chars
2792 - *
2793 2408 * @return string
2794 2409 */
2795 - public static function generate_new_key( $num_chars ) {
2796 - $max_slug_value = 36 ** $num_chars;
2410 + private static function generate_new_key( $num_chars ) {
2411 + $max_slug_value = pow( 36, $num_chars );
2797 2412
2798 2413 // We want to have at least 2 characters in the slug.
2799 2414 $min_slug_value = 37;
2800 - return base_convert( random_int( $min_slug_value, $max_slug_value ), 10, 36 );
2415 + return base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
2801 2416 }
2802 2417
2803 2418 /**
2804 2419 * @param string $key
2805 - *
2806 2420 * @return string
2807 2421 */
2808 2422 private static function prevent_numeric_and_reserved_keys( $key ) {
2809 2423 if ( is_numeric( $key ) ) {
@@ -2817,14 +2431,12 @@
2817 2431 'editlink',
2818 2432 'siteurl',
2819 2433 'evenodd',
2820 2434 );
2821 -
2822 2435 if ( in_array( $key, $not_allowed, true ) ) {
2823 2436 $key .= 'a';
2824 2437 }
2825 2438 }
2826 -
2827 2439 return $key;
2828 2440 }
2829 2441
2830 2442 /**
@@ -2843,9 +2455,9 @@
2843 2455 if ( ! $record ) {
2844 2456 return false;
2845 2457 }
2846 2458
2847 - if ( ! $post_values ) {
2459 + if ( empty( $post_values ) ) {
2848 2460 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
2849 2461 }
2850 2462
2851 2463 $values = array(
@@ -2853,9 +2465,9 @@
2853 2465 'fields' => array(),
2854 2466 );
2855 2467
2856 2468 foreach ( array( 'name', 'description' ) as $var ) {
2857 - $default_val = $record->{$var} ?? '';
2469 + $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
2858 2470 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
2859 2471 unset( $var, $default_val );
2860 2472 }
2861 2473
@@ -2873,67 +2485,46 @@
2873 2485
2874 2486 return $values;
2875 2487 }
2876 2488
2877 - /**
2878 - * @param array|string $fields
2879 - * @param object $record
2880 - * @param array $values
2881 - * @param array $args
2882 - *
2883 - * @return void
2884 - */
2885 2489 private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
2886 - if ( ! $fields ) {
2887 - return;
2888 - }
2889 -
2890 - foreach ( (array) $fields as $field ) {
2891 - if ( ! self::is_admin_page() ) {
2892 - // Don't prep default values on the form settings page.
2893 - $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
2490 + if ( ! empty( $fields ) ) {
2491 + foreach ( (array) $fields as $field ) {
2492 + if ( ! self::is_admin_page() ) {
2493 + // Don't prep default values on the form settings page.
2494 + $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
2495 + }
2496 + $args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
2497 + self::fill_field_defaults( $field, $record, $values, $args );
2894 2498 }
2895 -
2896 - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id;
2897 - self::fill_field_defaults( $field, $record, $values, $args );
2898 2499 }
2899 2500 }
2900 2501
2901 - /**
2902 - * @param object $field
2903 - * @param object $record
2904 - * @param array $values
2905 - * @param array $args
2906 - *
2907 - * @return void
2908 - */
2909 2502 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
2910 2503 $post_values = $args['post_values'];
2911 2504
2912 2505 if ( $args['default'] ) {
2913 2506 $meta_value = $field->default_value;
2914 - } elseif ( $record->post_id && self::pro_is_installed() && ! empty( $field->field_options['post_field'] ) ) {
2507 + } elseif ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) {
2915 2508 if ( ! isset( $field->field_options['custom_field'] ) ) {
2916 2509 $field->field_options['custom_field'] = '';
2917 2510 }
2918 -
2919 - $meta_value = FrmProEntryMetaHelper::get_post_value(
2920 - $record->post_id,
2921 - $field->field_options['post_field'],
2922 - $field->field_options['custom_field'],
2923 - array(
2924 - 'truncate' => false,
2925 - 'type' => $field->type,
2926 - 'form_id' => $field->form_id,
2927 - 'field' => $field,
2928 - )
2929 - );
2511 + $meta_value = FrmProEntryMetaHelper::get_post_value(
2512 + $record->post_id,
2513 + $field->field_options['post_field'],
2514 + $field->field_options['custom_field'],
2515 + array(
2516 + 'truncate' => false,
2517 + 'type' => $field->type,
2518 + 'form_id' => $field->form_id,
2519 + 'field' => $field,
2520 + )
2521 + );
2930 2522 } else {
2931 2523 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
2932 2524 }//end if
2933 2525
2934 - $field_type = $post_values['field_options'][ 'type_' . $field->id ] ?? $field->type;
2935 -
2526 + $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
2936 2527 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
2937 2528 $new_value = $post_values['item_meta'][ $field->id ];
2938 2529 self::unserialize_or_decode( $new_value );
2939 2530 } else {
@@ -2948,9 +2539,9 @@
2948 2539 $args['field_type'] = $field_type;
2949 2540
2950 2541 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
2951 2542
2952 - if ( empty( $field_array['unique'] ) ) {
2543 + if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
2953 2544 $field_array['unique_msg'] = '';
2954 2545 }
2955 2546
2956 2547 $field_array = array_merge( (array) $field->field_options, $field_array );
@@ -3017,21 +2608,15 @@
3017 2608 }
3018 2609
3019 2610 /**
3020 2611 * Set to POST value or default
3021 - *
3022 - * @param array $post_values
3023 - * @param array $values
3024 - *
3025 - * @return void
3026 2612 */
3027 2613 private static function fill_form_defaults( $post_values, array &$values ) {
3028 2614 $form_defaults = FrmFormsHelper::get_default_opts();
3029 2615
3030 2616 foreach ( $form_defaults as $opt => $default ) {
3031 - // phpcs:ignore Universal.Operators.StrictComparisons
3032 2617 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
3033 - $values[ $opt ] = $post_values['options'][ $opt ] ?? $default;
2618 + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default;
3034 2619 }
3035 2620
3036 2621 unset( $opt, $default );
3037 2622 }
@@ -3041,9 +2626,9 @@
3041 2626 }
3042 2627
3043 2628 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
3044 2629 if ( ! isset( $values[ $h . '_html' ] ) ) {
3045 - $values[ $h . '_html' ] = $post_values['options'][ $h . '_html' ] ?? FrmFormsHelper::get_default_html( $h );
2630 + $values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
3046 2631 }
3047 2632 unset( $h );
3048 2633 }
3049 2634 }
@@ -3055,57 +2640,46 @@
3055 2640 *
3056 2641 * @return bool|int
3057 2642 */
3058 2643 public static function custom_style_value( $post_values ) {
3059 - if ( $post_values && isset( $post_values['options']['custom_style'] ) ) {
3060 - return absint( $post_values['options']['custom_style'] );
2644 + if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
2645 + $custom_style = absint( $post_values['options']['custom_style'] );
2646 + } else {
2647 + $frm_settings = self::get_settings();
2648 + $custom_style = ( $frm_settings->load_style !== 'none' );
3061 2649 }
3062 2650
3063 - $frm_settings = self::get_settings();
3064 - return $frm_settings->load_style !== 'none';
2651 + return $custom_style;
3065 2652 }
3066 2653
3067 2654 /**
3068 - * Truncate a string.
3069 - *
3070 - * Note: By default, this function will allow for a few additional characters more than $length.
3071 - * If a string has no spaces, it allows up to 50 additional characters. To force a true length limit,
3072 - * use $force_length_limit = true.
3073 - *
3074 2655 * @param mixed $original_string
3075 2656 * @param int|string $length
3076 2657 * @param int $minword
3077 2658 * @param string $continue
3078 - * @param bool $force_length_limit Force the final string to never exceed the length limit.
3079 - *
3080 2659 * @return string
3081 2660 */
3082 - public static function truncate( $original_string, $length, $minword = 3, $continue = '...', $force_length_limit = false ) {
2661 + public static function truncate( $original_string, $length, $minword = 3, $continue = '...' ) {
3083 2662 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
3084 2663 return '';
3085 2664 }
3086 2665
3087 - $length = (int) $length;
2666 + $length = (int) $length;
2667 + $str = wp_strip_all_tags( (string) $original_string );
2668 + $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3088 2669
3089 - if ( $length === 0 ) {
2670 + if ( $length == 0 ) {
3090 2671 return '';
3091 2672 }
3092 2673
3093 - $str = wp_strip_all_tags( (string) $original_string );
3094 - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3095 -
3096 2674 if ( $length <= 10 ) {
3097 2675 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
3098 -
3099 - if ( $force_length_limit ) {
3100 - return $sub;
3101 - }
3102 -
3103 2676 return $sub . ( $length < $original_len ? $continue : '' );
3104 2677 }
3105 2678
3106 - $sub = '';
3107 - $len = 0;
2679 + $sub = '';
2680 + $len = 0;
2681 +
3108 2682 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
3109 2683
3110 2684 if ( ! is_array( $words ) ) {
3111 2685 return $original_string;
@@ -3111,11 +2685,10 @@
3111 2685 return $original_string;
3112 2686 }
3113 2687
3114 2688 foreach ( $words as $word ) {
3115 - $part = ( $sub !== '' ? ' ' : '' ) . $word;
2689 + $part = ( $sub != '' ? ' ' : '' ) . $word;
3116 2690 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
3117 -
3118 2691 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
3119 2692 break;
3120 2693 }
3121 2694
@@ -3128,21 +2701,10 @@
3128 2701
3129 2702 unset( $total_len, $word );
3130 2703 }
3131 2704
3132 - $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit );
2705 + $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length );
3133 2706
3134 - if ( $force_length_limit ) {
3135 - // Ensure the final string doesn't exceed the length limit.
3136 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3137 -
3138 - if ( $final_len > $length ) {
3139 - return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) );
3140 - }
3141 -
3142 - return $sub;
3143 - }
3144 -
3145 2707 return $sub . ( $len < $original_len ? $continue : '' );
3146 2708 }
3147 2709
3148 2710 /**
@@ -3149,51 +2711,30 @@
3149 2711 * If the string is still too long because there may not have been any spaces, force truncate.
3150 2712 *
3151 2713 * @since 6.5.4
3152 2714 *
3153 - * @param string $sub Current substring.
3154 - * @param int $length The length limit.
3155 - * @param bool $force_length_limit Force the string to not exceed the length limit.
3156 - *
2715 + * @param string $sub Current substring.
2716 + * @param int $length The length limit.
3157 2717 * @return string
3158 2718 */
3159 - private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit = false ) {
3160 - if ( ! $force_length_limit ) {
3161 - if ( strlen( $sub ) < $length + 50 ) {
3162 - // If the string isn't way over the limit, leave it.
3163 - return $sub;
3164 - }
3165 -
3166 - $first_space = strpos( $sub, ' ', $length );
3167 -
3168 - if ( false !== $first_space ) {
3169 - // Ignore anything with spaces.
3170 - return $sub;
3171 - }
3172 -
3173 - return substr( $sub, 0, $length + 10 );
2719 + private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) {
2720 + if ( strlen( $sub ) < $length + 50 ) {
2721 + // If the string isn't way over the limit, leave it.
2722 + return $sub;
3174 2723 }
3175 2724
3176 - // When force_length_limit is true, ensure the string doesn't exceed the length.
3177 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3178 -
3179 - if ( $final_len > $length ) {
3180 - return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) );
2725 + $first_space = strpos( $sub, ' ', $length );
2726 + if ( false !== $first_space ) {
2727 + // Ignore anything with spaces.
2728 + return $sub;
3181 2729 }
3182 2730
3183 - return $sub;
2731 + return substr( $sub, 0, $length + 10 );
3184 2732 }
3185 2733
3186 - /**
3187 - * @param array $function_names
3188 - * @param array $args
3189 - *
3190 - * @return mixed
3191 - */
3192 2734 public static function mb_function( $function_names, $args ) {
3193 2735 $mb_function_name = $function_names[0];
3194 2736 $function_name = $function_names[1];
3195 -
3196 2737 if ( function_exists( $mb_function_name ) ) {
3197 2738 $function_name = $mb_function_name;
3198 2739 }
3199 2740
@@ -3199,21 +2740,14 @@
3199 2740
3200 2741 return call_user_func_array( $function_name, $args );
3201 2742 }
3202 2743
3203 - /**
3204 - * @param string $date
3205 - * @param string $date_format
3206 - * @param string $time_format
3207 - *
3208 - * @return string
3209 - */
3210 2744 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
3211 - if ( ! $date ) {
2745 + if ( empty( $date ) ) {
3212 2746 return $date;
3213 2747 }
3214 2748
3215 - if ( ! $date_format ) {
2749 + if ( empty( $date_format ) ) {
3216 2750 $date_format = get_option( 'date_format' );
3217 2751 }
3218 2752
3219 2753 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
@@ -3221,10 +2755,10 @@
3221 2755 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
3222 2756 }
3223 2757
3224 2758 $formatted = self::get_localized_date( $date_format, $date );
3225 - $do_time = gmdate( 'H:i:s', strtotime( $date ) ) !== '00:00:00';
3226 2759
2760 + $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
3227 2761 if ( $do_time ) {
3228 2762 $formatted .= self::add_time_to_date( $time_format, $date );
3229 2763 }
3230 2764
@@ -3233,35 +2767,30 @@
3233 2767
3234 2768 /**
3235 2769 * @param string $time_format
3236 2770 * @param string $date
3237 - *
3238 2771 * @return string
3239 2772 */
3240 2773 private static function add_time_to_date( $time_format, $date ) {
3241 - if ( ! $time_format ) {
2774 + if ( empty( $time_format ) ) {
3242 2775 $time_format = get_option( 'time_format' );
3243 2776 }
3244 2777
3245 2778 $trimmed_format = trim( $time_format );
3246 -
3247 - if ( $time_format && $trimmed_format ) {
3248 - return ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
2779 + $time = '';
2780 + if ( $time_format && ! empty( $trimmed_format ) ) {
2781 + $time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
3249 2782 }
3250 2783
3251 - return '';
2784 + return $time;
3252 2785 }
3253 2786
3254 2787 /**
3255 2788 * @since 2.0.8
3256 - *
3257 - * @param string $date_format
3258 - * @param string $date
3259 - *
3260 - * @return string
3261 2789 */
3262 2790 public static function get_localized_date( $date_format, $date ) {
3263 2791 $date = get_date_from_gmt( $date );
2792 +
3264 2793 return date_i18n( $date_format, strtotime( $date ) );
3265 2794 }
3266 2795
3267 2796 /**
@@ -3266,16 +2795,19 @@
3266 2795
3267 2796 /**
3268 2797 * Gets the time ago in words.
3269 2798 *
3270 - * @param int $from In seconds.
3271 - * @param int|string $to In seconds.
3272 - * @param int|string $levels Number of time units to include or a specific unit.
2799 + * @param int $from In seconds.
2800 + * @param int|string $to In seconds.
3273 2801 *
3274 - * @return string Time ago.
2802 + * @return string $time_ago
3275 2803 */
3276 2804 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
3277 - $now = ! $to && 0 !== $to ? new DateTime() : new DateTime( '@' . $to );
2805 + if ( empty( $to ) && 0 !== $to ) {
2806 + $now = new DateTime();
2807 + } else {
2808 + $now = new DateTime( '@' . $to );
2809 + }
3278 2810 $ago = new DateTime( '@' . $from );
3279 2811
3280 2812 // Get the time difference
3281 2813 $diff_object = $now->diff( $ago );
@@ -3289,9 +2821,8 @@
3289 2821
3290 2822 if ( ! is_numeric( $levels ) ) {
3291 2823 // Show time in specified unit.
3292 2824 $levels = self::get_unit( $levels );
3293 -
3294 2825 if ( isset( $time_strings[ $levels ] ) ) {
3295 2826 $diff = array(
3296 2827 $levels => self::time_format( $levels, $diff ),
3297 2828 );
@@ -3298,14 +2829,13 @@
3298 2829 $time_strings = array(
3299 2830 $levels => $time_strings[ $levels ],
3300 2831 );
3301 2832 }
3302 -
3303 2833 $levels = 1;
3304 2834 }
3305 2835
3306 2836 foreach ( $time_strings as $k => $v ) {
3307 - if ( ! empty( $diff[ $k ] ) ) {
2837 + if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
3308 2838 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
3309 2839 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
3310 2840 // Account for 0.
3311 2841 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
@@ -3313,21 +2843,17 @@
3313 2843 unset( $time_strings[ $k ] );
3314 2844 }
3315 2845 }
3316 2846
3317 - $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
3318 - $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2847 + $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
2848 + $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2849 + $time_ago_string = implode( ' ', $time_strings );
3319 2850
3320 - return implode( ' ', $time_strings );
2851 + return $time_ago_string;
3321 2852 }
3322 2853
3323 2854 /**
3324 2855 * @since 4.05.01
3325 - *
3326 - * @param string $unit
3327 - * @param array $diff
3328 - *
3329 - * @return int
3330 2856 */
3331 2857 private static function time_format( $unit, $diff ) {
3332 2858 $return = array(
3333 2859 'y' => 'y',
@@ -3332,14 +2858,14 @@
3332 2858 $return = array(
3333 2859 'y' => 'y',
3334 2860 'd' => 'days',
3335 2861 );
3336 -
3337 2862 if ( isset( $return[ $unit ] ) ) {
3338 2863 return $diff[ $return[ $unit ] ];
3339 2864 }
3340 2865
3341 2866 $total = $diff['days'] * self::convert_time( 'd', $unit );
2867 +
3342 2868 $times = array( 'h', 'i', 's' );
3343 2869
3344 2870 foreach ( $times as $time ) {
3345 2871 if ( ! isset( $diff[ $time ] ) ) {
@@ -3353,13 +2879,8 @@
3353 2879 }
3354 2880
3355 2881 /**
3356 2882 * @since 4.05.01
3357 - *
3358 - * @param string $from
3359 - * @param string $to
3360 - *
3361 - * @return int
3362 2883 */
3363 2884 private static function convert_time( $from, $to ) {
3364 2885 $convert = array(
3365 2886 's' => 1,
@@ -3375,26 +2896,20 @@
3375 2896 }
3376 2897
3377 2898 /**
3378 2899 * @since 4.05.01
3379 - *
3380 - * @param string $unit
3381 - *
3382 - * @return int|string
3383 2900 */
3384 2901 private static function get_unit( $unit ) {
3385 2902 $units = self::get_time_strings();
3386 -
3387 2903 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
3388 2904 return $unit;
3389 2905 }
3390 2906
3391 2907 foreach ( $units as $u => $strings ) {
3392 - if ( in_array( $unit, $strings, true ) ) {
2908 + if ( in_array( $unit, $strings ) ) {
3393 2909 return $u;
3394 2910 }
3395 2911 }
3396 -
3397 2912 return 1;
3398 2913 }
3399 2914
3400 2915 /**
@@ -3401,9 +2916,8 @@
3401 2916 * Get the translatable time strings. The untranslated version is a failsafe
3402 2917 * in case languages are changing for the unit set in the shortcode.
3403 2918 *
3404 2919 * @since 2.0.20
3405 - *
3406 2920 * @return array
3407 2921 */
3408 2922 private static function get_time_strings() {
3409 2923 return array(
@@ -3450,13 +2964,12 @@
3450 2964 /**
3451 2965 * @param int $r_count
3452 2966 * @param int $current_p
3453 2967 * @param int $p_size
3454 - *
3455 2968 * @return int
3456 2969 */
3457 2970 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
3458 - return $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size;
2971 + return ( $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size );
3459 2972 }
3460 2973
3461 2974 /**
3462 2975 * @param int $r_count
@@ -3461,13 +2974,11 @@
3461 2974 /**
3462 2975 * @param int $r_count
3463 2976 * @param int $current_p
3464 2977 * @param int $p_size
3465 - *
3466 2978 * @return int
3467 2979 */
3468 2980 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
3469 - // phpcs:ignore Universal.Operators.StrictComparisons
3470 2981 if ( $current_p == 1 ) {
3471 2982 return 1;
3472 2983 }
3473 2984 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
@@ -3473,22 +2984,17 @@
3473 2984 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
3474 2985 }
3475 2986
3476 2987 /**
3477 - * @param array $json_vars
3478 - *
3479 2988 * @return array
3480 2989 */
3481 2990 public static function json_to_array( $json_vars ) {
3482 2991 $vars = array();
3483 -
3484 2992 foreach ( $json_vars as $jv ) {
3485 2993 $jv_name = explode( '[', $jv['name'] );
3486 2994 $last = count( $jv_name ) - 1;
3487 -
3488 2995 foreach ( $jv_name as $p => $n ) {
3489 2996 $name = trim( $n, ']' );
3490 -
3491 2997 if ( ! isset( $l1 ) ) {
3492 2998 $l1 = $name;
3493 2999 }
3494 3000
@@ -3499,9 +3005,9 @@
3499 3005 if ( ! isset( $l3 ) ) {
3500 3006 $l3 = $name;
3501 3007 }
3502 3008
3503 - $this_val = $p === $last ? $jv['value'] : array();
3009 + $this_val = $p == $last ? $jv['value'] : array();
3504 3010
3505 3011 switch ( $p ) {
3506 3012 case 0:
3507 3013 $l1 = $name;
@@ -3534,15 +3040,10 @@
3534 3040
3535 3041 /**
3536 3042 * @param string $name
3537 3043 * @param string $l1
3538 - * @param mixed $val
3539 - * @param array $vars
3540 - *
3541 - * @return void
3542 3044 */
3543 3045 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
3544 - // phpcs:ignore Universal.Operators.StrictComparisons
3545 3046 if ( $name == '' ) {
3546 3047 $vars[] = $val;
3547 3048 } elseif ( ! isset( $vars[ $l1 ] ) ) {
3548 3049 $vars[ $l1 ] = $val;
@@ -3548,26 +3049,19 @@
3548 3049 $vars[ $l1 ] = $val;
3549 3050 }
3550 3051 }
3551 3052
3552 - /**
3553 - * @param string $name
3554 - * @param string $class
3555 - * @param string $form_name
3556 - *
3557 - * @return void
3558 - */
3559 3053 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
3560 3054 $tooltips = array(
3561 3055 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
3562 - 'email_to' => __( 'Add one or more recipient addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com. [default-email] is the address set in the global "Default Email Address" settings.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3056 + 'email_to' => __( 'Add one or more recipient addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com. [admin_email] is the address set in WP General Settings.', 'formidable' ),
3563 3057 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3564 3058 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3565 - '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' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3059 + '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' ),
3566 3060 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
3567 3061 /* translators: %1$s: Form name, %2$s: Date */
3568 - '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() ) ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3569 - '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' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3062 + '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() ) ),
3063 + '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' ),
3570 3064 );
3571 3065
3572 3066 if ( ! isset( $tooltips[ $name ] ) ) {
3573 3067 return;
@@ -3572,9 +3066,9 @@
3572 3066 if ( ! isset( $tooltips[ $name ] ) ) {
3573 3067 return;
3574 3068 }
3575 3069
3576 - if ( 'open' === $class ) {
3070 + if ( 'open' == $class ) {
3577 3071 echo ' frm_help"';
3578 3072 } else {
3579 3073 echo ' class="frm_help"';
3580 3074 }
@@ -3580,9 +3074,9 @@
3580 3074 }
3581 3075
3582 3076 echo ' title="' . esc_attr( $tooltips[ $name ] );
3583 3077
3584 - if ( 'open' !== $class ) {
3078 + if ( 'open' != $class ) {
3585 3079 echo '"';
3586 3080 }
3587 3081 }
3588 3082
@@ -3587,28 +3081,20 @@
3587 3081 }
3588 3082
3589 3083 /**
3590 3084 * Add the current_page class to that page in the form nav
3591 - *
3592 - * @param int|string $page
3593 - * @param int|string $current_page
3594 - * @param array $action
3595 - *
3596 - * @return void
3597 3085 */
3598 3086 public static function select_current_page( $page, $current_page, $action = array() ) {
3599 - // phpcs:ignore Universal.Operators.StrictComparisons
3600 3087 if ( $current_page != $page ) {
3601 3088 return;
3602 3089 }
3603 3090
3604 3091 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
3605 -
3606 3092 if ( 'lite-reports' === $frm_action ) {
3607 3093 $frm_action = 'reports';
3608 3094 }
3609 3095
3610 - if ( ! $action || ( $frm_action && in_array( $frm_action, $action, true ) ) ) {
3096 + if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
3611 3097 echo ' class="current_page"';
3612 3098 }
3613 3099 }
3614 3100
@@ -3638,19 +3124,14 @@
3638 3124
3639 3125 // Add extra slashes for \r\n since WP strips them.
3640 3126 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
3641 3127
3642 - // Allow for &quot
3643 - return str_replace( '&quot;', '\\"', $post_content );
3128 + // allow for &quot
3129 + $post_content = str_replace( '&quot;', '\\"', $post_content );
3130 +
3131 + return $post_content;
3644 3132 }
3645 3133
3646 - /**
3647 - * @param array|string $val
3648 - * @param int|string $key
3649 - * @param array $post_content
3650 - *
3651 - * @return void
3652 - */
3653 3134 private static function prepare_action_slashes( $val, $key, &$post_content ) {
3654 3135 if ( ! isset( $post_content[ $key ] ) || is_numeric( $val ) ) {
3655 3136 return;
3656 3137 }
@@ -3659,17 +3140,15 @@
3659 3140 foreach ( $val as $k1 => $v1 ) {
3660 3141 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
3661 3142 unset( $k1, $v1 );
3662 3143 }
3144 + } else {
3145 + // Strip all slashes so everything is the same, no matter where the value is coming from
3146 + $val = stripslashes( $val );
3663 3147
3664 - return;
3148 + // Add backslashes before double quotes and forward slashes only
3149 + $post_content[ $key ] = addcslashes( $val, '"\\/' );
3665 3150 }
3666 -
3667 - // Strip all slashes so everything is the same, no matter where the value is coming from
3668 - $val = stripslashes( $val );
3669 -
3670 - // Add backslashes before double quotes and forward slashes only
3671 - $post_content[ $key ] = addcslashes( $val, '"\\/' );
3672 3151 }
3673 3152
3674 3153 /**
3675 3154 * Check for either json or serialized data. This is temporary while transitioning
@@ -3677,9 +3156,8 @@
3677 3156 *
3678 3157 * @since 4.02.03
3679 3158 *
3680 3159 * @param array|string $value
3681 - *
3682 3160 * @return void
3683 3161 */
3684 3162 public static function unserialize_or_decode( &$value ) {
3685 3163 if ( is_array( $value ) ) {
@@ -3685,9 +3163,13 @@
3685 3163 if ( is_array( $value ) ) {
3686 3164 return;
3687 3165 }
3688 3166
3689 - $value = is_serialized( $value ) ? self::maybe_unserialize_array( $value ) : self::maybe_json_decode( $value, false );
3167 + if ( is_serialized( $value ) ) {
3168 + $value = self::maybe_unserialize_array( $value );
3169 + } else {
3170 + $value = self::maybe_json_decode( $value, false );
3171 + }
3690 3172 }
3691 3173
3692 3174 /**
3693 3175 * Safely unserialize an array if necessary.
@@ -3695,9 +3177,8 @@
3695 3177 *
3696 3178 * @since 6.2
3697 3179 *
3698 3180 * @param mixed $value
3699 - *
3700 3181 * @return mixed
3701 3182 */
3702 3183 public static function maybe_unserialize_array( $value ) {
3703 3184 if ( ! is_string( $value ) ) {
@@ -3704,15 +3185,18 @@
3704 3185 return $value;
3705 3186 }
3706 3187
3707 3188 // Since we only expect an array, skip anything that doesn't start with a:.
3708 - if ( ! is_serialized( $value ) || ! str_starts_with( $value, 'a:' ) ) {
3189 + if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
3709 3190 return $value;
3710 3191 }
3711 3192
3712 3193 $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
3194 + if ( is_array( $parsed ) ) {
3195 + $value = $parsed;
3196 + }
3713 3197
3714 - return is_array( $parsed ) ? $parsed : $value;
3198 + return $value;
3715 3199 }
3716 3200
3717 3201 /**
3718 3202 * Decode a JSON string.
@@ -3717,12 +3201,11 @@
3717 3201 /**
3718 3202 * Decode a JSON string.
3719 3203 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
3720 3204 *
3721 - * @param array|string|null $string
3722 - * @param bool $single_to_array
3723 - *
3724 - * @return array|string|null
3205 + * @param mixed $string
3206 + * @param bool $single_to_array
3207 + * @return mixed
3725 3208 */
3726 3209 public static function maybe_json_decode( $string, $single_to_array = true ) {
3727 3210 if ( is_array( $string ) || is_null( $string ) ) {
3728 3211 return $string;
@@ -3727,19 +3210,20 @@
3727 3210 if ( is_array( $string ) || is_null( $string ) ) {
3728 3211 return $string;
3729 3212 }
3730 3213
3731 - $new_string = json_decode( $string, true );
3732 - $single_value = false;
3733 -
3734 - if ( ! $single_to_array ) {
3735 - $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
3214 + $new_string = json_decode( $string, true );
3215 + if ( function_exists( 'json_last_error' ) ) {
3216 + // php 5.3+
3217 + $single_value = false;
3218 + if ( ! $single_to_array ) {
3219 + $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
3220 + }
3221 + if ( json_last_error() == JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3222 + $string = $new_string;
3223 + }
3736 3224 }
3737 3225
3738 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3739 - return $new_string;
3740 - }
3741 -
3742 3226 return $string;
3743 3227 }
3744 3228
3745 3229 /**
@@ -3745,9 +3229,8 @@
3745 3229 /**
3746 3230 * @since 6.2.3
3747 3231 *
3748 3232 * @param string $value
3749 - *
3750 3233 * @return string
3751 3234 */
3752 3235 public static function maybe_utf8_encode( $value ) {
3753 3236 $from_format = 'ISO-8859-1';
@@ -3756,15 +3239,13 @@
3756 3239 if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
3757 3240 if ( mb_check_encoding( $value, $from_format ) ) {
3758 3241 return mb_convert_encoding( $value, $to_format, $from_format );
3759 3242 }
3760 -
3761 3243 return $value;
3762 3244 }
3763 3245
3764 3246 if ( function_exists( 'iconv' ) ) {
3765 3247 $converted = iconv( $from_format, $to_format, $value );
3766 -
3767 3248 // Value is false if $value is not ISO-8859-1.
3768 3249 if ( false !== $converted ) {
3769 3250 return $converted;
3770 3251 }
@@ -3776,12 +3257,8 @@
3776 3257 /**
3777 3258 * Reformat the json serialized array in name => value array.
3778 3259 *
3779 3260 * @since 4.02.03
3780 - *
3781 - * @param array $form
3782 - *
3783 - * @return void
3784 3261 */
3785 3262 public static function format_form_data( &$form ) {
3786 3263 $formatted = array();
3787 3264
@@ -3788,21 +3265,18 @@
3788 3265 foreach ( $form as $input ) {
3789 3266 if ( ! isset( $input['name'] ) ) {
3790 3267 continue;
3791 3268 }
3792 -
3793 3269 $key = $input['name'];
3794 -
3795 - if ( ! isset( $formatted[ $key ] ) ) {
3270 + if ( isset( $formatted[ $key ] ) ) {
3271 + if ( is_array( $formatted[ $key ] ) ) {
3272 + $formatted[ $key ][] = $input['value'];
3273 + } else {
3274 + $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3275 + }
3276 + } else {
3796 3277 $formatted[ $key ] = $input['value'];
3797 - continue;
3798 3278 }
3799 -
3800 - if ( is_array( $formatted[ $key ] ) ) {
3801 - $formatted[ $key ][] = $input['value'];
3802 - } else {
3803 - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3804 - }
3805 3279 }
3806 3280
3807 3281 parse_str( http_build_query( $formatted ), $form );
3808 3282 }
@@ -3810,13 +3284,15 @@
3810 3284 /**
3811 3285 * @since 4.02.03
3812 3286 *
3813 3287 * @param array|string $value
3814 - *
3815 3288 * @return string
3816 3289 */
3817 3290 public static function maybe_json_encode( $value ) {
3818 - return is_array( $value ) ? wp_json_encode( $value ) : $value;
3291 + if ( is_array( $value ) ) {
3292 + $value = wp_json_encode( $value );
3293 + }
3294 + return $value;
3819 3295 }
3820 3296
3821 3297 /**
3822 3298 * Echo The javascript to open and highlight the Formidable menu
@@ -3823,19 +3299,18 @@
3823 3299 *
3824 3300 * @since 1.07.10
3825 3301 *
3826 3302 * @param string $post_type The name of the post type that may need to be highlighted.
3827 - *
3828 3303 * @return void
3829 3304 */
3830 3305 public static function maybe_highlight_menu( $post_type ) {
3831 3306 global $post;
3832 3307
3833 - if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] !== $post_type ) {
3308 + if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
3834 3309 return;
3835 3310 }
3836 3311
3837 - if ( is_object( $post ) && $post->post_type !== $post_type ) {
3312 + if ( is_object( $post ) && $post->post_type != $post_type ) {
3838 3313 return;
3839 3314 }
3840 3315
3841 3316 self::load_admin_wide_js();
@@ -3847,13 +3322,13 @@
3847 3322 *
3848 3323 * @since 2.0
3849 3324 *
3850 3325 * @param bool $load
3851 - *
3852 3326 * @return void
3853 3327 */
3854 3328 public static function load_admin_wide_js( $load = true ) {
3855 - wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), self::plugin_version() );
3329 + $version = self::plugin_version();
3330 + wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
3856 3331
3857 3332 $global_strings = array(
3858 3333 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
3859 3334 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
@@ -3859,9 +3334,9 @@
3859 3334 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
3860 3335 'url' => self::plugin_url(),
3861 3336 'app_url' => 'https://formidableforms.com/',
3862 3337 'applicationsUrl' => admin_url( 'admin.php?page=formidable-applications' ),
3863 - 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3338 + 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ),
3864 3339 'loading' => __( 'Loading&hellip;', 'formidable' ),
3865 3340 'nonce' => wp_create_nonce( 'frm_ajax' ),
3866 3341 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
3867 3342 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(),
@@ -3874,9 +3349,8 @@
3874 3349 }
3875 3350
3876 3351 /**
3877 3352 * @since 2.0.9
3878 - *
3879 3353 * @return void
3880 3354 */
3881 3355 public static function load_font_style() {
3882 3356 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
@@ -3883,9 +3357,8 @@
3883 3357 }
3884 3358
3885 3359 /**
3886 3360 * @param string $location
3887 - *
3888 3361 * @return void
3889 3362 */
3890 3363 public static function localize_script( $location ) {
3891 3364 global $wp_scripts, $wp_version;
@@ -3908,9 +3381,8 @@
3908 3381 'include_resend_email' => false,
3909 3382 );
3910 3383
3911 3384 $data = $wp_scripts->get_data( 'formidable', 'data' );
3912 -
3913 3385 if ( ! $data ) {
3914 3386 wp_localize_script( 'formidable', 'frm_js', $script_strings );
3915 3387 }
3916 3388
@@ -3917,9 +3389,9 @@
3917 3389 if ( $location === 'admin' ) {
3918 3390 $admin_script_strings = array(
3919 3391 'desc' => __( '(Click to add description)', 'formidable' ),
3920 3392 'blank' => __( '(Blank)', 'formidable' ),
3921 - 'no_label' => self::get_no_label_text(),
3393 + 'no_label' => __( '(no label)', 'formidable' ),
3922 3394 'ok' => __( 'OK', 'formidable' ),
3923 3395 'cancel' => __( 'Cancel', 'formidable' ),
3924 3396 'default_label' => __( 'Default', 'formidable' ),
3925 3397 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3927,9 +3399,9 @@
3927 3399 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3928 3400 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3929 3401 'confirm' => __( 'Are you sure?', 'formidable' ),
3930 3402 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3931 - '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' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3403 + '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' ),
3932 3404 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3933 3405 'default_unique' => FrmFieldsHelper::default_unique_msg(),
3934 3406 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3935 3407 'enter_email' => __( 'Enter Email', 'formidable' ),
@@ -3935,9 +3407,9 @@
3935 3407 'enter_email' => __( 'Enter Email', 'formidable' ),
3936 3408 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3937 3409 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3938 3410 'new_option' => __( 'New Option', 'formidable' ),
3939 - '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' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3411 + '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' ),
3940 3412 'enter_password' => __( 'Enter Password', 'formidable' ),
3941 3413 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3942 3414 'import_complete' => __( 'Import Complete', 'formidable' ),
3943 3415 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
@@ -3953,11 +3425,11 @@
3953 3425 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ),
3954 3426 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ),
3955 3427 'unsafe_params' => FrmFormsHelper::reserved_words(),
3956 3428 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
3957 - 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3429 + 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
3958 3430 /* 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. */
3959 - 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3431 + 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
3960 3432 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3961 3433 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3962 3434 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3963 3435 'install' => __( 'Install', 'formidable' ),
@@ -3978,14 +3450,11 @@
3978 3450 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
3979 3451 'noTitleText' => FrmFormsHelper::get_no_title_text(),
3980 3452
3981 3453 // In older versions this event listener causes the section to immediately close again
3982 - // When the h3 element is clicked. It's only required in WP 6.7+.
3454 + // when the h3 element is clicked. It's only required in WP 6.7+.
3983 3455 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ),
3984 3456 );
3985 -
3986 - self::add_form_builder_modal_data( $admin_script_strings );
3987 -
3988 3457 /**
3989 3458 * @param array $admin_script_strings
3990 3459 */
3991 3460 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
@@ -3990,9 +3459,8 @@
3990 3459 */
3991 3460 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3992 3461
3993 3462 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
3994 -
3995 3463 if ( ! $data ) {
3996 3464 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
3997 3465 }
3998 3466 }//end if
@@ -3998,86 +3466,8 @@
3998 3466 }//end if
3999 3467 }
4000 3468
4001 3469 /**
4002 - * @param array $admin_script_strings
4003 - *
4004 - * @return void
4005 - */
4006 - private static function add_form_builder_modal_data( &$admin_script_strings ) {
4007 - if ( ! self::is_form_builder_page() || self::pro_is_installed() ) {
4008 - return;
4009 - }
4010 -
4011 - $stripe_connected = FrmStrpLiteConnectHelper::at_least_one_mode_is_setup();
4012 - $square_connected = FrmSquareLiteConnectHelper::at_least_one_mode_is_setup();
4013 - $gateway_connected = $stripe_connected || $square_connected;
4014 - $payments_settings_url = FrmStrpLiteAppController::get_payments_settings_url();
4015 -
4016 - if ( ! $gateway_connected ) {
4017 - // This modal shows when user clicks on one of the pricing fields and no payment gateways configured.
4018 - $admin_script_strings['paymentsSettingsModal'] = array(
4019 - 'title' => __( 'Setup a Payment Gateway first', 'formidable' ),
4020 - 'msg' => __( 'To use the payment fields, please install and configure a payment gateway in your account settings.', 'formidable' ),
4021 - 'closeText' => __( 'Close', 'formidable' ),
4022 - 'actionUrl' => $payments_settings_url,
4023 - 'actionText' => __( 'Go to Payment Settings', 'formidable' ),
4024 - 'noCenter' => true,
4025 - );
4026 - }
4027 -
4028 - // This modal shows on load once after upgrading the plugin.
4029 - $show_pricing_fields_modal = get_option( 'frm_show_pricing_fields_modal' );
4030 -
4031 - if ( ! $show_pricing_fields_modal ) {
4032 - return;
4033 - }
4034 -
4035 - $admin_script_strings['pricingFieldsModal'] = array(
4036 - 'title' => esc_html__( 'Start Accepting Payments Today!', 'formidable' ),
4037 - 'img' => esc_url( self::plugin_url() . '/images/upsell/pricing-fields.png' ),
4038 - 'noCenter' => true,
4039 - );
4040 -
4041 - if ( $gateway_connected ) {
4042 - $gateway_texts = array();
4043 -
4044 - if ( $stripe_connected ) {
4045 - $gateway_texts['stripe'] = esc_html__( 'Stripe', 'formidable' );
4046 - }
4047 -
4048 - if ( $square_connected ) {
4049 - $gateway_texts['square'] = esc_html__( 'Square', 'formidable' );
4050 - }
4051 -
4052 - $admin_script_strings['pricingFieldsModal']['msg'] = sprintf(
4053 - // translators: %s: Stripe or Square.
4054 - esc_html__( 'You already have %s connected, so these have already been unlocked.', 'formidable' ),
4055 - esc_html( implode( ' ' . esc_html__( 'and', 'formidable' ) . ' ', $gateway_texts ) )
4056 - );
4057 - } else {
4058 - $admin_script_strings['pricingFieldsModal']['closeText'] = __( 'I\'ll do it later!', 'formidable' );
4059 - $admin_script_strings['pricingFieldsModal']['actionText'] = __( 'Setup Payments Now', 'formidable' );
4060 - $admin_script_strings['pricingFieldsModal']['actionUrl'] = $payments_settings_url;
4061 - // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4062 - $admin_script_strings['pricingFieldsModal']['msg'] = __( 'We\'ve unlocked Product, Quantity, and Total fields for Lite users! You can now transform your forms into checkout pages. To start collecting revenue, simply connect your preferred payment gateway (Stripe, or Square) in your settings.', 'formidable' );
4063 - }//end if
4064 -
4065 - delete_option( 'frm_show_pricing_fields_modal' );
4066 - }
4067 -
4068 - /**
4069 - * Get the no label text.
4070 - *
4071 - * @since 6.25.1
4072 - *
4073 - * @return string
4074 - */
4075 - public static function get_no_label_text() {
4076 - return __( '(no label)', 'formidable' );
4077 - }
4078 -
4079 - /**
4080 3470 * @since 6.5
4081 3471 *
4082 3472 * @return string
4083 3473 */
@@ -4119,9 +3509,8 @@
4119 3509 *
4120 3510 * @since 1.07.10
4121 3511 *
4122 3512 * @param float $min_version The version the add-on requires.
4123 - *
4124 3513 * @return void
4125 3514 */
4126 3515 public static function min_version_notice( $min_version ) {
4127 3516 $frm_version = self::plugin_version();
@@ -4131,11 +3520,11 @@
4131 3520 return;
4132 3521 }
4133 3522
4134 3523 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
4135 - echo '<tr class="plugin-update-tr active"><th colspan="' . absint( $wp_list_table->get_column_count() ) . '" class="check-column plugin-update colspanchange"><div class="update-message">' . // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4136 - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
4137 - '</div></td></tr>';
3524 + echo '<tr class="plugin-update-tr active"><th colspan="' . absint( $wp_list_table->get_column_count() ) . '" class="check-column plugin-update colspanchange"><div class="update-message">' .
3525 + esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
3526 + '</div></td></tr>';
4138 3527 }
4139 3528
4140 3529 /**
4141 3530 * If Pro is far outdated, show a message.
@@ -4141,10 +3530,8 @@
4141 3530 * If Pro is far outdated, show a message.
4142 3531 *
4143 3532 * @since 4.0.01
4144 3533 *
4145 - * @param string $min_version
4146 - *
4147 3534 * @return void
4148 3535 */
4149 3536 public static function min_pro_version_notice( $min_version ) {
4150 3537 if ( ! self::is_formidable_admin() ) {
@@ -4154,14 +3541,25 @@
4154 3541
4155 3542 self::php_version_notice();
4156 3543
4157 3544 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
4158 -
4159 3545 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
4160 3546 return;
4161 3547 }
4162 3548
4163 - include self::plugin_path() . '/classes/views/addons/min-version-notice.php';
3549 + $expired = FrmAddonsController::is_license_expired();
3550 + ?>
3551 + <div class="frm-banner-alert frm_error_style frm_previous_install">
3552 + <?php
3553 + esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
3554 + if ( empty( $expired ) ) {
3555 + echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
3556 + } else {
3557 + echo '<br/>Please <a href="https://formidableforms.com/account/downloads/?utm_source=WordPress&utm_medium=outdated">renew now</a> to get the latest version.';
3558 + }
3559 + ?>
3560 + </div>
3561 + <?php
4164 3562 }
4165 3563
4166 3564 /**
4167 3565 * If Pro is installed, check the version number.
@@ -4168,9 +3566,8 @@
4168 3566 *
4169 3567 * @since 4.0.01
4170 3568 *
4171 3569 * @param string $min_version
4172 - *
4173 3570 * @return bool
4174 3571 */
4175 3572 public static function meets_min_pro_version( $min_version ) {
4176 3573 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
@@ -4179,19 +3576,16 @@
4179 3576 /**
4180 3577 * Show a message if the PHP version is below the recommendations.
4181 3578 *
4182 3579 * @since 4.0.02
4183 - *
4184 3580 * @return void
4185 3581 */
4186 3582 private static function php_version_notice() {
4187 3583 $message = array();
4188 -
4189 3584 if ( version_compare( phpversion(), '7.0', '<' ) ) {
4190 - $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3585 + $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' );
4191 3586 }
4192 3587
4193 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4194 3588 foreach ( $message as $m ) {
4195 3589 ?>
4196 3590 <div class="frm-banner-alert frm_error_style frm_previous_install">
4197 3591 <?php echo esc_html( $m ); ?>
@@ -4197,14 +3591,12 @@
4197 3591 <?php echo esc_html( $m ); ?>
4198 3592 </div>
4199 3593 <?php
4200 3594 }
4201 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4202 3595 }
4203 3596
4204 3597 /**
4205 3598 * @param string $type
4206 - *
4207 3599 * @return array<string,string>
4208 3600 */
4209 3601 public static function locales( $type = 'date' ) {
4210 3602 $locales = array(
@@ -4298,12 +3690,12 @@
4298 3690 'zu' => __( 'Zulu', 'formidable' ),
4299 3691 );
4300 3692
4301 3693 if ( $type === 'captcha' ) {
4302 - // Remove the languages unavailable for the captcha
3694 + // remove the languages unavailable for the captcha
4303 3695 $unset = array( 'sq', 'bs', 'eo', 'fo', 'fr-CH', 'sr-SR', 'ar-DZ', 'be', 'cy-GB', 'kk', 'km', 'ky', 'lb', 'mk', 'nb', 'nn', 'rm', 'tj' );
4304 3696 } else {
4305 - // Remove the languages unavailable for the datepicker
3697 + // remove the languages unavailable for the datepicker
4306 3698 $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' );
4307 3699 }
4308 3700
4309 3701 $locales = array_diff_key( $locales, array_flip( $unset ) );
@@ -4314,13 +3706,14 @@
4314 3706 * @since 5.4.5 Added $args parameter with type.
4315 3707 *
4316 3708 * @param array<string,string> $locales
4317 3709 * @param array $args {
4318 - *
4319 3710 * @type string $type
4320 3711 * }
4321 3712 */
4322 - return apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3713 + $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3714 +
3715 + return $locales;
4323 3716 }
4324 3717
4325 3718 /**
4326 3719 * @return string
@@ -4327,14 +3720,12 @@
4327 3720 */
4328 3721 public static function get_menu_icon_class() {
4329 3722 if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
4330 3723 $settings = FrmProAppHelper::get_settings();
4331 -
4332 3724 if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
4333 3725 return $settings->menu_icon;
4334 3726 }
4335 3727 }
4336 -
4337 3728 return 'frmfont frm_logo_icon';
4338 3729 }
4339 3730
4340 3731 /**
@@ -4352,9 +3743,10 @@
4352 3743 * @type array $input_attrs Attributes of value input.
4353 3744 * }
4354 3745 */
4355 3746 public static function images_dropdown( $args ) {
4356 - $args = self::fill_default_images_dropdown_args( $args );
3747 + $args = self::fill_default_images_dropdown_args( $args );
3748 +
4357 3749 $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
4358 3750 ob_start();
4359 3751 include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
4360 3752 $output = ob_get_clean();
@@ -4375,9 +3767,8 @@
4375 3767 *
4376 3768 * @since 5.0.04
4377 3769 *
4378 3770 * @param array $args The arguments.
4379 - *
4380 3771 * @return array
4381 3772 */
4382 3773 private static function fill_default_images_dropdown_args( $args ) {
4383 3774 $defaults = array(
@@ -4390,8 +3781,14 @@
4390 3781
4391 3782 $new_args['options'] = (array) $new_args['options'];
4392 3783 $new_args['input_attrs'] = (array) $new_args['input_attrs'];
4393 3784
3785 + // Set the number of columns.
3786 + $new_args['col_class'] = ceil( 12 / count( $new_args['options'] ) );
3787 + if ( $new_args['col_class'] > 6 ) {
3788 + $new_args['col_class'] = ceil( $new_args['col_class'] / 2 );
3789 + }
3790 +
4394 3791 /**
4395 3792 * Allows modifying the arguments of images_dropdown() method.
4396 3793 *
4397 3794 * @since 5.0.04
@@ -4407,9 +3804,8 @@
4407 3804 *
4408 3805 * @since 5.0.04
4409 3806 *
4410 3807 * @param array $args The arguments.
4411 - *
4412 3808 * @return string
4413 3809 */
4414 3810 private static function get_images_dropdown_input_attrs( $args ) {
4415 3811 $input_attrs = $args['input_attrs'];
@@ -4416,9 +3812,8 @@
4416 3812 $input_attrs['type'] = 'radio';
4417 3813 $input_attrs['name'] = $args['name'];
4418 3814
4419 3815 $input_attrs_str = '';
4420 -
4421 3816 foreach ( $input_attrs as $key => $input_attr ) {
4422 3817 $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
4423 3818 }
4424 3819
@@ -4434,13 +3829,8 @@
4434 3829 }
4435 3830
4436 3831 /**
4437 3832 * @since 6.7.1
4438 - *
4439 - * @param array $option Option data.
4440 - * @param array $args The arguments of images_dropdown() method.
4441 - *
4442 - * @return array
4443 3833 */
4444 3834 public static function get_images_dropdown_atts( $option, $args ) {
4445 3835 $image = self::get_images_dropdown_option_image( $option, $args );
4446 3836 $classes = self::get_images_dropdown_option_classes( $option, $args );
@@ -4454,9 +3844,8 @@
4454 3844 * @since 5.0.04
4455 3845 *
4456 3846 * @param array $option Option data.
4457 3847 * @param array $args The arguments of images_dropdown() method.
4458 - *
4459 3848 * @return string
4460 3849 */
4461 3850 private static function get_images_dropdown_option_image( $option, $args ) {
4462 3851 $image = self::icon_by_class(
@@ -4485,9 +3874,8 @@
4485 3874 * @since 5.0.04
4486 3875 *
4487 3876 * @param array $option Option data.
4488 3877 * @param array $args The arguments of images_dropdown() method.
4489 - *
4490 3878 * @return string
4491 3879 */
4492 3880 private static function get_images_dropdown_option_classes( $option, $args ) {
4493 3881 $classes = '';
@@ -4515,19 +3903,17 @@
4515 3903 * @since 5.0.04
4516 3904 *
4517 3905 * @param array $option Option data.
4518 3906 * @param array $args The arguments of images_dropdown() method.
4519 - *
4520 3907 * @return string
4521 3908 */
4522 3909 private static function get_images_dropdown_option_html_attrs( $option, $args ) {
4523 3910 $html_attrs = '';
4524 -
4525 3911 if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
4526 3912 $html_attrs_arr = array();
4527 3913
4528 3914 foreach ( $option['custom_attrs'] as $key => $value ) {
4529 - if ( in_array( $key, array( 'type', 'class', 'data-value' ), true ) ) {
3915 + if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
4530 3916 continue;
4531 3917 }
4532 3918
4533 3919 $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
@@ -4585,13 +3971,14 @@
4585 3971 * @since 5.0.07
4586 3972 *
4587 3973 * @param array $values
4588 3974 * @param array $keys
4589 - *
4590 3975 * @return array
4591 3976 */
4592 3977 public static function maybe_filter_array( $values, $keys ) {
4593 - if ( self::allow_unfiltered_html() ) {
3978 + $allow_unfiltered_html = self::allow_unfiltered_html();
3979 +
3980 + if ( $allow_unfiltered_html ) {
4594 3981 return $values;
4595 3982 }
4596 3983
4597 3984 foreach ( $keys as $key ) {
@@ -4610,14 +3997,13 @@
4610 3997 * @since 5.0.13
4611 3998 *
4612 3999 * @param string $value
4613 4000 * @param array|string $allowed 'all' for everything included as defaults.
4614 - *
4615 4001 * @return string
4616 4002 */
4617 4003 public static function maybe_kses( $value, $allowed = 'all' ) {
4618 4004 if ( self::should_never_allow_unfiltered_html() ) {
4619 - return self::kses( $value, $allowed );
4005 + $value = self::kses( $value, $allowed );
4620 4006 }
4621 4007 return $value;
4622 4008 }
4623 4009
@@ -4627,18 +4013,17 @@
4627 4013 * @since 6.11.2
4628 4014 *
4629 4015 * @param string $key
4630 4016 * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed.
4631 - *
4632 4017 * @return bool
4633 4018 */
4634 4019 public static function input_key_is_safe( $key, $context = 'display' ) {
4635 4020 if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) {
4636 4021 $safe = true;
4637 - } elseif ( str_starts_with( $key, 'data-' ) ) {
4022 + } elseif ( 0 === strpos( $key, 'data-' ) ) {
4638 4023 // Allow all data attributes.
4639 4024 $safe = true;
4640 - } elseif ( str_starts_with( $key, 'aria-' ) ) {
4025 + } elseif ( 0 === strpos( $key, 'aria-' ) ) {
4641 4026 // Allow all aria attributes.
4642 4027 $safe = true;
4643 4028 } else {
4644 4029 $safe_keys = array(
@@ -4680,9 +4065,16 @@
4680 4065
4681 4066 /**
4682 4067 * @since 5.0.16
4683 4068 *
4684 - * @param string $medium
4069 + * @return bool
4070 + */
4071 + public static function show_landing_pages() {
4072 + return self::show_new_feature( 'landing' );
4073 + }
4074 +
4075 + /**
4076 + * @since 5.0.16
4685 4077 *
4686 4078 * @return array
4687 4079 */
4688 4080 public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
@@ -4690,9 +4082,8 @@
4690 4082 'medium' => $medium,
4691 4083 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
4692 4084 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
4693 4085 'screenshot' => 'landing.png',
4694 - 'learn-more' => self::get_doc_url( 'landing-page-forms', 'form-landing-page-settings', false ),
4695 4086 );
4696 4087 return self::get_upgrade_data_params( 'landing', $params );
4697 4088 }
4698 4089
@@ -4699,9 +4090,8 @@
4699 4090 /**
4700 4091 * @since 5.0.17
4701 4092 *
4702 4093 * @param string $feature
4703 - *
4704 4094 * @return bool
4705 4095 */
4706 4096 public static function show_new_feature( $feature ) {
4707 4097 $link = FrmAddonsController::install_link( $feature );
@@ -4708,21 +4098,16 @@
4708 4098 return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
4709 4099 }
4710 4100
4711 4101 /**
4712 - * Enhances upgrade data parameters with installation link and plan requirement information.
4713 - *
4714 4102 * @since 5.0.17
4715 4103 *
4716 - * @param string $plugin The plugin slug to get installation data for.
4717 - * @param array $params Initial parameters for the upgrade data.
4718 - * @param bool $detailed Whether to include detailed information.
4719 - *
4720 - * @return array Modified parameters with installation data.
4104 + * @param string $plugin
4105 + * @param array $params
4106 + * @return array
4721 4107 */
4722 - public static function get_upgrade_data_params( $plugin, $params, $detailed = false ) {
4108 + public static function get_upgrade_data_params( $plugin, $params ) {
4723 4109 $link = FrmAddonsController::install_link( $plugin );
4724 -
4725 4110 if ( ! $link ) {
4726 4111 return $params;
4727 4112 }
4728 4113
@@ -4728,20 +4113,15 @@
4728 4113
4729 4114 if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
4730 4115 $params['oneclick'] = json_encode( $link );
4731 4116 unset( $params['message'] );
4732 -
4733 4117 if ( ! isset( $params['medium'] ) ) {
4734 4118 $params['medium'] = $plugin;
4735 4119 }
4736 4120 } else {
4737 - $params['requires'] = $params['requires'] ?? FrmFormsHelper::get_plan_required( $link );
4121 + $params['requires'] = FrmFormsHelper::get_plan_required( $link );
4738 4122 }
4739 4123
4740 - if ( $detailed ) {
4741 - $params['plugin-status'] = $link['status'] ?? '';
4742 - }
4743 -
4744 4124 return $params;
4745 4125 }
4746 4126
4747 4127 /**
@@ -4750,9 +4130,8 @@
4750 4130 *
4751 4131 * @since 5.0.17
4752 4132 *
4753 4133 * @param string $text
4754 - *
4755 4134 * @return bool
4756 4135 */
4757 4136 public static function ctype_xdigit( $text ) {
4758 4137 if ( function_exists( 'ctype_xdigit' ) ) {
@@ -4767,14 +4146,12 @@
4767 4146 * @since 5.2.01
4768 4147 */
4769 4148 public static function set_current_screen_and_hook_suffix() {
4770 4149 global $hook_suffix;
4771 -
4772 4150 if ( is_null( $hook_suffix ) ) {
4773 4151 // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
4774 4152 $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
4775 4153 }
4776 -
4777 4154 set_current_screen();
4778 4155 }
4779 4156
4780 4157 /**
@@ -4781,9 +4158,9 @@
4781 4158 * Shows pill text.
4782 4159 *
4783 4160 * @since 5.2.02
4784 4161 *
4785 - * @param string|null $text Text in the pill. Default is NEW.
4162 + * @param string $text Text in the pill. Default is NEW.
4786 4163 */
4787 4164 public static function show_pill_text( $text = null ) {
4788 4165 if ( null === $text ) {
4789 4166 $text = __( 'NEW', 'formidable' );
@@ -4796,9 +4173,8 @@
4796 4173 *
4797 4174 * @since 5.2.07
4798 4175 *
4799 4176 * @param mixed $num Number.
4800 - *
4801 4177 * @return false|int Returns `false` if the passed parameter is not number.
4802 4178 */
4803 4179 public static function count_decimals( $num ) {
4804 4180 if ( ! is_numeric( $num ) ) {
@@ -4806,9 +4182,8 @@
4806 4182 }
4807 4183
4808 4184 $num = (string) $num;
4809 4185 $parts = explode( '.', $num );
4810 -
4811 4186 if ( 1 === count( $parts ) ) {
4812 4187 return 0;
4813 4188 }
4814 4189
@@ -4890,20 +4265,17 @@
4890 4265 * @since 5.5.5
4891 4266 *
4892 4267 * @param string $url
4893 4268 * @param string $expected_extension
4894 - *
4895 4269 * @return bool
4896 4270 */
4897 4271 public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
4898 - $file_is_in_expected_s3_bucket = str_starts_with( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4899 -
4272 + $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4900 4273 if ( ! $file_is_in_expected_s3_bucket ) {
4901 4274 return false;
4902 4275 }
4903 4276
4904 4277 $parsed = parse_url( $url );
4905 -
4906 4278 if ( ! is_array( $parsed ) ) {
4907 4279 // URL is malformed.
4908 4280 return false;
4909 4281 }
@@ -4909,10 +4281,14 @@
4909 4281 }
4910 4282
4911 4283 $path = $parsed['path'];
4912 4284 $ext = pathinfo( $path, PATHINFO_EXTENSION );
4913 - // The URL isn't to an XML file.
4914 - return $expected_extension === $ext;
4285 + if ( $expected_extension !== $ext ) {
4286 + // The URL isn't to an XML file.
4287 + return false;
4288 + }
4289 +
4290 + return true;
4915 4291 }
4916 4292
4917 4293 /**
4918 4294 * Display a dismissable warning message and save its dismissal state.
@@ -4920,9 +4296,8 @@
4920 4296 * @since 6.3
4921 4297 *
4922 4298 * @param string $message The warning message to display.
4923 4299 * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
4924 - *
4925 4300 * @return void
4926 4301 */
4927 4302 public static function add_dismissable_warning_message( $message = '', $option = '' ) {
4928 4303 if ( ! $message || ! $option ) {
@@ -4965,9 +4340,8 @@
4965 4340 *
4966 4341 * @since 6.3
4967 4342 *
4968 4343 * @param string $option The unique identifier for the dismissal state of the message.
4969 - *
4970 4344 * @return void
4971 4345 */
4972 4346 public static function dismiss_warning_message( $option = '' ) {
4973 4347 self::permission_check( 'frm_change_settings' );
@@ -4973,9 +4347,9 @@
4973 4347 self::permission_check( 'frm_change_settings' );
4974 4348 check_ajax_referer( 'frm_ajax', 'nonce' );
4975 4349
4976 4350 if ( $option ) {
4977 - update_option( $option, true, false );
4351 + update_option( $option, true, 'no' );
4978 4352 }
4979 4353
4980 4354 wp_send_json_success();
4981 4355 }
@@ -4989,8 +4363,17 @@
4989 4363 * @return string
4990 4364 */
4991 4365 public static function copy_for_lite_license() {
4992 4366 $message = __( 'You\'re using Formidable Forms Lite - no license needed. Enjoy!', 'formidable' ) . ' 🙂';
4367 +
4368 + if ( is_callable( 'FrmProAddonsController::get_readable_license_type' ) && ! class_exists( 'FrmProDashboardController' ) ) {
4369 + // Manage PRO versions without PRO dashboard functionality.
4370 + $license_type = FrmProAddonsController::get_readable_license_type();
4371 + if ( 'lite' !== strtolower( $license_type ) ) {
4372 + $message = 'Formidable Pro ' . $license_type;
4373 + }
4374 + }
4375 +
4993 4376 return apply_filters( 'frm_license_type_text', $message );
4994 4377 }
4995 4378
4996 4379 /**
@@ -4996,9 +4379,8 @@
4996 4379 /**
4997 4380 * Removes scripts that are unnecessarily loaded across the pages!
4998 4381 *
4999 4382 * @since 6.9
5000 - *
5001 4383 * @return void
5002 4384 */
5003 4385 public static function dequeue_extra_global_scripts() {
5004 4386 wp_dequeue_script( 'frm-surveys-admin' );
@@ -5016,21 +4398,18 @@
5016 4398 * @return void
5017 4399 */
5018 4400 public static function tooltip_icon( $tooltip_text, $atts = array() ) {
5019 4401 $atts['title'] = $tooltip_text;
5020 -
5021 4402 if ( isset( $atts['class'] ) ) {
5022 4403 $atts['class'] .= ' frm_help';
5023 4404 } else {
5024 4405 $atts['class'] = 'frm_help';
5025 4406 }
5026 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5027 4407 ?>
5028 4408 <span <?php self::array_to_html_params( $atts, true ); ?>>
5029 4409 <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?>
5030 4410 </span>
5031 4411 <?php
5032 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5033 4412 }
5034 4413
5035 4414 /**
5036 4415 * Prints errors for settings in onboarding wizard or template settings.
@@ -5051,10 +4430,8 @@
5051 4430 )
5052 4431 );
5053 4432
5054 4433 $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden';
5055 -
5056 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5057 4434 ?>
5058 4435 <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>">
5059 4436 <?php
5060 4437 if ( is_array( $args['errors'] ) ) {
@@ -5068,9 +4445,8 @@
5068 4445 }
5069 4446 ?>
5070 4447 </span>
5071 4448 <?php
5072 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5073 4449 }
5074 4450
5075 4451 /**
5076 4452 * Check if GDPR is enabled.
@@ -5093,57 +4469,6 @@
5093 4469 */
5094 4470 public static function no_gdpr_cookies() {
5095 4471 $frm_settings = self::get_settings();
5096 4472 return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies;
5097 - }
5098 -
5099 - /**
5100 - * Check if a string is valid UTF-8.
5101 - *
5102 - * @since 6.24
5103 - *
5104 - * @param string $string The string to check.
5105 - *
5106 - * @return bool
5107 - */
5108 - public static function is_valid_utf8( $string ) {
5109 - // wp_is_valid_utf8 is added in WP 6.9.
5110 - if ( function_exists( 'wp_is_valid_utf8' ) ) {
5111 - return wp_is_valid_utf8( $string );
5112 - }
5113 -
5114 - // As of WP 6.9, seems_utf8 is deprecated.
5115 - return function_exists( 'seems_utf8' ) ? seems_utf8( $string ) : false;
5116 - }
5117 -
5118 - /**
5119 - * Get a documentation URL with UTM parameters and affiliate tracking.
5120 - *
5121 - * @since 6.26
5122 - *
5123 - * @param string $path The relative path to append to the base URL.
5124 - * @param string $campaign The campaign to use for UTM parameters.
5125 - * @param bool $add_kb_base Whether to prepend 'knowledgebase/' to the path. Default true.
5126 - *
5127 - * @return string The processed URL with UTM parameters and affiliate tracking.
5128 - */
5129 - public static function get_doc_url( $path, $campaign, $add_kb_base = true ) {
5130 - $path = trim( $path, '/' );
5131 -
5132 - if ( $add_kb_base ) {
5133 - $path = 'knowledgebase/' . $path;
5134 - }
5135 -
5136 - return self::maybe_add_missing_utm( 'https://formidableforms.com/' . $path, array( 'campaign' => $campaign ) );
5137 - }
5138 -
5139 - /**
5140 - * @since 5.0.16
5141 - * @deprecated 6.26
5142 - *
5143 - * @return bool
5144 - */
5145 - public static function show_landing_pages() {
5146 - _deprecated_function( __METHOD__, '6.26' );
5147 - return true;
5148 4473 }
5149 4474 }