PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.22.1
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.22.1
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 +461 -1052 6.356.22.1 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 = 106;
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.35';
32 + public static $plug_version = '6.22.1';
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,124 +114,55 @@
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 = isset( $args['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 165 * @since 6.21
238 166 *
239 167 * @param string $cta_link
240 168 * @param array $utm
@@ -239,29 +167,26 @@
239 167 * @param string $cta_link
240 168 * @param array $utm
241 169 */
242 170 public static function maybe_add_missing_utm( $cta_link, $utm ) {
243 - $utm = self::adjust_legacy_utm_args( $utm );
244 171 $query_args = array();
245 172
246 - if ( ! str_contains( $cta_link, 'utm_source' ) ) {
247 - $query_args['utm_source'] = 'plugin';
173 + if ( false === strpos( $cta_link, 'utm_source' ) ) {
174 + $query_args['utm_source'] = 'WordPress';
248 175 }
249 176
250 - if ( ! str_contains( $cta_link, 'utm_medium' ) ) {
251 - $query_args['utm_medium'] = self::get_utm_medium();
177 + if ( false === strpos( $cta_link, 'utm_campaign' ) ) {
178 + $query_args['utm_campaign'] = 'liteplugin';
252 179 }
253 180
254 - if ( ! str_contains( $cta_link, 'utm_campaign' ) && isset( $utm['campaign'] ) ) {
255 - $query_args['utm_campaign'] = $utm['campaign'];
181 + if ( false === strpos( $cta_link, 'utm_medium' ) && isset( $utm['medium'] ) ) {
182 + $query_args['utm_medium'] = $utm['medium'];
256 183 }
257 184
258 - if ( ! str_contains( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) {
185 + if ( false === strpos( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) {
259 186 $query_args['utm_content'] = $utm['content'];
260 187 }
261 188
262 - $query_args = self::maybe_add_utm_license( $query_args, $cta_link );
263 -
264 189 return $query_args ? add_query_arg( $query_args, $cta_link ) : $cta_link;
265 190 }
266 191
267 192 /**
@@ -269,15 +194,13 @@
269 194 *
270 195 * @since 2.0
271 196 *
272 197 * @param array $args - May include the form id when values need translation.
273 - *
274 - * @return FrmSettings
198 + * @return FrmSettings $frm_settings
275 199 */
276 200 public static function get_settings( $args = array() ) {
277 201 global $frm_settings;
278 -
279 - if ( ! $frm_settings ) {
202 + if ( empty( $frm_settings ) ) {
280 203 $frm_settings = new FrmSettings( $args );
281 204 } elseif ( isset( $args['current_form'] ) ) {
282 205 // If the global has already been set, allow strings to be filtered.
283 206 $frm_settings->maybe_filter_for_form( $args );
@@ -289,13 +212,11 @@
289 212 /**
290 213 * @return string
291 214 */
292 215 public static function get_menu_name() {
293 - if ( ! self::pro_is_installed() || FrmAddonsController::is_license_expired() ) {
294 - return 'Formidable';
295 - }
216 + $frm_settings = self::get_settings();
296 217
297 - return self::get_settings()->menu;
218 + return FrmAddonsController::is_license_expired() ? 'Formidable' : $frm_settings->menu;
298 219 }
299 220
300 221 /**
301 222 * Determine if the current branding is set to 'formidable'.
@@ -309,9 +230,10 @@
309 230 if ( ! self::pro_is_installed() ) {
310 231 return true;
311 232 }
312 233
313 - return str_contains( self::get_menu_icon_class(), 'frm_logo_icon' );
234 + $menu_icon = self::get_menu_icon_class();
235 + return strpos( $menu_icon, 'frm_logo_icon' ) !== false;
314 236 }
315 237
316 238 /**
317 239 * @since 3.05
@@ -316,9 +238,8 @@
316 238 /**
317 239 * @since 3.05
318 240 *
319 241 * @param array $atts
320 - *
321 242 * @return string
322 243 */
323 244 public static function svg_logo( $atts = array() ) {
324 245 $defaults = array(
@@ -328,14 +249,12 @@
328 249 'orange' => '#f05a24',
329 250 );
330 251 $atts = array_merge( $defaults, $atts );
331 252
332 - // phpcs:disable SlevomatCodingStandard.Files.LineLength.LineTooLong
333 253 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 254 <path fill="' . esc_attr( $atts['orange'] ) . '" d="M289.6 384h140v76h-140z"/>
335 255 <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 256 </svg>';
337 - // phpcs:enable SlevomatCodingStandard.Files.LineLength.LineTooLong
338 257 }
339 258
340 259 /**
341 260 * @since 4.0
@@ -340,13 +259,12 @@
340 259 /**
341 260 * @since 4.0
342 261 *
343 262 * @param array $atts
344 - *
345 263 * @return void
346 264 */
347 265 public static function show_logo( $atts = array() ) {
348 - self::kses_echo( self::svg_logo( $atts ), 'all' );
266 + echo self::kses( self::svg_logo( $atts ), 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
349 267 }
350 268
351 269 /**
352 270 * @since 4.03.02
@@ -361,11 +279,10 @@
361 279 )
362 280 );
363 281
364 282 $new_icon = apply_filters( 'frm_icon', $icon, true );
365 -
366 283 if ( $new_icon !== $icon ) {
367 - if ( str_starts_with( $new_icon, '<svg' ) ) {
284 + if ( strpos( $new_icon, '<svg' ) === 0 ) {
368 285 $icon = str_replace( 'viewBox="0 0 20', 'width="30" height="35" style="color:#929699" viewBox="0 0 20', $new_icon );
369 286 } else {
370 287 // Show nothing if it isn't an SVG.
371 288 $icon = '<div style="height:39px"></div>';
@@ -370,9 +287,9 @@
370 287 // Show nothing if it isn't an SVG.
371 288 $icon = '<div style="height:39px"></div>';
372 289 }
373 290 }
374 - self::kses_echo( $icon, 'all' );
291 + echo self::kses( $icon, 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
375 292 }
376 293
377 294 /**
378 295 * @since 2.02.04
@@ -422,13 +339,11 @@
422 339 */
423 340 public static function is_form_builder_page( $check_for_settings = true ) {
424 341 $action = self::simple_get( 'frm_action', 'sanitize_title' );
425 342 $check_actions = array( 'edit', 'duplicate' );
426 -
427 343 if ( $check_for_settings ) {
428 344 $check_actions[] = 'settings';
429 345 }
430 -
431 346 return self::is_admin_page( 'formidable' ) && in_array( $action, $check_actions, true );
432 347 }
433 348
434 349 /**
@@ -434,15 +349,15 @@
434 349 /**
435 350 * @return bool
436 351 */
437 352 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();
353 + $page = self::simple_get( 'page', 'sanitize_title' );
354 + $is_formidable = strpos( $page, 'formidable' ) !== false;
355 + if ( empty( $page ) ) {
356 + $is_formidable = self::is_view_builder_page();
442 357 }
443 358
444 - return str_contains( $page, 'formidable' );
359 + return $is_formidable;
445 360 }
446 361
447 362 /**
448 363 * Checks if is a list page.
@@ -449,9 +364,8 @@
449 364 *
450 365 * @since 6.19
451 366 *
452 367 * @param string $page The name of the page to check.
453 - *
454 368 * @return bool
455 369 */
456 370 public static function is_admin_list_page( $page = 'formidable' ) {
457 371 if ( 'formidable' === $page ) {
@@ -463,9 +377,8 @@
463 377 }
464 378
465 379 if ( 'formidable-entries' === $page ) {
466 380 $action = self::simple_get( 'frm_action' );
467 -
468 381 if ( ! $action || in_array( $action, self::get_entries_listing_page_form_actions(), true ) ) {
469 382 return true;
470 383 }
471 384 }
@@ -494,13 +407,11 @@
494 407 */
495 408 public static function is_admin_page( $page = 'formidable' ) {
496 409 global $pagenow;
497 410 $get_page = self::simple_get( 'page', 'sanitize_title' );
498 -
499 411 if ( $pagenow ) {
500 - // Allow this to be true during ajax load i.e. ajax form builder loading
412 + // allow this to be true during ajax load i.e. ajax form builder loading
501 413 $is_page = ( $pagenow === 'admin.php' || $pagenow === 'admin-ajax.php' ) && $get_page === $page;
502 -
503 414 if ( $is_page ) {
504 415 return true;
505 416 }
506 417 }
@@ -518,15 +429,15 @@
518 429 */
519 430 public static function is_view_builder_page() {
520 431 global $pagenow;
521 432
522 - if ( ! in_array( $pagenow, array( 'post.php', 'post-new.php', 'edit.php' ), true ) ) {
433 + if ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' && $pagenow !== 'edit.php' ) {
523 434 return false;
524 435 }
525 436
526 437 $post_type = self::simple_get( 'post_type', 'sanitize_title' );
527 438
528 - if ( ! $post_type ) {
439 + if ( empty( $post_type ) ) {
529 440 $post_id = self::simple_get( 'post', 'absint' );
530 441 $post = get_post( $post_id );
531 442 $post_type = $post ? $post->post_type : '';
532 443 }
@@ -544,9 +455,9 @@
544 455 public static function is_preview_page() {
545 456 global $pagenow;
546 457 $action = self::simple_get( 'action', 'sanitize_title' );
547 458
548 - return $pagenow === 'admin-ajax.php' && $action === 'frm_forms_preview';
459 + return $pagenow && $pagenow === 'admin-ajax.php' && $action === 'frm_forms_preview';
549 460 }
550 461
551 462 /**
552 463 * Check for ajax except the form preview page
@@ -567,9 +478,8 @@
567 478 }
568 479
569 480 /**
570 481 * @since 2.0.8
571 - *
572 482 * @return bool
573 483 */
574 484 public static function prevent_caching() {
575 485 global $frm_vars;
@@ -587,9 +497,8 @@
587 497 $is_admin = is_admin() && ! wp_doing_ajax();
588 498
589 499 /**
590 500 * @since 6.0
591 - *
592 501 * @param bool $is_admin
593 502 */
594 503 return apply_filters( 'frm_is_admin', $is_admin );
595 504 }
@@ -604,15 +513,14 @@
604 513 *
605 514 * @return bool
606 515 */
607 516 public static function is_empty_value( $value, $empty = '' ) {
608 - return $value === array() || $value === $empty;
517 + return ( is_array( $value ) && empty( $value ) ) || $value === $empty;
609 518 }
610 519
611 520 /**
612 521 * @param mixed $value
613 522 * @param string $empty
614 - *
615 523 * @return bool
616 524 */
617 525 public static function is_not_empty_value( $value, $empty = '' ) {
618 526 return ! self::is_empty_value( $value, $empty );
@@ -666,9 +574,8 @@
666 574 continue;
667 575 }
668 576
669 577 $key = self::get_server_value( $key );
670 -
671 578 foreach ( explode( ',', $key ) as $ip ) {
672 579 // Just to be safe.
673 580 $ip = trim( $ip );
674 581
@@ -724,26 +631,16 @@
724 631 */
725 632 return apply_filters( 'frm_use_custom_header_ip', $should_use_custom_header_ip );
726 633 }
727 634
728 - /**
729 - * @param string $param
730 - * @param mixed $default
731 - * @param string $src
732 - * @param callable|string $sanitize
733 - *
734 - * @return mixed
735 - */
736 635 public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
737 - if ( str_contains( $param, '[' ) ) {
636 + if ( strpos( $param, '[' ) ) {
738 637 $params = explode( '[', $param );
739 638 $param = $params[0];
740 639 }
741 640
742 641 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 -
642 + $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 643 if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
747 644 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
748 645 $value = htmlspecialchars_decode( wp_unslash( $_GET[ $param ] ) );
749 646 }
@@ -758,19 +655,17 @@
758 655 )
759 656 );
760 657 }
761 658
762 - if ( ! isset( $params ) || ! is_array( $value ) || ! $value ) {
763 - return $value;
764 - }
659 + if ( isset( $params ) && is_array( $value ) && ! empty( $value ) ) {
660 + foreach ( $params as $k => $p ) {
661 + if ( ! $k || ! is_array( $value ) ) {
662 + continue;
663 + }
765 664
766 - foreach ( $params as $k => $p ) {
767 - if ( ! $k || ! is_array( $value ) ) {
768 - continue;
665 + $p = trim( $p, ']' );
666 + $value = isset( $value[ $p ] ) ? $value[ $p ] : $default;
769 667 }
770 -
771 - $p = trim( $p, ']' );
772 - $value = $value[ $p ] ?? $default;
773 668 }
774 669
775 670 return $value;
776 671 }
@@ -781,9 +676,8 @@
781 676 * @param string $param The key we are trying to access data from in $_POST.
782 677 * @param mixed $default The default if nothing is being sent.
783 678 * @param callable|string $sanitize Make sure to pass a sanitize method here. This function will NOT sanitize by default.
784 679 * @param bool $serialized
785 - *
786 680 * @return mixed
787 681 */
788 682 public static function get_post_param( $param, $default = '', $sanitize = '', $serialized = false ) {
789 683 return self::get_simple_request(
@@ -803,9 +697,9 @@
803 697 * @param string $param
804 698 * @param string $sanitize
805 699 * @param string $default
806 700 *
807 - * @return array|int|string
701 + * @return array|string
808 702 */
809 703 public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) {
810 704 return self::get_simple_request(
811 705 array(
@@ -834,10 +728,10 @@
834 728 'sanitize' => 'sanitize_text_field',
835 729 'serialized' => false,
836 730 );
837 731 $args = wp_parse_args( $args, $defaults );
838 - $value = $args['default'];
839 732
733 + $value = $args['default'];
840 734 if ( $args['type'] === 'get' ) {
841 735 if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
842 736 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
843 737 $value = wp_unslash( $_GET[ $args['param'] ] );
@@ -845,16 +739,16 @@
845 739 } elseif ( $args['type'] === 'post' ) {
846 740 if ( isset( $_POST[ $args['param'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
847 741 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
848 742 $value = wp_unslash( $_POST[ $args['param'] ] );
849 -
850 743 if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) {
851 744 self::unserialize_or_decode( $value );
852 745 }
853 746 }
854 747 } 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'] ] );
748 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
749 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
750 + $value = wp_unslash( $_REQUEST[ $args['param'] ] );
857 751 }
858 752
859 753 self::sanitize_value( $args['sanitize'], $value );
860 754
@@ -867,13 +761,17 @@
867 761 * @since 2.0.8
868 762 *
869 763 * @param string $value
870 764 *
871 - * @return string Value.
765 + * @return string $value
872 766 */
873 767 public static function preserve_backslashes( $value ) {
874 768 // If backslashes have already been added, don't add them again
875 - return str_contains( $value, '\\\\' ) ? $value : addslashes( $value );
769 + if ( strpos( $value, '\\\\' ) === false ) {
770 + $value = addslashes( $value );
771 + }
772 +
773 + return $value;
876 774 }
877 775
878 776 /**
879 777 * Sanitize a value in-place.
@@ -880,9 +778,8 @@
880 778 * If $value is an array, the sanitize function will get called for each item.
881 779 *
882 780 * @param callable $sanitize
883 781 * @param mixed $value
884 - *
885 782 * @return void
886 783 */
887 784 public static function sanitize_value( $sanitize, &$value ) {
888 785 if ( ! $sanitize ) {
@@ -895,13 +792,11 @@
895 792 }
896 793
897 794 if ( is_array( $value ) ) {
898 795 $temp_values = $value;
899 -
900 796 foreach ( $temp_values as $k => $v ) {
901 797 self::sanitize_value( $sanitize, $value[ $k ] );
902 798 }
903 -
904 799 return;
905 800 }
906 801
907 802 $value = call_user_func( $sanitize, $value );
@@ -906,17 +801,10 @@
906 801
907 802 $value = call_user_func( $sanitize, $value );
908 803 }
909 804
910 - /**
911 - * @param array $sanitize_method
912 - * @param array $values
913 - *
914 - * @return void
915 - */
916 805 public static function sanitize_request( $sanitize_method, &$values ) {
917 806 $temp_values = $values;
918 -
919 807 foreach ( $temp_values as $k => $val ) {
920 808 if ( isset( $sanitize_method[ $k ] ) ) {
921 809 $values[ $k ] = call_user_func( $sanitize_method[ $k ], $val );
922 810 }
@@ -926,9 +814,8 @@
926 814 /**
927 815 * @since 4.0.04
928 816 *
929 817 * @param mixed $value
930 - *
931 818 * @return void
932 819 */
933 820 public static function sanitize_with_html( &$value ) {
934 821 if ( current_user_can( 'frm_edit_entries' ) || current_user_can( 'administrator' ) ) {
@@ -937,9 +824,8 @@
937 824 } else {
938 825 self::sanitize_value( self::class . '::strip_most_html', $value );
939 826 }
940 827 self::decode_specialchars( $value );
941 - self::sanitize_value( 'FrmHtmlSanitizer::sanitize_url_attributes', $value );
942 828 }
943 829
944 830 /**
945 831 * Allow only a small set of very basic HTML for unprivileged users.
@@ -948,12 +834,8 @@
948 834 *
949 835 * @param string $value
950 836 */
951 837 public static function strip_most_html( $value ) {
952 - if ( '' === $value ) {
953 - return $value;
954 - }
955 -
956 838 $allowed_html = array(
957 839 'b' => array(),
958 840 'br' => array(),
959 841 'strong' => array(),
@@ -978,15 +860,12 @@
978 860 * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&amp;'
979 861 * this MUST be done, else we'll be back to the '& entity' problem.
980 862 *
981 863 * @since 4.0.04
982 - *
983 - * @param mixed $value Value to decode, passed by reference.
984 864 */
985 865 public static function decode_specialchars( &$value ) {
986 866 if ( is_array( $value ) ) {
987 867 $temp_values = $value;
988 -
989 868 foreach ( $temp_values as $k => $v ) {
990 869 self::decode_specialchars( $value[ $k ] );
991 870 }
992 871 } else {
@@ -1000,13 +879,13 @@
1000 879 * Adapted from wp_specialchars_decode().
1001 880 *
1002 881 * @since 4.03.01
1003 882 *
1004 - * @param string $string The string to prep, passed by reference.
883 + * @param string $string The string to prep.
1005 884 */
1006 885 private static function decode_amp( &$string ) {
1007 886 // Don't bother if there are no entities - saves a lot of processing
1008 - if ( ! $string || ! str_contains( $string, '&' ) ) {
887 + if ( empty( $string ) || strpos( $string, '&' ) === false ) {
1009 888 return;
1010 889 }
1011 890
1012 891 $translation = array(
@@ -1044,15 +923,17 @@
1044 923 * Sanitize the value, and allow some HTML
1045 924 *
1046 925 * @since 2.0
1047 926 *
1048 - * @param string $value The value to sanitize.
1049 - * @param array|string $allowed Allowed HTML tags and attributes, or 'all' for defaults.
927 + * @param string $value
928 + * @param array|string $allowed 'all' for everything included as defaults.
1050 929 *
1051 930 * @return string
1052 931 */
1053 932 public static function kses( $value, $allowed = array() ) {
1054 - return wp_kses( $value, self::allowed_html( $allowed ) );
933 + $allowed_html = self::allowed_html( $allowed );
934 +
935 + return wp_kses( $value, $allowed_html );
1055 936 }
1056 937
1057 938 /**
1058 939 * Sanitizes and echoes a given value.
@@ -1060,9 +941,8 @@
1060 941 * @since 6.18
1061 942 *
1062 943 * @param string $value The value to sanitize and output.
1063 944 * @param array|string $allowed Allowed HTML tags and attributes.
1064 - *
1065 945 * @return void
1066 946 */
1067 947 public static function kses_echo( $value, $allowed = array() ) {
1068 948 echo self::kses( $value, $allowed ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -1073,23 +953,21 @@
1073 953 *
1074 954 * @since 5.0.13
1075 955 *
1076 956 * @param string $html
1077 - *
1078 957 * @return string
1079 958 */
1080 959 public static function kses_submit_button( $html ) {
1081 - $included_button_action = str_contains( $html, '[button_action]' );
1082 - $included_back_hook = str_contains( $html, '[back_hook]' );
1083 - $included_draft_hook = str_contains( $html, '[draft_hook]' );
960 + $included_button_action = false !== strpos( $html, '[button_action]' );
961 + $included_back_hook = false !== strpos( $html, '[back_hook]' );
962 + $included_draft_hook = false !== strpos( $html, '[draft_hook]' );
1084 963 add_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1085 964 add_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1086 965 $html = self::kses( $html, 'all' );
1087 966 remove_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1088 967 remove_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1089 -
1090 968 if ( $included_button_action ) {
1091 - if ( str_contains( $html, '<input type="submit"' ) ) {
969 + if ( false !== strpos( $html, '<input type="submit"' ) ) {
1092 970 $pattern = '/(<input type="submit")([^>]*)(\/>)/';
1093 971 $html = preg_replace( $pattern, '$1$2[button_action] $3', $html, 1 );
1094 972 } else {
1095 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
@@ -1095,17 +973,14 @@
1095 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
1096 974 $html = preg_replace( $pattern, '$1$2$3$4$5$6$7 [button_action]$8$9$10', $html, 1 );
1097 975 }
1098 976 }
1099 -
1100 977 if ( $included_back_hook ) {
1101 978 $html = str_replace( 'class="frm_prev_page"', 'class="frm_prev_page" [back_hook]', $html );
1102 979 }
1103 -
1104 980 if ( $included_draft_hook ) {
1105 - return str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html );
981 + $html = str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html );
1106 982 }
1107 -
1108 983 return $html;
1109 984 }
1110 985
1111 986 /**
@@ -1111,9 +986,8 @@
1111 986 /**
1112 987 * @since 5.0.13
1113 988 *
1114 989 * @param array $allowed_attr
1115 - *
1116 990 * @return array
1117 991 */
1118 992 public static function allow_visibility_style( $allowed_attr ) {
1119 993 $allowed_attr[] = 'visibility';
@@ -1123,9 +997,8 @@
1123 997 /**
1124 998 * @since 5.0.13
1125 999 *
1126 1000 * @param array $allowed_html
1127 - *
1128 1001 * @return array
1129 1002 */
1130 1003 public static function add_allowed_submit_button_tags( $allowed_html ) {
1131 1004 $allowed_html['input'] = array(
@@ -1142,22 +1015,17 @@
1142 1015 }
1143 1016
1144 1017 /**
1145 1018 * @since 2.05.03
1146 - *
1147 - * @param array|string $allowed
1148 - *
1149 - * @return array
1150 1019 */
1151 1020 private static function allowed_html( $allowed ) {
1152 1021 $html = self::safe_html();
1153 1022 $allowed_html = array();
1154 -
1155 1023 if ( $allowed === 'all' ) {
1156 1024 $allowed_html = $html;
1157 - } elseif ( $allowed ) {
1025 + } elseif ( ! empty( $allowed ) ) {
1158 1026 foreach ( (array) $allowed as $a ) {
1159 - $allowed_html[ $a ] = $html[ $a ] ?? array();
1027 + $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
1160 1028 }
1161 1029 }
1162 1030
1163 1031 return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
@@ -1164,10 +1032,8 @@
1164 1032 }
1165 1033
1166 1034 /**
1167 1035 * @since 2.05.03
1168 - *
1169 - * @return array
1170 1036 */
1171 1037 private static function safe_html() {
1172 1038 $allow_class = array(
1173 1039 'class' => true,
@@ -1319,16 +1185,14 @@
1319 1185 return;
1320 1186 }
1321 1187
1322 1188 $action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' );
1323 -
1324 - if ( ! $action_name ) {
1189 + if ( empty( $action_name ) ) {
1325 1190 return;
1326 1191 }
1327 1192
1328 1193 $new_action = self::get_param( $action_name, '', 'get', 'sanitize_text_field' );
1329 -
1330 - if ( $new_action ) {
1194 + if ( ! empty( $new_action ) ) {
1331 1195 $_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', self::get_server_value( 'REQUEST_URI' ) );
1332 1196 }
1333 1197 }
1334 1198
@@ -1335,23 +1199,21 @@
1335 1199 /**
1336 1200 * Check the WP query for a parameter
1337 1201 *
1338 1202 * @since 2.0
1339 - *
1340 - * @param array|string $value
1341 - * @param string $param
1342 - *
1343 1203 * @return array|string
1344 1204 */
1345 1205 public static function get_query_var( $value, $param ) {
1346 - // phpcs:ignore Universal.Operators.StrictComparisons
1347 1206 if ( $value != '' ) {
1348 1207 return $value;
1349 1208 }
1350 1209
1351 1210 global $wp_query;
1211 + if ( isset( $wp_query->query_vars[ $param ] ) ) {
1212 + $value = $wp_query->query_vars[ $param ];
1213 + }
1352 1214
1353 - return $wp_query->query_vars[ $param ] ?? $value;
1215 + return $value;
1354 1216 }
1355 1217
1356 1218 /**
1357 1219 * Try to show the SVG if possible. Otherwise, use the font icon.
@@ -1359,18 +1221,18 @@
1359 1221 * @since 4.0.02
1360 1222 *
1361 1223 * @param string $class
1362 1224 * @param array $atts
1363 - *
1364 1225 * @return string|null
1365 1226 */
1366 1227 public static function icon_by_class( $class, $atts = array() ) {
1367 1228 $echo = ! isset( $atts['echo'] ) || $atts['echo'];
1368 -
1369 1229 if ( isset( $atts['echo'] ) ) {
1370 1230 unset( $atts['echo'] );
1371 1231 }
1372 1232
1233 + $html_atts = self::array_to_html_params( $atts );
1234 +
1373 1235 $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1374 1236
1375 1237 // Replace icons that have been removed or renamed.
1376 1238 $deprecated = array(
@@ -1377,61 +1239,29 @@
1377 1239 'frm_clone_solid_icon' => 'frm_clone_icon',
1378 1240 'frm_keyalt_icon' => 'frm_key_icon',
1379 1241 'frm_keyalt_solid_icon' => 'frm_key_solid_icon',
1380 1242 );
1381 -
1382 1243 if ( isset( $deprecated[ $icon ] ) ) {
1383 1244 $icon = $deprecated[ $icon ];
1384 1245 $class = str_replace( $icon, $deprecated[ $icon ], $class );
1385 1246 }
1386 1247
1387 - $is_font_icon = $icon === $class;
1388 -
1389 - if ( ! $is_font_icon ) {
1390 - $class = str_contains( $icon, ' ' ) ? ' ' . $icon : '';
1391 -
1392 - if ( str_contains( $icon, ' ' ) ) {
1248 + if ( $icon === $class ) {
1249 + $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
1250 + } else {
1251 + $class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
1252 + if ( strpos( $icon, ' ' ) ) {
1393 1253 $icon = explode( ' ', $icon );
1394 1254 $icon = reset( $icon );
1395 1255 }
1256 + $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use xlink:href="#' . esc_attr( $icon ) . '" /></svg>';
1396 1257 }
1397 1258
1398 - if ( $atts ) {
1399 - // A caller passed attributes, so kses still has to decide which of them survive. Its
1400 - // allowlist comes from safe_html() through the frm_striphtml_allowed_tags filter, and
1401 - // add-ons widen it around their own icons, so there is no fixed list to check against.
1402 - $html_atts = self::array_to_html_params( $atts );
1403 - $markup = $is_font_icon
1404 - ? '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>'
1405 - : '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use href="#' . esc_attr( $icon ) . '" /></svg>';
1406 -
1407 - if ( ! $echo ) {
1408 - return $markup;
1409 - }
1410 -
1411 - echo self::kses_icon( $markup ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1412 - return null;
1259 + if ( $echo ) {
1260 + echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1261 + } else {
1262 + return $icon;
1413 1263 }
1414 -
1415 - /**
1416 - * With no attributes from the caller, the tag is nothing but this method's own markup
1417 - * around an escaped class and icon id, so there is nothing left for kses to decide and it
1418 - * can be skipped. Echoing the pieces rather than a finished string keeps that safe to the
1419 - * escaping sniff without an annotation.
1420 - *
1421 - * This is the path the form builder takes for most of the tens of thousands of icons it
1422 - * renders on a large form, and the kses pass was most of what each one cost.
1423 - */
1424 - $callback = function () use ( $is_font_icon, $class, $icon ) {
1425 - if ( $is_font_icon ) {
1426 - echo '<i class="' . esc_attr( $class ) . '"></i>';
1427 - return;
1428 - }
1429 -
1430 - echo '<svg class="frmsvg' . esc_attr( $class ) . '"><use href="#' . esc_attr( $icon ) . '" /></svg>';
1431 - };
1432 -
1433 - return self::clip( $callback, $echo );
1434 1264 }
1435 1265
1436 1266 /**
1437 1267 * Run kses for icons. It needs to add a few filters first in order to preserve some custom style values.
@@ -1438,9 +1268,8 @@
1438 1268 *
1439 1269 * @since 5.0.13
1440 1270 *
1441 1271 * @param string $icon
1442 - *
1443 1272 * @return string
1444 1273 */
1445 1274 public static function kses_icon( $icon ) {
1446 1275 add_filter( 'safe_style_css', 'FrmAppHelper::allow_vars_in_styles' );
@@ -1456,15 +1285,13 @@
1456 1285 /**
1457 1286 * @since 5.0.13.1
1458 1287 *
1459 1288 * @param array $allowed_html
1460 - *
1461 1289 * @return array
1462 1290 */
1463 1291 public static function add_allowed_icon_tags( $allowed_html ) {
1464 1292 $allowed_html['svg']['data-open'] = true;
1465 1293 $allowed_html['svg']['title'] = true;
1466 - $allowed_html['svg']['tabindex'] = true;
1467 1294 return $allowed_html;
1468 1295 }
1469 1296
1470 1297 /**
@@ -1470,9 +1297,8 @@
1470 1297 /**
1471 1298 * @since 5.0.13
1472 1299 *
1473 1300 * @param array $allowed_attr
1474 - *
1475 1301 * @return array
1476 1302 */
1477 1303 public static function allow_vars_in_styles( $allowed_attr ) {
1478 1304 $allowed_attr[] = '--primary-700';
@@ -1485,9 +1311,9 @@
1485 1311 * @param bool $allow_css
1486 1312 * @param string $css_string
1487 1313 */
1488 1314 public static function allow_style( $allow_css, $css_string ) {
1489 - if ( ! $allow_css && str_starts_with( $css_string, '--primary-700:' ) ) {
1315 + if ( ! $allow_css && 0 === strpos( $css_string, '--primary-700:' ) ) {
1490 1316 $split = explode( ':', $css_string, 2 );
1491 1317 $allow_css = 2 === count( $split ) && self::is_a_valid_color( $split[1] );
1492 1318 }
1493 1319 return $allow_css;
@@ -1496,22 +1322,19 @@
1496 1322 /**
1497 1323 * @since 5.0.13
1498 1324 *
1499 1325 * @param string $value
1500 - *
1501 1326 * @return bool
1502 1327 */
1503 1328 private static function is_a_valid_color( $value ) {
1504 1329 $match = 0;
1505 -
1506 - if ( str_starts_with( $value, 'rgba(' ) ) {
1330 + if ( 0 === strpos( $value, 'rgba(' ) ) {
1507 1331 $match = preg_match( '/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/', $value );
1508 - } elseif ( str_starts_with( $value, 'rgb(' ) ) {
1332 + } elseif ( 0 === strpos( $value, 'rgb(' ) ) {
1509 1333 $match = preg_match( '/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/', $value );
1510 - } elseif ( str_starts_with( $value, '#' ) ) {
1334 + } elseif ( 0 === strpos( $value, '#' ) ) {
1511 1335 $match = preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})\b$/', $value );
1512 1336 }
1513 -
1514 1337 return (bool) $match;
1515 1338 }
1516 1339
1517 1340 /**
@@ -1517,9 +1340,8 @@
1517 1340 /**
1518 1341 * Include svg images.
1519 1342 *
1520 1343 * @since 4.0.02
1521 - *
1522 1344 * @return void
1523 1345 */
1524 1346 public static function include_svg() {
1525 1347 if ( self::$included_svg ) {
@@ -1538,20 +1360,17 @@
1538 1360 * @since 5.0.13 added $echo parameter.
1539 1361 *
1540 1362 * @param array $atts
1541 1363 * @param bool $echo
1542 - *
1543 1364 * @return string|void
1544 1365 */
1545 1366 public static function array_to_html_params( $atts, $echo = false ) {
1546 1367 $callback = function () use ( $atts ) {
1547 - if ( ! $atts ) {
1548 - return;
1368 + if ( $atts ) {
1369 + foreach ( $atts as $key => $value ) {
1370 + echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1371 + }
1549 1372 }
1550 -
1551 - foreach ( $atts as $key => $value ) {
1552 - echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1553 - }
1554 1373 };
1555 1374 return self::clip( $callback, $echo );
1556 1375 }
1557 1376
@@ -1561,12 +1380,9 @@
1561 1380 * @since 5.0.13
1562 1381 *
1563 1382 * @param Closure $echo_function
1564 1383 * @param bool $echo
1565 - *
1566 1384 * @return string|null
1567 - *
1568 - * @psalm-return ($echo is true ? null : string)
1569 1385 */
1570 1386 public static function clip( $echo_function, $echo = false ) {
1571 1387 if ( ! $echo ) {
1572 1388 ob_start();
@@ -1575,9 +1391,13 @@
1575 1391 if ( is_callable( $echo_function ) ) {
1576 1392 $echo_function();
1577 1393 }
1578 1394
1579 - return $echo ? null : ob_get_clean();
1395 + if ( ! $echo ) {
1396 + $return = ob_get_contents();
1397 + ob_end_clean();
1398 + return $return;
1399 + }
1580 1400 }
1581 1401
1582 1402 /**
1583 1403 * @since 3.0
@@ -1582,18 +1402,15 @@
1582 1402 /**
1583 1403 * @since 3.0
1584 1404 *
1585 1405 * @param array $atts
1586 - *
1587 1406 * @return void
1588 1407 */
1589 1408 public static function get_admin_header( $atts ) {
1590 1409 $has_nav = ! empty( $atts['form'] ) && empty( $atts['is_template'] );
1591 -
1592 1410 if ( empty( $atts['close'] ) ) {
1593 1411 $atts['close'] = admin_url( 'admin.php?page=formidable' );
1594 1412 }
1595 -
1596 1413 if ( ! isset( $atts['import_link'] ) ) {
1597 1414 $atts['import_link'] = false;
1598 1415 }
1599 1416
@@ -1603,19 +1420,16 @@
1603 1420 /**
1604 1421 * @since 6.0
1605 1422 *
1606 1423 * @param string $type
1607 - *
1608 1424 * @return void
1609 1425 */
1610 1426 public static function import_link( $type = 'secondary' ) {
1611 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1612 1427 ?>
1613 1428 <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">
1614 1429 <?php esc_html_e( 'Import', 'formidable' ); ?>
1615 1430 </a>
1616 1431 <?php
1617 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1618 1432 }
1619 1433
1620 1434 /**
1621 1435 * Print applicable admin banner.
@@ -1622,9 +1436,8 @@
1622 1436 *
1623 1437 * @since 5.4.2
1624 1438 *
1625 1439 * @param bool $should_show_lite_upgrade
1626 - *
1627 1440 * @return void
1628 1441 */
1629 1442 public static function print_admin_banner( $should_show_lite_upgrade ) {
1630 1443 if ( ! current_user_can( 'administrator' ) ) {
@@ -1636,15 +1449,13 @@
1636 1449 // Print license warning or inbox banner and exit if either prints.
1637 1450 // And exit before printing the upgrade bar if it shouldn't be shown.
1638 1451 return;
1639 1452 }
1640 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1641 1453 ?>
1642 1454 <div class="frm-upgrade-bar">
1643 1455 <div class="frm-upgrade-bar-inner">
1644 1456 <?php
1645 1457 $cta_text = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_text' );
1646 -
1647 1458 if ( ! $cta_text ) {
1648 1459 $cta_text = __( 'upgrading to PRO', 'formidable' );
1649 1460 }
1650 1461
@@ -1649,18 +1460,22 @@
1649 1460 }
1650 1461
1651 1462 $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' );
1652 1463 $utm = array(
1653 - 'campaign' => 'settings-license',
1654 - 'content' => 'lite-banner',
1464 + 'medium' => 'settings-license',
1465 + 'content' => 'lite-banner',
1655 1466 );
1656 1467
1657 - $upgrade_link = $upgrade_link ? self::maybe_add_missing_utm( $upgrade_link, $utm ) : self::admin_upgrade_link( $utm );
1468 + if ( $upgrade_link ) {
1469 + $upgrade_link = self::maybe_add_missing_utm( $upgrade_link, $utm );
1470 + } else {
1471 + $upgrade_link = self::admin_upgrade_link( $utm );
1472 + }
1658 1473
1659 1474 printf(
1660 1475 /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */
1661 1476 esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ),
1662 - '<a href="' . esc_url( $upgrade_link ) . '" target="_blank" rel="noopener">',
1477 + '<a href="' . esc_url( $upgrade_link ) . '">',
1663 1478 esc_html( $cta_text ),
1664 1479 '</a>'
1665 1480 );
1666 1481 ?>
@@ -1666,9 +1481,8 @@
1666 1481 ?>
1667 1482 </div>
1668 1483 </div>
1669 1484 <?php
1670 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1671 1485 }
1672 1486
1673 1487 /**
1674 1488 * @since 5.4.2
@@ -1682,9 +1496,8 @@
1682 1496 /**
1683 1497 * Render a button for a new item (Form, Application, etc).
1684 1498 *
1685 1499 * @since 3.0
1686 - *
1687 1500 * @param array $atts {
1688 1501 * Details about the button.
1689 1502 *
1690 1503 * @type array $link_hook Custom link hook, calls do_action and exits early.
@@ -1691,9 +1504,8 @@
1691 1504 * @type string $new_link Href value, default #.
1692 1505 * @type string $class Custom class names, space separated.
1693 1506 * @type string $button_text Button text. Default "Add New".
1694 1507 * }
1695 - *
1696 1508 * @return void
1697 1509 */
1698 1510 public static function add_new_item_link( $atts ) {
1699 1511 if ( isset( $atts['link_hook'] ) ) {
@@ -1719,12 +1531,8 @@
1719 1531 }
1720 1532
1721 1533 /**
1722 1534 * @since 3.06
1723 - *
1724 - * @param array $atts
1725 - *
1726 - * @return void
1727 1535 */
1728 1536 public static function show_search_box( $atts ) {
1729 1537 $defaults = array(
1730 1538 'placeholder' => '',
@@ -1731,9 +1539,8 @@
1731 1539 'tosearch' => '',
1732 1540 'text' => __( 'Search', 'formidable' ),
1733 1541 'input_id' => '',
1734 1542 'value' => false,
1735 - 'class' => '',
1736 1543 );
1737 1544 $atts = array_merge( $defaults, $atts );
1738 1545
1739 1546 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
@@ -1740,9 +1547,8 @@
1740 1547 $atts['tosearch'] = 'frm-card';
1741 1548 }
1742 1549
1743 1550 $class = 'frm-search-input';
1744 -
1745 1551 if ( ! empty( $atts['tosearch'] ) ) {
1746 1552 $class .= ' frm-auto-search';
1747 1553 }
1748 1554
@@ -1766,15 +1572,14 @@
1766 1572
1767 1573 if ( ! empty( $atts['tosearch'] ) ) {
1768 1574 $input_atts['autocomplete'] = 'off';
1769 1575 }
1770 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1771 1576 ?>
1772 - <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>">
1577 + <p class="frm-search">
1773 1578 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
1774 1579 <?php echo esc_html( $atts['text'] ); ?>:
1775 1580 </label>
1776 - <?php self::icon_by_class( 'frmfont frm_search_icon frm_svg20' ); ?>
1581 + <span class="frmfont frm_search_icon"></span>
1777 1582 <input <?php self::array_to_html_params( $input_atts, true ); ?> />
1778 1583 <?php
1779 1584 if ( empty( $atts['tosearch'] ) ) {
1780 1585 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
@@ -1781,21 +1586,17 @@
1781 1586 }
1782 1587 ?>
1783 1588 </p>
1784 1589 <?php
1785 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1786 1590 }
1787 1591
1788 1592 /**
1789 - * @param string $type Hook type slug.
1790 - * @param object|null $object Optional related object.
1791 - *
1593 + * @param string $type
1792 1594 * @return void
1793 1595 */
1794 1596 public static function trigger_hook_load( $type, $object = null ) {
1795 1597 // Only load the form hooks once.
1796 1598 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
1797 -
1798 1599 if ( ! $hooks_loaded ) {
1799 1600 do_action( 'frm_load_' . $type . '_hooks' );
1800 1601 }
1801 1602 }
@@ -1854,14 +1655,14 @@
1854 1655 * True when value is 1, true, 'true', 'yes'
1855 1656 *
1856 1657 * @since 1.07.10
1857 1658 *
1858 - * @param bool|int|string $value The value to compare.
1659 + * @param string $value The value to compare.
1859 1660 *
1860 1661 * @return bool
1861 1662 */
1862 1663 public static function is_true( $value ) {
1863 - return true === $value || '1' === (string) $value || 'true' === $value || 'yes' === $value;
1664 + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value;
1864 1665 }
1865 1666
1866 1667 /**
1867 1668 * Gets all post from a specific post type.
@@ -1869,9 +1670,8 @@
1869 1670 *
1870 1671 * @since 4.10.01 Add `$post_type` argument.
1871 1672 *
1872 1673 * @param string $post_type Post type to query. Default is `page`.
1873 - *
1874 1674 * @return WP_Post[]
1875 1675 */
1876 1676 public static function get_pages( $post_type = 'page' ) {
1877 1677 $query = array(
@@ -1890,9 +1690,8 @@
1890 1690 *
1891 1691 * @since 5.0.09
1892 1692 *
1893 1693 * @param string $post_type Post type to query. Default is `page`.
1894 - *
1895 1694 * @return array
1896 1695 */
1897 1696 public static function get_post_ids_and_titles( $post_type = 'page' ) {
1898 1697 return FrmDb::get_results(
@@ -1917,9 +1716,10 @@
1917 1716 *
1918 1717 * @param array $args Selection arguments.
1919 1718 */
1920 1719 public static function maybe_autocomplete_pages_options( $args ) {
1921 - $args = self::preformat_selection_args( $args );
1720 + $args = self::preformat_selection_args( $args );
1721 +
1922 1722 $pages_count = wp_count_posts( $args['post_type'] );
1923 1723
1924 1724 if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) {
1925 1725 self::wp_pages_dropdown( $args );
@@ -1966,11 +1766,11 @@
1966 1766 'value_key' => 'value',
1967 1767 'label_key' => 'label',
1968 1768 );
1969 1769
1970 - $args = wp_parse_args( $args, $defaults );
1770 + $args = wp_parse_args( $args, $defaults );
1771 +
1971 1772 $html_attrs = array();
1972 -
1973 1773 if ( ! empty( $args['name'] ) ) {
1974 1774 $html_attrs['name'] = $args['name'];
1975 1775 }
1976 1776
@@ -1977,9 +1777,8 @@
1977 1777 if ( ! empty( $args['id'] ) ) {
1978 1778 $html_attrs['id'] = $args['id'];
1979 1779 }
1980 1780
1981 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1982 1781 if ( count( $args['source'] ) <= $args['dropdown_limit'] ) {
1983 1782 ?>
1984 1783 <select <?php self::array_to_html_params( $html_attrs, true ); ?>>
1985 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
@@ -1985,44 +1784,40 @@
1985 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1986 1785 <?php
1987 1786 foreach ( $args['source'] as $key => $source ) :
1988 1787 $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1989 -
1990 1788 if ( ! empty( $args['truncate'] ) ) {
1991 1789 $value_label['label'] = self::truncate( $value_label['label'], $args['truncate'] );
1992 1790 }
1993 1791 ?>
1994 - <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1792 + <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option>
1995 1793 <?php endforeach; ?>
1996 1794 </select>
1997 1795 <?php
1998 - return;
1999 - }
2000 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1796 + } else {
1797 + $options = array();
1798 + $autocomplete_value = '';
1799 + foreach ( $args['source'] as $key => $source ) {
1800 + $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
2001 1801
2002 - $options = array();
2003 - $autocomplete_value = '';
1802 + if ( $value_label['value'] === $args['selected'] ) {
1803 + $autocomplete_value = $value_label['label'];
1804 + }
2004 1805
2005 - foreach ( $args['source'] as $key => $source ) {
2006 - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
2007 -
2008 - if ( $value_label['value'] === $args['selected'] ) {
2009 - $autocomplete_value = $value_label['label'];
1806 + $options[] = $value_label;
2010 1807 }
2011 1808
2012 - $options[] = $value_label;
2013 - }
2014 -
2015 - $html_attrs['type'] = 'hidden';
2016 - $html_attrs['class'] = 'frm_autocomplete_value_input';
2017 - $html_attrs['value'] = $args['selected'];
2018 - ?>
2019 - <input type="text" class="frm-custom-search"
2020 - data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
2021 - placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
2022 - value="<?php echo esc_attr( $autocomplete_value ); ?>" />
2023 - <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
2024 - <?php
1809 + $html_attrs['type'] = 'hidden';
1810 + $html_attrs['class'] = 'frm_autocomplete_value_input';
1811 + $html_attrs['value'] = $args['selected'];
1812 + ?>
1813 + <input type="text" class="frm-custom-search"
1814 + data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
1815 + placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1816 + value="<?php echo esc_attr( $autocomplete_value ); ?>" />
1817 + <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
1818 + <?php
1819 + }//end if
2025 1820 }
2026 1821
2027 1822 /**
2028 1823 * Gets dropdown value and label from autodropdown option.
@@ -2031,15 +1826,14 @@
2031 1826 *
2032 1827 * @param array|string $option Autocomplete option.
2033 1828 * @param string $key Array key of the option.
2034 1829 * @param array $args See {@see FrmAppHelper::maybe_autocomplete_options()}.
2035 - *
2036 1830 * @return array
2037 1831 */
2038 1832 private static function get_dropdown_value_and_label_from_option( $option, $key, $args ) {
2039 1833 if ( is_array( $option ) ) {
2040 - $value = $option[ $args['value_key'] ] ?? '';
2041 - $label = $option[ $args['label_key'] ] ?? '';
1834 + $value = isset( $option[ $args['value_key'] ] ) ? $option[ $args['value_key'] ] : '';
1835 + $label = isset( $option[ $args['label_key'] ] ) ? $option[ $args['label_key'] ] : '';
2042 1836 } else {
2043 1837 $value = $key;
2044 1838 $label = $option;
2045 1839 }
@@ -2056,9 +1850,8 @@
2056 1850 self::prep_page_dropdown_params( $page_id, $truncate, $args );
2057 1851
2058 1852 $pages = self::get_post_ids_and_titles( $args['post_type'] );
2059 1853 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
2060 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2061 1854 ?>
2062 1855 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
2063 1856 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
2064 1857 <?php foreach ( $pages as $page ) { ?>
@@ -2067,9 +1860,8 @@
2067 1860 </option>
2068 1861 <?php } ?>
2069 1862 </select>
2070 1863 <?php
2071 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2072 1864 }
2073 1865
2074 1866 /**
2075 1867 * Fill in missing parameters passed to wp_pages_dropdown().
@@ -2075,14 +1867,8 @@
2075 1867 * Fill in missing parameters passed to wp_pages_dropdown().
2076 1868 * This is for reverse compatibility with switching 3 params to 1.
2077 1869 *
2078 1870 * @since 4.03.06
2079 - *
2080 - * @param string $page_id Deprecated.
2081 - * @param bool $truncate Deprecated.
2082 - * @param mixed $args
2083 - *
2084 - * @return void
2085 1871 */
2086 1872 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
2087 1873 if ( ! is_array( $args ) ) {
2088 1874 $args = array(
@@ -2099,12 +1885,8 @@
2099 1885 * Filter to format args for page dropdown or autocomplete
2100 1886 *
2101 1887 * @since 4.03.06
2102 1888 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
2103 - *
2104 - * @param array $args
2105 - *
2106 - * @return array
2107 1889 */
2108 1890 private static function preformat_selection_args( $args ) {
2109 1891 $defaults = array(
2110 1892 'truncate' => false,
@@ -2117,18 +1899,13 @@
2117 1899
2118 1900 return array_merge( $defaults, $args );
2119 1901 }
2120 1902
2121 - /**
2122 - * @param int $post_id
2123 - *
2124 - * @return string
2125 - */
2126 1903 public static function post_edit_link( $post_id ) {
2127 1904 $post = get_post( $post_id );
2128 -
2129 1905 if ( $post ) {
2130 1906 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1907 +
2131 1908 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
2132 1909 }
2133 1910
2134 1911 return '';
@@ -2141,9 +1918,11 @@
2141 1918 *
2142 1919 * @return bool
2143 1920 */
2144 1921 public static function is_full_screen() {
2145 - return self::is_form_builder_page() || self::is_style_editor_page() || self::is_full_screen_view_builder_page();
1922 + return self::is_form_builder_page() ||
1923 + self::is_style_editor_page() ||
1924 + self::is_full_screen_view_builder_page();
2146 1925 }
2147 1926
2148 1927 /**
2149 1928 * Check if user is on the style editor or its alternative URL.
@@ -2153,9 +1932,8 @@
2153 1932 * @since 5.5.3
2154 1933 * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
2155 1934 *
2156 1935 * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
2157 - *
2158 1936 * @return bool
2159 1937 */
2160 1938 public static function is_style_editor_page( $view = '' ) {
2161 1939 if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
@@ -2192,9 +1970,8 @@
2192 1970 * @param array|string $capability
2193 1971 * @param string $multiple 'single' and 'multiple'.
2194 1972 */
2195 1973 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
2196 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2197 1974 ?>
2198 1975 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
2199 1976 <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?>
2200 1977 class="frm_multiselect">
@@ -2200,14 +1977,12 @@
2200 1977 class="frm_multiselect">
2201 1978 <?php self::roles_options( $capability ); ?>
2202 1979 </select>
2203 1980 <?php
2204 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2205 1981 }
2206 1982
2207 1983 /**
2208 1984 * @since 4.07
2209 - *
2210 1985 * @param array|string $selected
2211 1986 * @param string $current
2212 1987 */
2213 1988 private static function selected( $selected, $current ) {
@@ -2222,9 +1997,8 @@
2222 1997 * @param array|string $capability
2223 1998 */
2224 1999 public static function roles_options( $capability ) {
2225 2000 global $frm_vars;
2226 -
2227 2001 if ( isset( $frm_vars['editable_roles'] ) ) {
2228 2002 $editable_roles = $frm_vars['editable_roles'];
2229 2003 } else {
2230 2004 $editable_roles = get_editable_roles();
@@ -2233,9 +2007,9 @@
2233 2007
2234 2008 foreach ( $editable_roles as $role => $details ) {
2235 2009 $name = translate_user_role( $details['name'] );
2236 2010 ?>
2237 - <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?></option>
2011 + <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?> </option>
2238 2012 <?php
2239 2013 unset( $role, $details );
2240 2014 }
2241 2015 }
@@ -2245,9 +2019,8 @@
2245 2019 *
2246 2020 * @since 5.0 Parameter `$type` supports `pro_only` value.
2247 2021 *
2248 2022 * @param string $type Supports `auto`, `pro`, or `pro_only`.
2249 - *
2250 2023 * @return array
2251 2024 */
2252 2025 public static function frm_capabilities( $type = 'auto' ) {
2253 2026 if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
@@ -2265,8 +2038,14 @@
2265 2038 * @param array<string,string> $pro_cap
2266 2039 */
2267 2040 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
2268 2041
2042 + if ( ! array_key_exists( 'frm_edit_displays', $pro_cap ) && is_callable( 'FrmProAppHelper::views_is_installed' ) && FrmProAppHelper::views_is_installed() ) {
2043 + // For backward compatibility, add the Add/Edit Views permission if Pro is not up to date.
2044 + // This was added in 6.5.4. Remove this in the future.
2045 + $pro_cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
2046 + }
2047 +
2269 2048 if ( 'pro_only' === $type ) {
2270 2049 return $pro_cap;
2271 2050 }
2272 2051
@@ -2312,18 +2091,21 @@
2312 2091 if ( $role === 'loggedin' || ! $role ) {
2313 2092 return is_user_logged_in();
2314 2093 }
2315 2094
2316 - if ( (int) $role === 1 ) {
2095 + if ( $role == 1 ) {
2317 2096 $role = 'administrator';
2318 2097 }
2319 2098
2320 - return is_user_logged_in() ? current_user_can( $role ) : false;
2099 + if ( ! is_user_logged_in() ) {
2100 + return false;
2101 + }
2102 +
2103 + return current_user_can( $role );
2321 2104 }
2322 2105
2323 2106 /**
2324 2107 * @param array|string $needed_role
2325 - *
2326 2108 * @return bool
2327 2109 */
2328 2110 public static function user_has_permission( $needed_role ) {
2329 2111 if ( is_array( $needed_role ) ) {
@@ -2337,20 +2119,18 @@
2337 2119 }
2338 2120
2339 2121 $can = self::current_user_can( $needed_role );
2340 2122
2341 - if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ), true ) ) {
2123 + if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
2342 2124 return $can;
2343 2125 }
2344 2126
2345 2127 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
2346 -
2347 2128 foreach ( $roles as $role ) {
2348 2129 if ( current_user_can( $role ) ) {
2349 2130 return true;
2350 2131 }
2351 -
2352 - if ( $role === $needed_role ) {
2132 + if ( $role == $needed_role ) {
2353 2133 break;
2354 2134 }
2355 2135 }
2356 2136
@@ -2368,11 +2148,11 @@
2368 2148 if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
2369 2149 return;
2370 2150 }
2371 2151
2372 - $user = new WP_User( get_current_user_id() );
2152 + $user_id = get_current_user_id();
2153 + $user = new WP_User( $user_id );
2373 2154 $frm_roles = self::frm_capabilities();
2374 -
2375 2155 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2376 2156 $user->add_cap( $frm_role );
2377 2157 unset( $frm_role, $frm_role_description );
2378 2158 }
@@ -2383,22 +2163,18 @@
2383 2163 *
2384 2164 * @since 2.0.6
2385 2165 *
2386 2166 * @param string $cap
2387 - *
2388 2167 * @return void
2389 2168 */
2390 2169 public static function force_capability( $cap = 'frm_change_settings' ) {
2391 - if ( ! current_user_can( 'administrator' ) || current_user_can( $cap ) ) {
2392 - return;
2170 + if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
2171 + $role = get_role( 'administrator' );
2172 + $frm_roles = self::frm_capabilities();
2173 + foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2174 + $role->add_cap( $frm_role );
2175 + }
2393 2176 }
2394 -
2395 - $role = get_role( 'administrator' );
2396 - $frm_roles = self::frm_capabilities();
2397 -
2398 - foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2399 - $role->add_cap( $frm_role );
2400 - }
2401 2177 }
2402 2178
2403 2179 /**
2404 2180 * Check if the user has permission for action.
@@ -2406,22 +2182,17 @@
2406 2182 *
2407 2183 * @since 2.0
2408 2184 *
2409 2185 * @param string $permission
2410 - * @param string $show_message
2411 2186 */
2412 2187 public static function permission_check( $permission, $show_message = 'show' ) {
2413 2188 $permission_error = self::permission_nonce_error( $permission );
2414 -
2415 - if ( $permission_error === false ) {
2416 - return;
2189 + if ( $permission_error !== false ) {
2190 + if ( 'hide' == $show_message ) {
2191 + $permission_error = '';
2192 + }
2193 + wp_die( esc_html( $permission_error ) );
2417 2194 }
2418 -
2419 - if ( 'hide' === $show_message ) {
2420 - $permission_error = '';
2421 - }
2422 -
2423 - wp_die( esc_html( $permission_error ) );
2424 2195 }
2425 2196
2426 2197 /**
2427 2198 * Check user permission and nonce
@@ -2428,27 +2199,24 @@
2428 2199 *
2429 2200 * @since 2.0
2430 2201 *
2431 2202 * @param string $permission
2432 - * @param string $nonce_name
2433 - * @param string $nonce
2434 2203 *
2435 2204 * @return false|string The permission message or false if allowed
2436 2205 */
2437 2206 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
2438 - if ( $permission && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2207 + if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2439 2208 $frm_settings = self::get_settings();
2209 +
2440 2210 return $frm_settings->admin_permission;
2441 2211 }
2442 2212
2443 2213 $error = false;
2444 -
2445 - if ( ! $nonce_name ) {
2214 + if ( empty( $nonce_name ) ) {
2446 2215 return $error;
2447 2216 }
2448 2217
2449 2218 $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
2450 -
2451 2219 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
2452 2220 $frm_settings = self::get_settings();
2453 2221 $error = $frm_settings->admin_permission;
2454 2222 }
@@ -2455,14 +2223,8 @@
2455 2223
2456 2224 return $error;
2457 2225 }
2458 2226
2459 - /**
2460 - * @param array|string $values
2461 - * @param string $current
2462 - *
2463 - * @return void
2464 - */
2465 2227 public static function checked( $values, $current ) {
2466 2228 if ( self::check_selected( $values, $current ) ) {
2467 2229 echo ' checked="checked"';
2468 2230 }
@@ -2467,47 +2229,38 @@
2467 2229 echo ' checked="checked"';
2468 2230 }
2469 2231 }
2470 2232
2471 - /**
2472 - * @param array|string $values
2473 - * @param string|null $current
2474 - *
2475 - * @return bool
2476 - */
2477 2233 public static function check_selected( $values, $current ) {
2478 - $values = self::recursive_function_map( $values, 'trim' );
2479 - $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2234 + $values = self::recursive_function_map( $values, 'trim' );
2235 + $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2236 +
2480 2237 $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) );
2481 2238
2482 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons
2483 - return is_array( $values ) ? in_array( $current, $values ) : $values == $current;
2239 + return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
2484 2240 }
2485 2241
2486 - /**
2487 - * @param array|string $value
2488 - * @param callable|string $function
2489 - *
2490 - * @return array|string
2491 - */
2492 2242 public static function recursive_function_map( $value, $function ) {
2493 2243 if ( is_array( $value ) ) {
2494 2244 $original_function = $function;
2495 - $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function );
2496 -
2497 - if ( self::is_assoc( $value ) ) {
2245 + if ( count( $value ) ) {
2246 + $function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
2247 + } else {
2248 + $function = array( $function );
2249 + }
2250 + if ( ! self::is_assoc( $value ) ) {
2251 + $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2252 + } else {
2498 2253 foreach ( $value as $k => $v ) {
2499 2254 if ( ! is_array( $v ) ) {
2500 2255 $value[ $k ] = call_user_func( $original_function, $v );
2501 2256 }
2502 2257 }
2503 - } else {
2504 - $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2505 2258 }
2506 2259 } else {
2507 2260 $value = self::maybe_update_value_if_null( $value, $function );
2508 2261 $value = call_user_func( $function, $value );
2509 - }//end if
2262 + }
2510 2263
2511 2264 return $value;
2512 2265 }
2513 2266
@@ -2514,27 +2267,20 @@
2514 2267 /**
2515 2268 * Updates value to empty string if it is null and being passed to a string function.
2516 2269 *
2517 2270 * @since 6.8.4
2518 - *
2519 2271 * @param mixed $value
2520 2272 * @param string $function
2521 - *
2522 2273 * @return mixed
2523 2274 */
2524 2275 private static function maybe_update_value_if_null( $value, $function ) {
2525 2276 if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) {
2526 - return '';
2277 + $value = '';
2527 2278 }
2528 2279
2529 2280 return $value;
2530 2281 }
2531 2282
2532 - /**
2533 - * @param array $array
2534 - *
2535 - * @return bool
2536 - */
2537 2283 public static function is_assoc( $array ) {
2538 2284 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
2539 2285 }
2540 2286
@@ -2539,22 +2285,16 @@
2539 2285 }
2540 2286
2541 2287 /**
2542 2288 * Flatten a multi-dimensional array
2543 - *
2544 - * @param array $array
2545 - * @param string $keys
2546 - *
2547 - * @return array
2548 2289 */
2549 2290 public static function array_flatten( $array, $keys = 'keep' ) {
2550 2291 $return = array();
2551 -
2552 2292 foreach ( $array as $key => $value ) {
2553 2293 if ( is_array( $value ) ) {
2554 2294 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
2555 2295 } elseif ( $keys === 'keep' ) {
2556 - $return[ $key ] = $value;
2296 + $return[ $key ] = $value;
2557 2297 } else {
2558 2298 $return[] = $value;
2559 2299 }
2560 2300 }
@@ -2568,9 +2308,8 @@
2568 2308 * @since 6.16.1
2569 2309 *
2570 2310 * @param string $sep
2571 2311 * @param array $array
2572 - *
2573 2312 * @return string
2574 2313 */
2575 2314 public static function safe_implode( $sep, $array ) {
2576 2315 $array = self::array_flatten( $array );
@@ -2579,18 +2318,15 @@
2579 2318
2580 2319 /**
2581 2320 * @param string $text
2582 2321 * @param bool $is_rich_text
2583 - *
2584 2322 * @return string
2585 2323 */
2586 2324 public static function esc_textarea( $text, $is_rich_text = false ) {
2587 2325 $safe_text = str_replace( '&quot;', '"', $text );
2588 -
2589 2326 if ( ! $is_rich_text ) {
2590 2327 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
2591 2328 }
2592 -
2593 2329 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
2594 2330
2595 2331 /**
2596 2332 * @param string $safe_text
@@ -2602,59 +2338,44 @@
2602 2338 /**
2603 2339 * Add auto paragraphs to text areas
2604 2340 *
2605 2341 * @since 2.0
2606 - *
2607 - * @param mixed $content
2608 - *
2609 - * @return mixed
2610 2342 */
2611 2343 public static function use_wpautop( $content ) {
2612 2344 if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) {
2613 - return wpautop( str_replace( '<br>', '<br />', $content ) );
2345 + $content = wpautop( str_replace( '<br>', '<br />', $content ) );
2614 2346 }
2615 2347
2616 2348 return $content;
2617 2349 }
2618 2350
2619 - /**
2620 - * Replace quotes with their HTML entities.
2621 - *
2622 - * @param string $val
2623 - *
2624 - * @return string
2625 - */
2626 2351 public static function replace_quotes( $val ) {
2627 2352 // Replace double quotes.
2628 2353 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
2629 2354
2630 2355 // Replace single quotes.
2631 - return str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2356 + $val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2357 +
2358 + return $val;
2632 2359 }
2633 2360
2634 2361 /**
2635 - * @param string $handle
2636 - * @param int|string $default
2637 - *
2638 - * @return int|string
2362 + * @param string $handle
2639 2363 */
2640 2364 public static function script_version( $handle, $default = 0 ) {
2641 2365 global $wp_scripts;
2642 -
2643 2366 if ( ! $wp_scripts ) {
2644 2367 return $default;
2645 2368 }
2646 2369
2647 2370 $ver = $default;
2648 -
2649 2371 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
2650 2372 return $ver;
2651 2373 }
2652 2374
2653 2375 $query = $wp_scripts->registered[ $handle ];
2654 -
2655 2376 if ( is_object( $query ) && ! empty( $query->ver ) ) {
2656 - return $query->ver;
2377 + $ver = $query->ver;
2657 2378 }
2658 2379
2659 2380 return $ver;
2660 2381 }
@@ -2663,9 +2384,8 @@
2663 2384 * @since 5.0.13 added $echo param.
2664 2385 *
2665 2386 * @param string $url
2666 2387 * @param bool $echo
2667 - *
2668 2388 * @return string|null
2669 2389 */
2670 2390 public static function js_redirect( $url, $echo = false ) {
2671 2391 $callback = function () use ( $url ) {
@@ -2673,13 +2393,8 @@
2673 2393 };
2674 2394 return self::clip( $callback, $echo );
2675 2395 }
2676 2396
2677 - /**
2678 - * @param int|string $user_id
2679 - *
2680 - * @return int|string
2681 - */
2682 2397 public static function get_user_id_param( $user_id ) {
2683 2398 if ( ! $user_id || is_numeric( $user_id ) ) {
2684 2399 return $user_id;
2685 2400 }
@@ -2684,13 +2399,16 @@
2684 2399 return $user_id;
2685 2400 }
2686 2401
2687 2402 $user_id = sanitize_text_field( $user_id );
2688 -
2689 2403 if ( $user_id === 'current' ) {
2690 2404 $user_id = get_current_user_id();
2691 2405 } else {
2692 - $user = is_email( $user_id ) ? get_user_by( 'email', $user_id ) : get_user_by( 'login', $user_id );
2406 + if ( is_email( $user_id ) ) {
2407 + $user = get_user_by( 'email', $user_id );
2408 + } else {
2409 + $user = get_user_by( 'login', $user_id );
2410 + }
2693 2411
2694 2412 if ( $user ) {
2695 2413 $user_id = $user->ID;
2696 2414 }
@@ -2702,9 +2420,8 @@
2702 2420
2703 2421 /**
2704 2422 * @param string $filename
2705 2423 * @param array $atts
2706 - *
2707 2424 * @return false|string
2708 2425 */
2709 2426 public static function get_file_contents( $filename, $atts = array() ) {
2710 2427 if ( ! is_file( $filename ) ) {
@@ -2713,9 +2430,12 @@
2713 2430
2714 2431 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
2715 2432 ob_start();
2716 2433 include $filename;
2717 - return ob_get_clean();
2434 + $contents = ob_get_contents();
2435 + ob_end_clean();
2436 +
2437 + return $contents;
2718 2438 }
2719 2439
2720 2440 /**
2721 2441 * @param string $name
@@ -2725,9 +2445,8 @@
2725 2445 * @param int $num_chars
2726 2446 */
2727 2447 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
2728 2448 $key = '';
2729 -
2730 2449 if ( $name ) {
2731 2450 $key = sanitize_key( $name );
2732 2451 $key = self::maybe_clear_long_key( $key, $column );
2733 2452 }
@@ -2747,31 +2466,31 @@
2747 2466 $column
2748 2467 );
2749 2468
2750 2469 // Create a unique field id if it has already been used.
2751 - if ( ! in_array( $key, $similar_keys, true ) ) {
2752 - return $key;
2753 - }
2470 + if ( in_array( $key, $similar_keys, true ) ) {
2471 + $key = self::maybe_truncate_key_before_appending( $column, $key );
2754 2472
2755 - $key = self::maybe_truncate_key_before_appending( $column, $key );
2473 + /**
2474 + * Allow for a custom separator between the attempted key and the generated suffix.
2475 + *
2476 + * @since 5.2.03
2477 + *
2478 + * @param string $separator. Default empty.
2479 + * @param string $key the key without the added suffix.
2480 + */
2481 + $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2756 2482
2757 - /**
2758 - * Allow for a custom separator between the attempted key and the generated suffix.
2759 - *
2760 - * @since 5.2.03
2761 - *
2762 - * @param string $separator. Default empty.
2763 - * @param string $key the key without the added suffix.
2764 - */
2765 - $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2483 + $suffix = 2;
2484 + do {
2485 + $key_check = $key . $separator . $suffix;
2486 + ++$suffix;
2487 + } while ( in_array( $key_check, $similar_keys, true ) );
2766 2488
2767 - $suffix = 2;
2768 - do {
2769 - $key_check = $key . $separator . $suffix;
2770 - ++$suffix;
2771 - } while ( in_array( $key_check, $similar_keys, true ) );
2489 + $key = $key_check;
2490 + }//end if
2772 2491
2773 - return $key_check;
2492 + return $key;
2774 2493 }
2775 2494
2776 2495 /**
2777 2496 * Avoid trying to append to a really long key,
@@ -2778,26 +2497,20 @@
2778 2497 * The database limit is 100 for form and field keys so we want to avoid getting too close.
2779 2498 *
2780 2499 * @param string $column
2781 2500 * @param string $key
2782 - *
2783 2501 * @return string
2784 2502 */
2785 2503 private static function maybe_truncate_key_before_appending( $column, $key ) {
2786 - if ( ! in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2787 - return $key;
2788 - }
2789 -
2790 - $max_key_length_before_truncating = 60;
2791 -
2792 - if ( strlen( $key ) > $max_key_length_before_truncating ) {
2793 - $key = substr( $key, 0, $max_key_length_before_truncating );
2794 -
2795 - if ( is_numeric( $key ) ) {
2796 - $key .= 'a';
2504 + if ( in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2505 + $max_key_length_before_truncating = 60;
2506 + if ( strlen( $key ) > $max_key_length_before_truncating ) {
2507 + $key = substr( $key, 0, $max_key_length_before_truncating );
2508 + if ( is_numeric( $key ) ) {
2509 + $key .= 'a';
2510 + }
2797 2511 }
2798 2512 }
2799 -
2800 2513 return $key;
2801 2514 }
2802 2515
2803 2516 /**
@@ -2804,14 +2517,13 @@
2804 2517 * Possibly reset a key to avoid conflicts with column size limits.
2805 2518 *
2806 2519 * @param string $key
2807 2520 * @param string $column
2808 - *
2809 2521 * @return string either the original key value, or an empty string if the key was too long.
2810 2522 */
2811 2523 private static function maybe_clear_long_key( $key, $column ) {
2812 2524 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
2813 - return '';
2525 + $key = '';
2814 2526 }
2815 2527 return $key;
2816 2528 }
2817 2529
@@ -2818,22 +2530,20 @@
2818 2530 /**
2819 2531 * @since 6.21 This is changed from `private` to `public`.
2820 2532 *
2821 2533 * @param int $num_chars
2822 - *
2823 2534 * @return string
2824 2535 */
2825 2536 public static function generate_new_key( $num_chars ) {
2826 - $max_slug_value = 36 ** $num_chars;
2537 + $max_slug_value = pow( 36, $num_chars );
2827 2538
2828 2539 // We want to have at least 2 characters in the slug.
2829 2540 $min_slug_value = 37;
2830 - return base_convert( random_int( $min_slug_value, $max_slug_value ), 10, 36 );
2541 + return base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
2831 2542 }
2832 2543
2833 2544 /**
2834 2545 * @param string $key
2835 - *
2836 2546 * @return string
2837 2547 */
2838 2548 private static function prevent_numeric_and_reserved_keys( $key ) {
2839 2549 if ( is_numeric( $key ) ) {
@@ -2847,14 +2557,12 @@
2847 2557 'editlink',
2848 2558 'siteurl',
2849 2559 'evenodd',
2850 2560 );
2851 -
2852 2561 if ( in_array( $key, $not_allowed, true ) ) {
2853 2562 $key .= 'a';
2854 2563 }
2855 2564 }
2856 -
2857 2565 return $key;
2858 2566 }
2859 2567
2860 2568 /**
@@ -2873,9 +2581,9 @@
2873 2581 if ( ! $record ) {
2874 2582 return false;
2875 2583 }
2876 2584
2877 - if ( ! $post_values ) {
2585 + if ( empty( $post_values ) ) {
2878 2586 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
2879 2587 }
2880 2588
2881 2589 $values = array(
@@ -2883,9 +2591,9 @@
2883 2591 'fields' => array(),
2884 2592 );
2885 2593
2886 2594 foreach ( array( 'name', 'description' ) as $var ) {
2887 - $default_val = $record->{$var} ?? '';
2595 + $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
2888 2596 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
2889 2597 unset( $var, $default_val );
2890 2598 }
2891 2599
@@ -2903,67 +2611,46 @@
2903 2611
2904 2612 return $values;
2905 2613 }
2906 2614
2907 - /**
2908 - * @param array|string $fields
2909 - * @param object $record
2910 - * @param array $values
2911 - * @param array $args
2912 - *
2913 - * @return void
2914 - */
2915 2615 private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
2916 - if ( ! $fields ) {
2917 - return;
2918 - }
2919 -
2920 - foreach ( (array) $fields as $field ) {
2921 - if ( ! self::is_admin_page() ) {
2922 - // Don't prep default values on the form settings page.
2923 - $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
2616 + if ( ! empty( $fields ) ) {
2617 + foreach ( (array) $fields as $field ) {
2618 + if ( ! self::is_admin_page() ) {
2619 + // Don't prep default values on the form settings page.
2620 + $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
2621 + }
2622 + $args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
2623 + self::fill_field_defaults( $field, $record, $values, $args );
2924 2624 }
2925 -
2926 - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id;
2927 - self::fill_field_defaults( $field, $record, $values, $args );
2928 2625 }
2929 2626 }
2930 2627
2931 - /**
2932 - * @param object $field
2933 - * @param object $record
2934 - * @param array $values
2935 - * @param array $args
2936 - *
2937 - * @return void
2938 - */
2939 2628 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
2940 2629 $post_values = $args['post_values'];
2941 2630
2942 2631 if ( $args['default'] ) {
2943 2632 $meta_value = $field->default_value;
2944 - } elseif ( $record->post_id && self::pro_is_installed() && ! empty( $field->field_options['post_field'] ) ) {
2633 + } elseif ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) {
2945 2634 if ( ! isset( $field->field_options['custom_field'] ) ) {
2946 2635 $field->field_options['custom_field'] = '';
2947 2636 }
2948 -
2949 - $meta_value = FrmProEntryMetaHelper::get_post_value(
2950 - $record->post_id,
2951 - $field->field_options['post_field'],
2952 - $field->field_options['custom_field'],
2953 - array(
2954 - 'truncate' => false,
2955 - 'type' => $field->type,
2956 - 'form_id' => $field->form_id,
2957 - 'field' => $field,
2958 - )
2959 - );
2637 + $meta_value = FrmProEntryMetaHelper::get_post_value(
2638 + $record->post_id,
2639 + $field->field_options['post_field'],
2640 + $field->field_options['custom_field'],
2641 + array(
2642 + 'truncate' => false,
2643 + 'type' => $field->type,
2644 + 'form_id' => $field->form_id,
2645 + 'field' => $field,
2646 + )
2647 + );
2960 2648 } else {
2961 2649 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
2962 2650 }//end if
2963 2651
2964 - $field_type = $post_values['field_options'][ 'type_' . $field->id ] ?? $field->type;
2965 -
2652 + $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
2966 2653 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
2967 2654 $new_value = $post_values['item_meta'][ $field->id ];
2968 2655 self::unserialize_or_decode( $new_value );
2969 2656 } else {
@@ -2978,9 +2665,9 @@
2978 2665 $args['field_type'] = $field_type;
2979 2666
2980 2667 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
2981 2668
2982 - if ( empty( $field_array['unique'] ) ) {
2669 + if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
2983 2670 $field_array['unique_msg'] = '';
2984 2671 }
2985 2672
2986 2673 $field_array = array_merge( (array) $field->field_options, $field_array );
@@ -3047,21 +2734,15 @@
3047 2734 }
3048 2735
3049 2736 /**
3050 2737 * Set to POST value or default
3051 - *
3052 - * @param array $post_values
3053 - * @param array $values
3054 - *
3055 - * @return void
3056 2738 */
3057 2739 private static function fill_form_defaults( $post_values, array &$values ) {
3058 2740 $form_defaults = FrmFormsHelper::get_default_opts();
3059 2741
3060 2742 foreach ( $form_defaults as $opt => $default ) {
3061 - // phpcs:ignore Universal.Operators.StrictComparisons
3062 2743 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
3063 - $values[ $opt ] = $post_values['options'][ $opt ] ?? $default;
2744 + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default;
3064 2745 }
3065 2746
3066 2747 unset( $opt, $default );
3067 2748 }
@@ -3071,9 +2752,9 @@
3071 2752 }
3072 2753
3073 2754 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
3074 2755 if ( ! isset( $values[ $h . '_html' ] ) ) {
3075 - $values[ $h . '_html' ] = $post_values['options'][ $h . '_html' ] ?? FrmFormsHelper::get_default_html( $h );
2756 + $values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
3076 2757 }
3077 2758 unset( $h );
3078 2759 }
3079 2760 }
@@ -3085,57 +2766,46 @@
3085 2766 *
3086 2767 * @return bool|int
3087 2768 */
3088 2769 public static function custom_style_value( $post_values ) {
3089 - if ( $post_values && isset( $post_values['options']['custom_style'] ) ) {
3090 - return absint( $post_values['options']['custom_style'] );
2770 + if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
2771 + $custom_style = absint( $post_values['options']['custom_style'] );
2772 + } else {
2773 + $frm_settings = self::get_settings();
2774 + $custom_style = ( $frm_settings->load_style !== 'none' );
3091 2775 }
3092 2776
3093 - $frm_settings = self::get_settings();
3094 - return $frm_settings->load_style !== 'none';
2777 + return $custom_style;
3095 2778 }
3096 2779
3097 2780 /**
3098 - * Truncate a string.
3099 - *
3100 - * Note: By default, this function will allow for a few additional characters more than $length.
3101 - * If a string has no spaces, it allows up to 50 additional characters. To force a true length limit,
3102 - * use $force_length_limit = true.
3103 - *
3104 2781 * @param mixed $original_string
3105 2782 * @param int|string $length
3106 2783 * @param int $minword
3107 2784 * @param string $continue
3108 - * @param bool $force_length_limit Force the final string to never exceed the length limit.
3109 - *
3110 2785 * @return string
3111 2786 */
3112 - public static function truncate( $original_string, $length, $minword = 3, $continue = '...', $force_length_limit = false ) {
2787 + public static function truncate( $original_string, $length, $minword = 3, $continue = '...' ) {
3113 2788 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
3114 2789 return '';
3115 2790 }
3116 2791
3117 - $length = (int) $length;
2792 + $length = (int) $length;
2793 + $str = wp_strip_all_tags( (string) $original_string );
2794 + $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3118 2795
3119 - if ( $length === 0 ) {
2796 + if ( $length == 0 ) {
3120 2797 return '';
3121 2798 }
3122 2799
3123 - $str = wp_strip_all_tags( (string) $original_string );
3124 - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3125 -
3126 2800 if ( $length <= 10 ) {
3127 2801 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
3128 -
3129 - if ( $force_length_limit ) {
3130 - return $sub;
3131 - }
3132 -
3133 2802 return $sub . ( $length < $original_len ? $continue : '' );
3134 2803 }
3135 2804
3136 - $sub = '';
3137 - $len = 0;
2805 + $sub = '';
2806 + $len = 0;
2807 +
3138 2808 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
3139 2809
3140 2810 if ( ! is_array( $words ) ) {
3141 2811 return $original_string;
@@ -3141,11 +2811,10 @@
3141 2811 return $original_string;
3142 2812 }
3143 2813
3144 2814 foreach ( $words as $word ) {
3145 - $part = ( $sub !== '' ? ' ' : '' ) . $word;
2815 + $part = ( $sub != '' ? ' ' : '' ) . $word;
3146 2816 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
3147 -
3148 2817 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
3149 2818 break;
3150 2819 }
3151 2820
@@ -3158,21 +2827,10 @@
3158 2827
3159 2828 unset( $total_len, $word );
3160 2829 }
3161 2830
3162 - $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit );
2831 + $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length );
3163 2832
3164 - if ( $force_length_limit ) {
3165 - // Ensure the final string doesn't exceed the length limit.
3166 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3167 -
3168 - if ( $final_len > $length ) {
3169 - return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) );
3170 - }
3171 -
3172 - return $sub;
3173 - }
3174 -
3175 2833 return $sub . ( $len < $original_len ? $continue : '' );
3176 2834 }
3177 2835
3178 2836 /**
@@ -3179,51 +2837,30 @@
3179 2837 * If the string is still too long because there may not have been any spaces, force truncate.
3180 2838 *
3181 2839 * @since 6.5.4
3182 2840 *
3183 - * @param string $sub Current substring.
3184 - * @param int $length The length limit.
3185 - * @param bool $force_length_limit Force the string to not exceed the length limit.
3186 - *
2841 + * @param string $sub Current substring.
2842 + * @param int $length The length limit.
3187 2843 * @return string
3188 2844 */
3189 - private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit = false ) {
3190 - if ( ! $force_length_limit ) {
3191 - if ( strlen( $sub ) < $length + 50 ) {
3192 - // If the string isn't way over the limit, leave it.
3193 - return $sub;
3194 - }
3195 -
3196 - $first_space = strpos( $sub, ' ', $length );
3197 -
3198 - if ( false !== $first_space ) {
3199 - // Ignore anything with spaces.
3200 - return $sub;
3201 - }
3202 -
3203 - return substr( $sub, 0, $length + 10 );
2845 + private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) {
2846 + if ( strlen( $sub ) < $length + 50 ) {
2847 + // If the string isn't way over the limit, leave it.
2848 + return $sub;
3204 2849 }
3205 2850
3206 - // When force_length_limit is true, ensure the string doesn't exceed the length.
3207 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3208 -
3209 - if ( $final_len > $length ) {
3210 - return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) );
2851 + $first_space = strpos( $sub, ' ', $length );
2852 + if ( false !== $first_space ) {
2853 + // Ignore anything with spaces.
2854 + return $sub;
3211 2855 }
3212 2856
3213 - return $sub;
2857 + return substr( $sub, 0, $length + 10 );
3214 2858 }
3215 2859
3216 - /**
3217 - * @param array $function_names
3218 - * @param array $args
3219 - *
3220 - * @return mixed
3221 - */
3222 2860 public static function mb_function( $function_names, $args ) {
3223 2861 $mb_function_name = $function_names[0];
3224 2862 $function_name = $function_names[1];
3225 -
3226 2863 if ( function_exists( $mb_function_name ) ) {
3227 2864 $function_name = $mb_function_name;
3228 2865 }
3229 2866
@@ -3229,21 +2866,14 @@
3229 2866
3230 2867 return call_user_func_array( $function_name, $args );
3231 2868 }
3232 2869
3233 - /**
3234 - * @param string $date
3235 - * @param string $date_format
3236 - * @param string $time_format
3237 - *
3238 - * @return string
3239 - */
3240 2870 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
3241 - if ( ! $date ) {
2871 + if ( empty( $date ) ) {
3242 2872 return $date;
3243 2873 }
3244 2874
3245 - if ( ! $date_format ) {
2875 + if ( empty( $date_format ) ) {
3246 2876 $date_format = get_option( 'date_format' );
3247 2877 }
3248 2878
3249 2879 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
@@ -3251,10 +2881,10 @@
3251 2881 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
3252 2882 }
3253 2883
3254 2884 $formatted = self::get_localized_date( $date_format, $date );
3255 - $do_time = gmdate( 'H:i:s', strtotime( $date ) ) !== '00:00:00';
3256 2885
2886 + $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
3257 2887 if ( $do_time ) {
3258 2888 $formatted .= self::add_time_to_date( $time_format, $date );
3259 2889 }
3260 2890
@@ -3263,35 +2893,30 @@
3263 2893
3264 2894 /**
3265 2895 * @param string $time_format
3266 2896 * @param string $date
3267 - *
3268 2897 * @return string
3269 2898 */
3270 2899 private static function add_time_to_date( $time_format, $date ) {
3271 - if ( ! $time_format ) {
2900 + if ( empty( $time_format ) ) {
3272 2901 $time_format = get_option( 'time_format' );
3273 2902 }
3274 2903
3275 2904 $trimmed_format = trim( $time_format );
3276 -
3277 - if ( $time_format && $trimmed_format ) {
3278 - return ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
2905 + $time = '';
2906 + if ( $time_format && ! empty( $trimmed_format ) ) {
2907 + $time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
3279 2908 }
3280 2909
3281 - return '';
2910 + return $time;
3282 2911 }
3283 2912
3284 2913 /**
3285 2914 * @since 2.0.8
3286 - *
3287 - * @param string $date_format
3288 - * @param string $date
3289 - *
3290 - * @return string
3291 2915 */
3292 2916 public static function get_localized_date( $date_format, $date ) {
3293 2917 $date = get_date_from_gmt( $date );
2918 +
3294 2919 return date_i18n( $date_format, strtotime( $date ) );
3295 2920 }
3296 2921
3297 2922 /**
@@ -3296,16 +2921,19 @@
3296 2921
3297 2922 /**
3298 2923 * Gets the time ago in words.
3299 2924 *
3300 - * @param int $from In seconds.
3301 - * @param int|string $to In seconds.
3302 - * @param int|string $levels Number of time units to include or a specific unit.
2925 + * @param int $from In seconds.
2926 + * @param int|string $to In seconds.
3303 2927 *
3304 - * @return string Time ago.
2928 + * @return string $time_ago
3305 2929 */
3306 2930 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
3307 - $now = ! $to && 0 !== $to ? new DateTime() : new DateTime( '@' . $to );
2931 + if ( empty( $to ) && 0 !== $to ) {
2932 + $now = new DateTime();
2933 + } else {
2934 + $now = new DateTime( '@' . $to );
2935 + }
3308 2936 $ago = new DateTime( '@' . $from );
3309 2937
3310 2938 // Get the time difference
3311 2939 $diff_object = $now->diff( $ago );
@@ -3319,9 +2947,8 @@
3319 2947
3320 2948 if ( ! is_numeric( $levels ) ) {
3321 2949 // Show time in specified unit.
3322 2950 $levels = self::get_unit( $levels );
3323 -
3324 2951 if ( isset( $time_strings[ $levels ] ) ) {
3325 2952 $diff = array(
3326 2953 $levels => self::time_format( $levels, $diff ),
3327 2954 );
@@ -3328,14 +2955,13 @@
3328 2955 $time_strings = array(
3329 2956 $levels => $time_strings[ $levels ],
3330 2957 );
3331 2958 }
3332 -
3333 2959 $levels = 1;
3334 2960 }
3335 2961
3336 2962 foreach ( $time_strings as $k => $v ) {
3337 - if ( ! empty( $diff[ $k ] ) ) {
2963 + if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
3338 2964 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
3339 2965 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
3340 2966 // Account for 0.
3341 2967 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
@@ -3343,21 +2969,17 @@
3343 2969 unset( $time_strings[ $k ] );
3344 2970 }
3345 2971 }
3346 2972
3347 - $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
3348 - $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2973 + $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
2974 + $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2975 + $time_ago_string = implode( ' ', $time_strings );
3349 2976
3350 - return implode( ' ', $time_strings );
2977 + return $time_ago_string;
3351 2978 }
3352 2979
3353 2980 /**
3354 2981 * @since 4.05.01
3355 - *
3356 - * @param string $unit
3357 - * @param array $diff
3358 - *
3359 - * @return int
3360 2982 */
3361 2983 private static function time_format( $unit, $diff ) {
3362 2984 $return = array(
3363 2985 'y' => 'y',
@@ -3362,14 +2984,14 @@
3362 2984 $return = array(
3363 2985 'y' => 'y',
3364 2986 'd' => 'days',
3365 2987 );
3366 -
3367 2988 if ( isset( $return[ $unit ] ) ) {
3368 2989 return $diff[ $return[ $unit ] ];
3369 2990 }
3370 2991
3371 2992 $total = $diff['days'] * self::convert_time( 'd', $unit );
2993 +
3372 2994 $times = array( 'h', 'i', 's' );
3373 2995
3374 2996 foreach ( $times as $time ) {
3375 2997 if ( ! isset( $diff[ $time ] ) ) {
@@ -3383,13 +3005,8 @@
3383 3005 }
3384 3006
3385 3007 /**
3386 3008 * @since 4.05.01
3387 - *
3388 - * @param string $from
3389 - * @param string $to
3390 - *
3391 - * @return int
3392 3009 */
3393 3010 private static function convert_time( $from, $to ) {
3394 3011 $convert = array(
3395 3012 's' => 1,
@@ -3405,26 +3022,20 @@
3405 3022 }
3406 3023
3407 3024 /**
3408 3025 * @since 4.05.01
3409 - *
3410 - * @param string $unit
3411 - *
3412 - * @return int|string
3413 3026 */
3414 3027 private static function get_unit( $unit ) {
3415 3028 $units = self::get_time_strings();
3416 -
3417 3029 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
3418 3030 return $unit;
3419 3031 }
3420 3032
3421 3033 foreach ( $units as $u => $strings ) {
3422 - if ( in_array( $unit, $strings, true ) ) {
3034 + if ( in_array( $unit, $strings ) ) {
3423 3035 return $u;
3424 3036 }
3425 3037 }
3426 -
3427 3038 return 1;
3428 3039 }
3429 3040
3430 3041 /**
@@ -3431,9 +3042,8 @@
3431 3042 * Get the translatable time strings. The untranslated version is a failsafe
3432 3043 * in case languages are changing for the unit set in the shortcode.
3433 3044 *
3434 3045 * @since 2.0.20
3435 - *
3436 3046 * @return array
3437 3047 */
3438 3048 private static function get_time_strings() {
3439 3049 return array(
@@ -3480,13 +3090,12 @@
3480 3090 /**
3481 3091 * @param int $r_count
3482 3092 * @param int $current_p
3483 3093 * @param int $p_size
3484 - *
3485 3094 * @return int
3486 3095 */
3487 3096 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
3488 - return $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size;
3097 + return ( $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size );
3489 3098 }
3490 3099
3491 3100 /**
3492 3101 * @param int $r_count
@@ -3491,13 +3100,11 @@
3491 3100 /**
3492 3101 * @param int $r_count
3493 3102 * @param int $current_p
3494 3103 * @param int $p_size
3495 - *
3496 3104 * @return int
3497 3105 */
3498 3106 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
3499 - // phpcs:ignore Universal.Operators.StrictComparisons
3500 3107 if ( $current_p == 1 ) {
3501 3108 return 1;
3502 3109 }
3503 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
@@ -3503,22 +3110,17 @@
3503 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
3504 3111 }
3505 3112
3506 3113 /**
3507 - * @param array $json_vars
3508 - *
3509 3114 * @return array
3510 3115 */
3511 3116 public static function json_to_array( $json_vars ) {
3512 3117 $vars = array();
3513 -
3514 3118 foreach ( $json_vars as $jv ) {
3515 3119 $jv_name = explode( '[', $jv['name'] );
3516 3120 $last = count( $jv_name ) - 1;
3517 -
3518 3121 foreach ( $jv_name as $p => $n ) {
3519 3122 $name = trim( $n, ']' );
3520 -
3521 3123 if ( ! isset( $l1 ) ) {
3522 3124 $l1 = $name;
3523 3125 }
3524 3126
@@ -3529,9 +3131,9 @@
3529 3131 if ( ! isset( $l3 ) ) {
3530 3132 $l3 = $name;
3531 3133 }
3532 3134
3533 - $this_val = $p === $last ? $jv['value'] : array();
3135 + $this_val = $p == $last ? $jv['value'] : array();
3534 3136
3535 3137 switch ( $p ) {
3536 3138 case 0:
3537 3139 $l1 = $name;
@@ -3564,15 +3166,10 @@
3564 3166
3565 3167 /**
3566 3168 * @param string $name
3567 3169 * @param string $l1
3568 - * @param mixed $val
3569 - * @param array $vars
3570 - *
3571 - * @return void
3572 3170 */
3573 3171 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
3574 - // phpcs:ignore Universal.Operators.StrictComparisons
3575 3172 if ( $name == '' ) {
3576 3173 $vars[] = $val;
3577 3174 } elseif ( ! isset( $vars[ $l1 ] ) ) {
3578 3175 $vars[ $l1 ] = $val;
@@ -3578,26 +3175,19 @@
3578 3175 $vars[ $l1 ] = $val;
3579 3176 }
3580 3177 }
3581 3178
3582 - /**
3583 - * @param string $name
3584 - * @param string $class
3585 - * @param string $form_name
3586 - *
3587 - * @return void
3588 - */
3589 3179 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
3590 3180 $tooltips = array(
3591 3181 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
3592 - '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
3182 + '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' ),
3593 3183 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3594 3184 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3595 - '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
3185 + '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' ),
3596 3186 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
3597 3187 /* translators: %1$s: Form name, %2$s: Date */
3598 - '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
3599 - '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
3188 + '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() ) ),
3189 + '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' ),
3600 3190 );
3601 3191
3602 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3603 3193 return;
@@ -3602,9 +3192,9 @@
3602 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3603 3193 return;
3604 3194 }
3605 3195
3606 - if ( 'open' === $class ) {
3196 + if ( 'open' == $class ) {
3607 3197 echo ' frm_help"';
3608 3198 } else {
3609 3199 echo ' class="frm_help"';
3610 3200 }
@@ -3610,9 +3200,9 @@
3610 3200 }
3611 3201
3612 3202 echo ' title="' . esc_attr( $tooltips[ $name ] );
3613 3203
3614 - if ( 'open' !== $class ) {
3204 + if ( 'open' != $class ) {
3615 3205 echo '"';
3616 3206 }
3617 3207 }
3618 3208
@@ -3617,28 +3207,20 @@
3617 3207 }
3618 3208
3619 3209 /**
3620 3210 * Add the current_page class to that page in the form nav
3621 - *
3622 - * @param int|string $page
3623 - * @param int|string $current_page
3624 - * @param array $action
3625 - *
3626 - * @return void
3627 3211 */
3628 3212 public static function select_current_page( $page, $current_page, $action = array() ) {
3629 - // phpcs:ignore Universal.Operators.StrictComparisons
3630 3213 if ( $current_page != $page ) {
3631 3214 return;
3632 3215 }
3633 3216
3634 3217 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
3635 -
3636 3218 if ( 'lite-reports' === $frm_action ) {
3637 3219 $frm_action = 'reports';
3638 3220 }
3639 3221
3640 - if ( ! $action || ( $frm_action && in_array( $frm_action, $action, true ) ) ) {
3222 + if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
3641 3223 echo ' class="current_page"';
3642 3224 }
3643 3225 }
3644 3226
@@ -3668,19 +3250,14 @@
3668 3250
3669 3251 // Add extra slashes for \r\n since WP strips them.
3670 3252 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
3671 3253
3672 - // Allow for &quot
3673 - return str_replace( '&quot;', '\\"', $post_content );
3254 + // allow for &quot
3255 + $post_content = str_replace( '&quot;', '\\"', $post_content );
3256 +
3257 + return $post_content;
3674 3258 }
3675 3259
3676 - /**
3677 - * @param array|string $val
3678 - * @param int|string $key
3679 - * @param array $post_content
3680 - *
3681 - * @return void
3682 - */
3683 3260 private static function prepare_action_slashes( $val, $key, &$post_content ) {
3684 3261 if ( ! isset( $post_content[ $key ] ) || is_numeric( $val ) ) {
3685 3262 return;
3686 3263 }
@@ -3689,17 +3266,15 @@
3689 3266 foreach ( $val as $k1 => $v1 ) {
3690 3267 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
3691 3268 unset( $k1, $v1 );
3692 3269 }
3270 + } else {
3271 + // Strip all slashes so everything is the same, no matter where the value is coming from
3272 + $val = stripslashes( $val );
3693 3273
3694 - return;
3274 + // Add backslashes before double quotes and forward slashes only
3275 + $post_content[ $key ] = addcslashes( $val, '"\\/' );
3695 3276 }
3696 -
3697 - // Strip all slashes so everything is the same, no matter where the value is coming from
3698 - $val = stripslashes( $val );
3699 -
3700 - // Add backslashes before double quotes and forward slashes only
3701 - $post_content[ $key ] = addcslashes( $val, '"\\/' );
3702 3277 }
3703 3278
3704 3279 /**
3705 3280 * Check for either json or serialized data. This is temporary while transitioning
@@ -3707,9 +3282,8 @@
3707 3282 *
3708 3283 * @since 4.02.03
3709 3284 *
3710 3285 * @param array|string $value
3711 - *
3712 3286 * @return void
3713 3287 */
3714 3288 public static function unserialize_or_decode( &$value ) {
3715 3289 if ( is_array( $value ) ) {
@@ -3715,9 +3289,13 @@
3715 3289 if ( is_array( $value ) ) {
3716 3290 return;
3717 3291 }
3718 3292
3719 - $value = is_serialized( $value ) ? self::maybe_unserialize_array( $value ) : self::maybe_json_decode( $value, false );
3293 + if ( is_serialized( $value ) ) {
3294 + $value = self::maybe_unserialize_array( $value );
3295 + } else {
3296 + $value = self::maybe_json_decode( $value, false );
3297 + }
3720 3298 }
3721 3299
3722 3300 /**
3723 3301 * Safely unserialize an array if necessary.
@@ -3725,9 +3303,8 @@
3725 3303 *
3726 3304 * @since 6.2
3727 3305 *
3728 3306 * @param mixed $value
3729 - *
3730 3307 * @return mixed
3731 3308 */
3732 3309 public static function maybe_unserialize_array( $value ) {
3733 3310 if ( ! is_string( $value ) ) {
@@ -3734,15 +3311,18 @@
3734 3311 return $value;
3735 3312 }
3736 3313
3737 3314 // Since we only expect an array, skip anything that doesn't start with a:.
3738 - if ( ! is_serialized( $value ) || ! str_starts_with( $value, 'a:' ) ) {
3315 + if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
3739 3316 return $value;
3740 3317 }
3741 3318
3742 3319 $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
3320 + if ( is_array( $parsed ) ) {
3321 + $value = $parsed;
3322 + }
3743 3323
3744 - return is_array( $parsed ) ? $parsed : $value;
3324 + return $value;
3745 3325 }
3746 3326
3747 3327 /**
3748 3328 * Decode a JSON string.
@@ -3747,12 +3327,11 @@
3747 3327 /**
3748 3328 * Decode a JSON string.
3749 3329 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
3750 3330 *
3751 - * @param array|string|null $string
3752 - * @param bool $single_to_array
3753 - *
3754 - * @return array|string|null
3331 + * @param mixed $string
3332 + * @param bool $single_to_array
3333 + * @return mixed
3755 3334 */
3756 3335 public static function maybe_json_decode( $string, $single_to_array = true ) {
3757 3336 if ( is_array( $string ) || is_null( $string ) ) {
3758 3337 return $string;
@@ -3757,19 +3336,20 @@
3757 3336 if ( is_array( $string ) || is_null( $string ) ) {
3758 3337 return $string;
3759 3338 }
3760 3339
3761 - $new_string = json_decode( $string, true );
3762 - $single_value = false;
3763 -
3764 - if ( ! $single_to_array ) {
3765 - $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
3340 + $new_string = json_decode( $string, true );
3341 + if ( function_exists( 'json_last_error' ) ) {
3342 + // php 5.3+
3343 + $single_value = false;
3344 + if ( ! $single_to_array ) {
3345 + $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
3346 + }
3347 + if ( json_last_error() == JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3348 + $string = $new_string;
3349 + }
3766 3350 }
3767 3351
3768 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3769 - return $new_string;
3770 - }
3771 -
3772 3352 return $string;
3773 3353 }
3774 3354
3775 3355 /**
@@ -3775,9 +3355,8 @@
3775 3355 /**
3776 3356 * @since 6.2.3
3777 3357 *
3778 3358 * @param string $value
3779 - *
3780 3359 * @return string
3781 3360 */
3782 3361 public static function maybe_utf8_encode( $value ) {
3783 3362 $from_format = 'ISO-8859-1';
@@ -3786,15 +3365,13 @@
3786 3365 if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
3787 3366 if ( mb_check_encoding( $value, $from_format ) ) {
3788 3367 return mb_convert_encoding( $value, $to_format, $from_format );
3789 3368 }
3790 -
3791 3369 return $value;
3792 3370 }
3793 3371
3794 3372 if ( function_exists( 'iconv' ) ) {
3795 3373 $converted = iconv( $from_format, $to_format, $value );
3796 -
3797 3374 // Value is false if $value is not ISO-8859-1.
3798 3375 if ( false !== $converted ) {
3799 3376 return $converted;
3800 3377 }
@@ -3806,12 +3383,8 @@
3806 3383 /**
3807 3384 * Reformat the json serialized array in name => value array.
3808 3385 *
3809 3386 * @since 4.02.03
3810 - *
3811 - * @param array $form
3812 - *
3813 - * @return void
3814 3387 */
3815 3388 public static function format_form_data( &$form ) {
3816 3389 $formatted = array();
3817 3390
@@ -3818,21 +3391,18 @@
3818 3391 foreach ( $form as $input ) {
3819 3392 if ( ! isset( $input['name'] ) ) {
3820 3393 continue;
3821 3394 }
3822 -
3823 3395 $key = $input['name'];
3824 -
3825 - if ( ! isset( $formatted[ $key ] ) ) {
3396 + if ( isset( $formatted[ $key ] ) ) {
3397 + if ( is_array( $formatted[ $key ] ) ) {
3398 + $formatted[ $key ][] = $input['value'];
3399 + } else {
3400 + $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3401 + }
3402 + } else {
3826 3403 $formatted[ $key ] = $input['value'];
3827 - continue;
3828 3404 }
3829 -
3830 - if ( is_array( $formatted[ $key ] ) ) {
3831 - $formatted[ $key ][] = $input['value'];
3832 - } else {
3833 - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3834 - }
3835 3405 }
3836 3406
3837 3407 parse_str( http_build_query( $formatted ), $form );
3838 3408 }
@@ -3840,13 +3410,15 @@
3840 3410 /**
3841 3411 * @since 4.02.03
3842 3412 *
3843 3413 * @param array|string $value
3844 - *
3845 3414 * @return string
3846 3415 */
3847 3416 public static function maybe_json_encode( $value ) {
3848 - return is_array( $value ) ? wp_json_encode( $value ) : $value;
3417 + if ( is_array( $value ) ) {
3418 + $value = wp_json_encode( $value );
3419 + }
3420 + return $value;
3849 3421 }
3850 3422
3851 3423 /**
3852 3424 * Echo The javascript to open and highlight the Formidable menu
@@ -3853,19 +3425,18 @@
3853 3425 *
3854 3426 * @since 1.07.10
3855 3427 *
3856 3428 * @param string $post_type The name of the post type that may need to be highlighted.
3857 - *
3858 3429 * @return void
3859 3430 */
3860 3431 public static function maybe_highlight_menu( $post_type ) {
3861 3432 global $post;
3862 3433
3863 - if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] !== $post_type ) {
3434 + if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
3864 3435 return;
3865 3436 }
3866 3437
3867 - if ( is_object( $post ) && $post->post_type !== $post_type ) {
3438 + if ( is_object( $post ) && $post->post_type != $post_type ) {
3868 3439 return;
3869 3440 }
3870 3441
3871 3442 self::load_admin_wide_js();
@@ -3877,13 +3448,13 @@
3877 3448 *
3878 3449 * @since 2.0
3879 3450 *
3880 3451 * @param bool $load
3881 - *
3882 3452 * @return void
3883 3453 */
3884 3454 public static function load_admin_wide_js( $load = true ) {
3885 - wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), self::plugin_version() );
3455 + $version = self::plugin_version();
3456 + wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
3886 3457
3887 3458 $global_strings = array(
3888 3459 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
3889 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
@@ -3889,9 +3460,9 @@
3889 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
3890 3461 'url' => self::plugin_url(),
3891 3462 'app_url' => 'https://formidableforms.com/',
3892 3463 'applicationsUrl' => admin_url( 'admin.php?page=formidable-applications' ),
3893 - '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
3464 + 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ),
3894 3465 'loading' => __( 'Loading&hellip;', 'formidable' ),
3895 3466 'nonce' => wp_create_nonce( 'frm_ajax' ),
3896 3467 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
3897 3468 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(),
@@ -3904,9 +3475,8 @@
3904 3475 }
3905 3476
3906 3477 /**
3907 3478 * @since 2.0.9
3908 - *
3909 3479 * @return void
3910 3480 */
3911 3481 public static function load_font_style() {
3912 3482 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
@@ -3913,9 +3483,8 @@
3913 3483 }
3914 3484
3915 3485 /**
3916 3486 * @param string $location
3917 - *
3918 3487 * @return void
3919 3488 */
3920 3489 public static function localize_script( $location ) {
3921 3490 global $wp_scripts, $wp_version;
@@ -3938,9 +3507,8 @@
3938 3507 'include_resend_email' => false,
3939 3508 );
3940 3509
3941 3510 $data = $wp_scripts->get_data( 'formidable', 'data' );
3942 -
3943 3511 if ( ! $data ) {
3944 3512 wp_localize_script( 'formidable', 'frm_js', $script_strings );
3945 3513 }
3946 3514
@@ -3947,9 +3515,9 @@
3947 3515 if ( $location === 'admin' ) {
3948 3516 $admin_script_strings = array(
3949 3517 'desc' => __( '(Click to add description)', 'formidable' ),
3950 3518 'blank' => __( '(Blank)', 'formidable' ),
3951 - 'no_label' => self::get_no_label_text(),
3519 + 'no_label' => __( '(no label)', 'formidable' ),
3952 3520 'ok' => __( 'OK', 'formidable' ),
3953 3521 'cancel' => __( 'Cancel', 'formidable' ),
3954 3522 'default_label' => __( 'Default', 'formidable' ),
3955 3523 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3957,9 +3525,9 @@
3957 3525 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3958 3526 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3959 3527 'confirm' => __( 'Are you sure?', 'formidable' ),
3960 3528 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3961 - '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
3529 + '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' ),
3962 3530 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3963 3531 'default_unique' => FrmFieldsHelper::default_unique_msg(),
3964 3532 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3965 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
@@ -3965,9 +3533,9 @@
3965 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
3966 3534 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3967 3535 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3968 3536 'new_option' => __( 'New Option', 'formidable' ),
3969 - '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
3537 + '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' ),
3970 3538 'enter_password' => __( 'Enter Password', 'formidable' ),
3971 3539 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3972 3540 'import_complete' => __( 'Import Complete', 'formidable' ),
3973 3541 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
@@ -3981,15 +3549,13 @@
3981 3549 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
3982 3550 /* translators: %d is the number of allowed actions per form */
3983 3551 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ),
3984 3552 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ),
3985 - 'only_one_payment_action' => __( 'This form already has a payment action, and is currently limited to a single payment action.', 'formidable' ),
3986 - 'only_one_stripe_action' => __( 'This form already has a payment action. Multiple Stripe actions are available when using the Stripe add-on, available for Formidable Business licenses and higher.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3987 3553 'unsafe_params' => FrmFormsHelper::reserved_words(),
3988 3554 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
3989 - 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3555 + 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
3990 3556 /* 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. */
3991 - '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
3557 + 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
3992 3558 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3993 3559 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3994 3560 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3995 3561 'install' => __( 'Install', 'formidable' ),
@@ -4010,14 +3576,11 @@
4010 3576 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
4011 3577 'noTitleText' => FrmFormsHelper::get_no_title_text(),
4012 3578
4013 3579 // In older versions this event listener causes the section to immediately close again
4014 - // When the h3 element is clicked. It's only required in WP 6.7+.
3580 + // when the h3 element is clicked. It's only required in WP 6.7+.
4015 3581 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ),
4016 3582 );
4017 -
4018 - self::add_form_builder_modal_data( $admin_script_strings );
4019 -
4020 3583 /**
4021 3584 * @param array $admin_script_strings
4022 3585 */
4023 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
@@ -4022,9 +3585,8 @@
4022 3585 */
4023 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
4024 3587
4025 3588 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
4026 -
4027 3589 if ( ! $data ) {
4028 3590 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
4029 3591 }
4030 3592 }//end if
@@ -4030,91 +3592,8 @@
4030 3592 }//end if
4031 3593 }
4032 3594
4033 3595 /**
4034 - * @param array $admin_script_strings
4035 - *
4036 - * @return void
4037 - */
4038 - private static function add_form_builder_modal_data( &$admin_script_strings ) {
4039 - if ( ! self::is_form_builder_page() || self::pro_is_installed() ) {
4040 - return;
4041 - }
4042 -
4043 - $stripe_connected = FrmStrpLiteConnectHelper::at_least_one_mode_is_setup();
4044 - $square_connected = FrmSquareLiteConnectHelper::at_least_one_mode_is_setup();
4045 - $paypal_connected = FrmPayPalLiteConnectHelper::at_least_one_mode_is_setup();
4046 - $gateway_connected = $stripe_connected || $square_connected || $paypal_connected;
4047 - $payments_settings_url = FrmStrpLiteAppController::get_payments_settings_url();
4048 -
4049 - if ( ! $gateway_connected ) {
4050 - // This modal shows when user clicks on one of the pricing fields and no payment gateways configured.
4051 - $admin_script_strings['paymentsSettingsModal'] = array(
4052 - 'title' => __( 'Setup a Payment Gateway first', 'formidable' ),
4053 - 'msg' => __( 'To use the payment fields, please install and configure a payment gateway in your account settings.', 'formidable' ),
4054 - 'closeText' => __( 'Close', 'formidable' ),
4055 - 'actionUrl' => $payments_settings_url,
4056 - 'actionText' => __( 'Go to Payment Settings', 'formidable' ),
4057 - 'noCenter' => true,
4058 - );
4059 - }
4060 -
4061 - // This modal shows on load once after upgrading the plugin.
4062 - $show_pricing_fields_modal = get_option( 'frm_show_pricing_fields_modal' );
4063 -
4064 - if ( ! $show_pricing_fields_modal ) {
4065 - return;
4066 - }
4067 -
4068 - $admin_script_strings['pricingFieldsModal'] = array(
4069 - 'title' => esc_html__( 'Start Accepting Payments Today!', 'formidable' ),
4070 - 'img' => esc_url( self::plugin_url() . '/images/upsell/pricing-fields.png' ),
4071 - 'noCenter' => true,
4072 - );
4073 -
4074 - if ( $gateway_connected ) {
4075 - $gateway_texts = array();
4076 -
4077 - if ( $stripe_connected ) {
4078 - $gateway_texts['stripe'] = esc_html__( 'Stripe', 'formidable' );
4079 - }
4080 -
4081 - if ( $square_connected ) {
4082 - $gateway_texts['square'] = esc_html__( 'Square', 'formidable' );
4083 - }
4084 -
4085 - if ( $paypal_connected ) {
4086 - $gateway_texts['paypal'] = esc_html__( 'PayPal', 'formidable' );
4087 - }
4088 -
4089 - $admin_script_strings['pricingFieldsModal']['msg'] = sprintf(
4090 - // translators: %s: Stripe, Square, or PayPal.
4091 - esc_html__( 'You already have %s connected, so these have already been unlocked.', 'formidable' ),
4092 - esc_html( implode( ' ' . esc_html__( 'and', 'formidable' ) . ' ', $gateway_texts ) )
4093 - );
4094 - } else {
4095 - $admin_script_strings['pricingFieldsModal']['closeText'] = __( 'I\'ll do it later!', 'formidable' );
4096 - $admin_script_strings['pricingFieldsModal']['actionText'] = __( 'Setup Payments Now', 'formidable' );
4097 - $admin_script_strings['pricingFieldsModal']['actionUrl'] = $payments_settings_url;
4098 - // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4099 - $admin_script_strings['pricingFieldsModal']['msg'] = __( 'We\'ve unlocked Product, Quantity, and Total fields for Lite users! You can now transform your forms into checkout pages. To start collecting revenue, simply connect your preferred payment gateway (Stripe, Square, or PayPal) in your settings.', 'formidable' );
4100 - }//end if
4101 -
4102 - delete_option( 'frm_show_pricing_fields_modal' );
4103 - }
4104 -
4105 - /**
4106 - * Get the no label text.
4107 - *
4108 - * @since 6.25.1
4109 - *
4110 - * @return string
4111 - */
4112 - public static function get_no_label_text() {
4113 - return __( '(no label)', 'formidable' );
4114 - }
4115 -
4116 - /**
4117 3596 * @since 6.5
4118 3597 *
4119 3598 * @return string
4120 3599 */
@@ -4156,9 +3635,8 @@
4156 3635 *
4157 3636 * @since 1.07.10
4158 3637 *
4159 3638 * @param float $min_version The version the add-on requires.
4160 - *
4161 3639 * @return void
4162 3640 */
4163 3641 public static function min_version_notice( $min_version ) {
4164 3642 $frm_version = self::plugin_version();
@@ -4168,11 +3646,11 @@
4168 3646 return;
4169 3647 }
4170 3648
4171 3649 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
4172 - echo '<tr class="plugin-update-tr active"><th colspan="' . absint( $wp_list_table->get_column_count() ) . '" class="check-column plugin-update colspanchange"><div class="update-message">' . // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4173 - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
4174 - '</div></td></tr>';
3650 + 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">' .
3651 + esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
3652 + '</div></td></tr>';
4175 3653 }
4176 3654
4177 3655 /**
4178 3656 * If Pro is far outdated, show a message.
@@ -4178,10 +3656,8 @@
4178 3656 * If Pro is far outdated, show a message.
4179 3657 *
4180 3658 * @since 4.0.01
4181 3659 *
4182 - * @param string $min_version
4183 - *
4184 3660 * @return void
4185 3661 */
4186 3662 public static function min_pro_version_notice( $min_version ) {
4187 3663 if ( ! self::is_formidable_admin() ) {
@@ -4191,14 +3667,25 @@
4191 3667
4192 3668 self::php_version_notice();
4193 3669
4194 3670 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
4195 -
4196 3671 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
4197 3672 return;
4198 3673 }
4199 3674
4200 - include self::plugin_path() . '/classes/views/addons/min-version-notice.php';
3675 + $expired = FrmAddonsController::is_license_expired();
3676 + ?>
3677 + <div class="frm-banner-alert frm_error_style frm_previous_install">
3678 + <?php
3679 + esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
3680 + if ( empty( $expired ) ) {
3681 + echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
3682 + } else {
3683 + echo '<br/>Please <a href="https://formidableforms.com/account/downloads/?utm_source=WordPress&utm_medium=outdated">renew now</a> to get the latest version.';
3684 + }
3685 + ?>
3686 + </div>
3687 + <?php
4201 3688 }
4202 3689
4203 3690 /**
4204 3691 * If Pro is installed, check the version number.
@@ -4205,9 +3692,8 @@
4205 3692 *
4206 3693 * @since 4.0.01
4207 3694 *
4208 3695 * @param string $min_version
4209 - *
4210 3696 * @return bool
4211 3697 */
4212 3698 public static function meets_min_pro_version( $min_version ) {
4213 3699 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
@@ -4216,19 +3702,16 @@
4216 3702 /**
4217 3703 * Show a message if the PHP version is below the recommendations.
4218 3704 *
4219 3705 * @since 4.0.02
4220 - *
4221 3706 * @return void
4222 3707 */
4223 3708 private static function php_version_notice() {
4224 3709 $message = array();
4225 -
4226 3710 if ( version_compare( phpversion(), '7.0', '<' ) ) {
4227 - $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3711 + $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' );
4228 3712 }
4229 3713
4230 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4231 3714 foreach ( $message as $m ) {
4232 3715 ?>
4233 3716 <div class="frm-banner-alert frm_error_style frm_previous_install">
4234 3717 <?php echo esc_html( $m ); ?>
@@ -4234,14 +3717,12 @@
4234 3717 <?php echo esc_html( $m ); ?>
4235 3718 </div>
4236 3719 <?php
4237 3720 }
4238 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4239 3721 }
4240 3722
4241 3723 /**
4242 3724 * @param string $type
4243 - *
4244 3725 * @return array<string,string>
4245 3726 */
4246 3727 public static function locales( $type = 'date' ) {
4247 3728 $locales = array(
@@ -4335,12 +3816,12 @@
4335 3816 'zu' => __( 'Zulu', 'formidable' ),
4336 3817 );
4337 3818
4338 3819 if ( $type === 'captcha' ) {
4339 - // Remove the languages unavailable for the captcha
3820 + // remove the languages unavailable for the captcha
4340 3821 $unset = array( 'sq', 'bs', 'eo', 'fo', 'fr-CH', 'sr-SR', 'ar-DZ', 'be', 'cy-GB', 'kk', 'km', 'ky', 'lb', 'mk', 'nb', 'nn', 'rm', 'tj' );
4341 3822 } else {
4342 - // Remove the languages unavailable for the datepicker
3823 + // remove the languages unavailable for the datepicker
4343 3824 $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' );
4344 3825 }
4345 3826
4346 3827 $locales = array_diff_key( $locales, array_flip( $unset ) );
@@ -4351,13 +3832,14 @@
4351 3832 * @since 5.4.5 Added $args parameter with type.
4352 3833 *
4353 3834 * @param array<string,string> $locales
4354 3835 * @param array $args {
4355 - *
4356 3836 * @type string $type
4357 3837 * }
4358 3838 */
4359 - return apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3839 + $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3840 +
3841 + return $locales;
4360 3842 }
4361 3843
4362 3844 /**
4363 3845 * @return string
@@ -4364,14 +3846,12 @@
4364 3846 */
4365 3847 public static function get_menu_icon_class() {
4366 3848 if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
4367 3849 $settings = FrmProAppHelper::get_settings();
4368 -
4369 3850 if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
4370 3851 return $settings->menu_icon;
4371 3852 }
4372 3853 }
4373 -
4374 3854 return 'frmfont frm_logo_icon';
4375 3855 }
4376 3856
4377 3857 /**
@@ -4389,9 +3869,10 @@
4389 3869 * @type array $input_attrs Attributes of value input.
4390 3870 * }
4391 3871 */
4392 3872 public static function images_dropdown( $args ) {
4393 - $args = self::fill_default_images_dropdown_args( $args );
3873 + $args = self::fill_default_images_dropdown_args( $args );
3874 +
4394 3875 $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
4395 3876 ob_start();
4396 3877 include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
4397 3878 $output = ob_get_clean();
@@ -4412,9 +3893,8 @@
4412 3893 *
4413 3894 * @since 5.0.04
4414 3895 *
4415 3896 * @param array $args The arguments.
4416 - *
4417 3897 * @return array
4418 3898 */
4419 3899 private static function fill_default_images_dropdown_args( $args ) {
4420 3900 $defaults = array(
@@ -4427,8 +3907,14 @@
4427 3907
4428 3908 $new_args['options'] = (array) $new_args['options'];
4429 3909 $new_args['input_attrs'] = (array) $new_args['input_attrs'];
4430 3910
3911 + // Set the number of columns.
3912 + $new_args['col_class'] = ceil( 12 / count( $new_args['options'] ) );
3913 + if ( $new_args['col_class'] > 6 ) {
3914 + $new_args['col_class'] = ceil( $new_args['col_class'] / 2 );
3915 + }
3916 +
4431 3917 /**
4432 3918 * Allows modifying the arguments of images_dropdown() method.
4433 3919 *
4434 3920 * @since 5.0.04
@@ -4444,9 +3930,8 @@
4444 3930 *
4445 3931 * @since 5.0.04
4446 3932 *
4447 3933 * @param array $args The arguments.
4448 - *
4449 3934 * @return string
4450 3935 */
4451 3936 private static function get_images_dropdown_input_attrs( $args ) {
4452 3937 $input_attrs = $args['input_attrs'];
@@ -4453,9 +3938,8 @@
4453 3938 $input_attrs['type'] = 'radio';
4454 3939 $input_attrs['name'] = $args['name'];
4455 3940
4456 3941 $input_attrs_str = '';
4457 -
4458 3942 foreach ( $input_attrs as $key => $input_attr ) {
4459 3943 $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
4460 3944 }
4461 3945
@@ -4471,13 +3955,8 @@
4471 3955 }
4472 3956
4473 3957 /**
4474 3958 * @since 6.7.1
4475 - *
4476 - * @param array $option Option data.
4477 - * @param array $args The arguments of images_dropdown() method.
4478 - *
4479 - * @return array
4480 3959 */
4481 3960 public static function get_images_dropdown_atts( $option, $args ) {
4482 3961 $image = self::get_images_dropdown_option_image( $option, $args );
4483 3962 $classes = self::get_images_dropdown_option_classes( $option, $args );
@@ -4491,9 +3970,8 @@
4491 3970 * @since 5.0.04
4492 3971 *
4493 3972 * @param array $option Option data.
4494 3973 * @param array $args The arguments of images_dropdown() method.
4495 - *
4496 3974 * @return string
4497 3975 */
4498 3976 private static function get_images_dropdown_option_image( $option, $args ) {
4499 3977 $image = self::icon_by_class(
@@ -4522,9 +4000,8 @@
4522 4000 * @since 5.0.04
4523 4001 *
4524 4002 * @param array $option Option data.
4525 4003 * @param array $args The arguments of images_dropdown() method.
4526 - *
4527 4004 * @return string
4528 4005 */
4529 4006 private static function get_images_dropdown_option_classes( $option, $args ) {
4530 4007 $classes = '';
@@ -4552,19 +4029,17 @@
4552 4029 * @since 5.0.04
4553 4030 *
4554 4031 * @param array $option Option data.
4555 4032 * @param array $args The arguments of images_dropdown() method.
4556 - *
4557 4033 * @return string
4558 4034 */
4559 4035 private static function get_images_dropdown_option_html_attrs( $option, $args ) {
4560 4036 $html_attrs = '';
4561 -
4562 4037 if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
4563 4038 $html_attrs_arr = array();
4564 4039
4565 4040 foreach ( $option['custom_attrs'] as $key => $value ) {
4566 - if ( in_array( $key, array( 'type', 'class', 'data-value' ), true ) ) {
4041 + if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
4567 4042 continue;
4568 4043 }
4569 4044
4570 4045 $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
@@ -4622,13 +4097,14 @@
4622 4097 * @since 5.0.07
4623 4098 *
4624 4099 * @param array $values
4625 4100 * @param array $keys
4626 - *
4627 4101 * @return array
4628 4102 */
4629 4103 public static function maybe_filter_array( $values, $keys ) {
4630 - if ( self::allow_unfiltered_html() ) {
4104 + $allow_unfiltered_html = self::allow_unfiltered_html();
4105 +
4106 + if ( $allow_unfiltered_html ) {
4631 4107 return $values;
4632 4108 }
4633 4109
4634 4110 foreach ( $keys as $key ) {
@@ -4647,14 +4123,13 @@
4647 4123 * @since 5.0.13
4648 4124 *
4649 4125 * @param string $value
4650 4126 * @param array|string $allowed 'all' for everything included as defaults.
4651 - *
4652 4127 * @return string
4653 4128 */
4654 4129 public static function maybe_kses( $value, $allowed = 'all' ) {
4655 4130 if ( self::should_never_allow_unfiltered_html() ) {
4656 - return self::kses( $value, $allowed );
4131 + $value = self::kses( $value, $allowed );
4657 4132 }
4658 4133 return $value;
4659 4134 }
4660 4135
@@ -4664,18 +4139,17 @@
4664 4139 * @since 6.11.2
4665 4140 *
4666 4141 * @param string $key
4667 4142 * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed.
4668 - *
4669 4143 * @return bool
4670 4144 */
4671 4145 public static function input_key_is_safe( $key, $context = 'display' ) {
4672 4146 if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) {
4673 4147 $safe = true;
4674 - } elseif ( str_starts_with( $key, 'data-' ) ) {
4148 + } elseif ( 0 === strpos( $key, 'data-' ) ) {
4675 4149 // Allow all data attributes.
4676 4150 $safe = true;
4677 - } elseif ( str_starts_with( $key, 'aria-' ) ) {
4151 + } elseif ( 0 === strpos( $key, 'aria-' ) ) {
4678 4152 // Allow all aria attributes.
4679 4153 $safe = true;
4680 4154 } else {
4681 4155 $safe_keys = array(
@@ -4717,9 +4191,16 @@
4717 4191
4718 4192 /**
4719 4193 * @since 5.0.16
4720 4194 *
4721 - * @param string $medium
4195 + * @return bool
4196 + */
4197 + public static function show_landing_pages() {
4198 + return self::show_new_feature( 'landing' );
4199 + }
4200 +
4201 + /**
4202 + * @since 5.0.16
4722 4203 *
4723 4204 * @return array
4724 4205 */
4725 4206 public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
@@ -4727,9 +4208,8 @@
4727 4208 'medium' => $medium,
4728 4209 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
4729 4210 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
4730 4211 'screenshot' => 'landing.png',
4731 - 'learn-more' => self::get_doc_url( 'landing-page-forms', 'form-landing-page-settings', false ),
4732 4212 );
4733 4213 return self::get_upgrade_data_params( 'landing', $params );
4734 4214 }
4735 4215
@@ -4736,9 +4216,8 @@
4736 4216 /**
4737 4217 * @since 5.0.17
4738 4218 *
4739 4219 * @param string $feature
4740 - *
4741 4220 * @return bool
4742 4221 */
4743 4222 public static function show_new_feature( $feature ) {
4744 4223 $link = FrmAddonsController::install_link( $feature );
@@ -4745,21 +4224,16 @@
4745 4224 return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
4746 4225 }
4747 4226
4748 4227 /**
4749 - * Enhances upgrade data parameters with installation link and plan requirement information.
4750 - *
4751 4228 * @since 5.0.17
4752 4229 *
4753 - * @param string $plugin The plugin slug to get installation data for.
4754 - * @param array $params Initial parameters for the upgrade data.
4755 - * @param bool $detailed Whether to include detailed information.
4756 - *
4757 - * @return array Modified parameters with installation data.
4230 + * @param string $plugin
4231 + * @param array $params
4232 + * @return array
4758 4233 */
4759 - public static function get_upgrade_data_params( $plugin, $params, $detailed = false ) {
4234 + public static function get_upgrade_data_params( $plugin, $params ) {
4760 4235 $link = FrmAddonsController::install_link( $plugin );
4761 -
4762 4236 if ( ! $link ) {
4763 4237 return $params;
4764 4238 }
4765 4239
@@ -4765,20 +4239,15 @@
4765 4239
4766 4240 if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
4767 4241 $params['oneclick'] = json_encode( $link );
4768 4242 unset( $params['message'] );
4769 -
4770 4243 if ( ! isset( $params['medium'] ) ) {
4771 4244 $params['medium'] = $plugin;
4772 4245 }
4773 4246 } else {
4774 - $params['requires'] = $params['requires'] ?? FrmFormsHelper::get_plan_required( $link );
4247 + $params['requires'] = FrmFormsHelper::get_plan_required( $link );
4775 4248 }
4776 4249
4777 - if ( $detailed ) {
4778 - $params['plugin-status'] = $link['status'] ?? '';
4779 - }
4780 -
4781 4250 return $params;
4782 4251 }
4783 4252
4784 4253 /**
@@ -4787,9 +4256,8 @@
4787 4256 *
4788 4257 * @since 5.0.17
4789 4258 *
4790 4259 * @param string $text
4791 - *
4792 4260 * @return bool
4793 4261 */
4794 4262 public static function ctype_xdigit( $text ) {
4795 4263 if ( function_exists( 'ctype_xdigit' ) ) {
@@ -4804,14 +4272,12 @@
4804 4272 * @since 5.2.01
4805 4273 */
4806 4274 public static function set_current_screen_and_hook_suffix() {
4807 4275 global $hook_suffix;
4808 -
4809 4276 if ( is_null( $hook_suffix ) ) {
4810 4277 // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
4811 4278 $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
4812 4279 }
4813 -
4814 4280 set_current_screen();
4815 4281 }
4816 4282
4817 4283 /**
@@ -4818,9 +4284,9 @@
4818 4284 * Shows pill text.
4819 4285 *
4820 4286 * @since 5.2.02
4821 4287 *
4822 - * @param string|null $text Text in the pill. Default is NEW.
4288 + * @param string $text Text in the pill. Default is NEW.
4823 4289 */
4824 4290 public static function show_pill_text( $text = null ) {
4825 4291 if ( null === $text ) {
4826 4292 $text = __( 'NEW', 'formidable' );
@@ -4833,9 +4299,8 @@
4833 4299 *
4834 4300 * @since 5.2.07
4835 4301 *
4836 4302 * @param mixed $num Number.
4837 - *
4838 4303 * @return false|int Returns `false` if the passed parameter is not number.
4839 4304 */
4840 4305 public static function count_decimals( $num ) {
4841 4306 if ( ! is_numeric( $num ) ) {
@@ -4843,9 +4308,8 @@
4843 4308 }
4844 4309
4845 4310 $num = (string) $num;
4846 4311 $parts = explode( '.', $num );
4847 -
4848 4312 if ( 1 === count( $parts ) ) {
4849 4313 return 0;
4850 4314 }
4851 4315
@@ -4927,20 +4391,17 @@
4927 4391 * @since 5.5.5
4928 4392 *
4929 4393 * @param string $url
4930 4394 * @param string $expected_extension
4931 - *
4932 4395 * @return bool
4933 4396 */
4934 4397 public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
4935 - $file_is_in_expected_s3_bucket = str_starts_with( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4936 -
4398 + $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4937 4399 if ( ! $file_is_in_expected_s3_bucket ) {
4938 4400 return false;
4939 4401 }
4940 4402
4941 4403 $parsed = parse_url( $url );
4942 -
4943 4404 if ( ! is_array( $parsed ) ) {
4944 4405 // URL is malformed.
4945 4406 return false;
4946 4407 }
@@ -4946,10 +4407,14 @@
4946 4407 }
4947 4408
4948 4409 $path = $parsed['path'];
4949 4410 $ext = pathinfo( $path, PATHINFO_EXTENSION );
4950 - // The URL isn't to an XML file.
4951 - return $expected_extension === $ext;
4411 + if ( $expected_extension !== $ext ) {
4412 + // The URL isn't to an XML file.
4413 + return false;
4414 + }
4415 +
4416 + return true;
4952 4417 }
4953 4418
4954 4419 /**
4955 4420 * Display a dismissable warning message and save its dismissal state.
@@ -4957,9 +4422,8 @@
4957 4422 * @since 6.3
4958 4423 *
4959 4424 * @param string $message The warning message to display.
4960 4425 * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
4961 - *
4962 4426 * @return void
4963 4427 */
4964 4428 public static function add_dismissable_warning_message( $message = '', $option = '' ) {
4965 4429 if ( ! $message || ! $option ) {
@@ -5002,9 +4466,8 @@
5002 4466 *
5003 4467 * @since 6.3
5004 4468 *
5005 4469 * @param string $option The unique identifier for the dismissal state of the message.
5006 - *
5007 4470 * @return void
5008 4471 */
5009 4472 public static function dismiss_warning_message( $option = '' ) {
5010 4473 self::permission_check( 'frm_change_settings' );
@@ -5010,9 +4473,9 @@
5010 4473 self::permission_check( 'frm_change_settings' );
5011 4474 check_ajax_referer( 'frm_ajax', 'nonce' );
5012 4475
5013 4476 if ( $option ) {
5014 - update_option( $option, true, false );
4477 + update_option( $option, true, 'no' );
5015 4478 }
5016 4479
5017 4480 wp_send_json_success();
5018 4481 }
@@ -5026,8 +4489,17 @@
5026 4489 * @return string
5027 4490 */
5028 4491 public static function copy_for_lite_license() {
5029 4492 $message = __( 'You\'re using Formidable Forms Lite - no license needed. Enjoy!', 'formidable' ) . ' 🙂';
4493 +
4494 + if ( is_callable( 'FrmProAddonsController::get_readable_license_type' ) && ! class_exists( 'FrmProDashboardController' ) ) {
4495 + // Manage PRO versions without PRO dashboard functionality.
4496 + $license_type = FrmProAddonsController::get_readable_license_type();
4497 + if ( 'lite' !== strtolower( $license_type ) ) {
4498 + $message = 'Formidable Pro ' . $license_type;
4499 + }
4500 + }
4501 +
5030 4502 return apply_filters( 'frm_license_type_text', $message );
5031 4503 }
5032 4504
5033 4505 /**
@@ -5033,9 +4505,8 @@
5033 4505 /**
5034 4506 * Removes scripts that are unnecessarily loaded across the pages!
5035 4507 *
5036 4508 * @since 6.9
5037 - *
5038 4509 * @return void
5039 4510 */
5040 4511 public static function dequeue_extra_global_scripts() {
5041 4512 wp_dequeue_script( 'frm-surveys-admin' );
@@ -5053,21 +4524,18 @@
5053 4524 * @return void
5054 4525 */
5055 4526 public static function tooltip_icon( $tooltip_text, $atts = array() ) {
5056 4527 $atts['title'] = $tooltip_text;
5057 -
5058 4528 if ( isset( $atts['class'] ) ) {
5059 4529 $atts['class'] .= ' frm_help';
5060 4530 } else {
5061 4531 $atts['class'] = 'frm_help';
5062 4532 }
5063 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5064 4533 ?>
5065 4534 <span <?php self::array_to_html_params( $atts, true ); ?>>
5066 4535 <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?>
5067 4536 </span>
5068 4537 <?php
5069 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5070 4538 }
5071 4539
5072 4540 /**
5073 4541 * Prints errors for settings in onboarding wizard or template settings.
@@ -5088,10 +4556,8 @@
5088 4556 )
5089 4557 );
5090 4558
5091 4559 $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden';
5092 -
5093 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5094 4560 ?>
5095 4561 <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>">
5096 4562 <?php
5097 4563 if ( is_array( $args['errors'] ) ) {
@@ -5105,9 +4571,8 @@
5105 4571 }
5106 4572 ?>
5107 4573 </span>
5108 4574 <?php
5109 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5110 4575 }
5111 4576
5112 4577 /**
5113 4578 * Check if GDPR is enabled.
@@ -5130,62 +4595,6 @@
5130 4595 */
5131 4596 public static function no_gdpr_cookies() {
5132 4597 $frm_settings = self::get_settings();
5133 4598 return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies;
5134 - }
5135 -
5136 - /**
5137 - * Check if a string is valid UTF-8.
5138 - *
5139 - * @since 6.24
5140 - *
5141 - * @param string|null $string The string to check.
5142 - *
5143 - * @return bool
5144 - */
5145 - public static function is_valid_utf8( $string ) {
5146 - if ( is_null( $string ) ) {
5147 - // Return true so we do not attempt to change encoding on a null value.
5148 - return true;
5149 - }
5150 -
5151 - // wp_is_valid_utf8 is added in WP 6.9.
5152 - if ( function_exists( 'wp_is_valid_utf8' ) ) {
5153 - return wp_is_valid_utf8( $string );
5154 - }
5155 -
5156 - // As of WP 6.9, seems_utf8 is deprecated.
5157 - return function_exists( 'seems_utf8' ) ? seems_utf8( $string ) : false;
5158 - }
5159 -
5160 - /**
5161 - * Get a documentation URL with UTM parameters and affiliate tracking.
5162 - *
5163 - * @since 6.26
5164 - *
5165 - * @param string $path The relative path to append to the base URL.
5166 - * @param string $campaign The campaign to use for UTM parameters.
5167 - * @param bool $add_kb_base Whether to prepend 'knowledgebase/' to the path. Default true.
5168 - *
5169 - * @return string The processed URL with UTM parameters and affiliate tracking.
5170 - */
5171 - public static function get_doc_url( $path, $campaign, $add_kb_base = true ) {
5172 - $path = trim( $path, '/' );
5173 -
5174 - if ( $add_kb_base ) {
5175 - $path = 'knowledgebase/' . $path;
5176 - }
5177 -
5178 - return self::maybe_add_missing_utm( 'https://formidableforms.com/' . $path, array( 'campaign' => $campaign ) );
5179 - }
5180 -
5181 - /**
5182 - * @since 5.0.16
5183 - * @deprecated 6.26
5184 - *
5185 - * @return bool
5186 - */
5187 - public static function show_landing_pages() {
5188 - _deprecated_function( __METHOD__, '6.26' );
5189 - return true;
5190 4599 }
5191 4600 }