PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.22
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.22
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 +455 -1018 6.336.22 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.33';
32 + public static $plug_version = '6.22';
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' ) ) {
@@ -947,12 +834,8 @@
947 834 *
948 835 * @param string $value
949 836 */
950 837 public static function strip_most_html( $value ) {
951 - if ( '' === $value ) {
952 - return $value;
953 - }
954 -
955 838 $allowed_html = array(
956 839 'b' => array(),
957 840 'br' => array(),
958 841 'strong' => array(),
@@ -977,15 +860,12 @@
977 860 * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&amp;'
978 861 * this MUST be done, else we'll be back to the '& entity' problem.
979 862 *
980 863 * @since 4.0.04
981 - *
982 - * @param mixed $value Value to decode, passed by reference.
983 864 */
984 865 public static function decode_specialchars( &$value ) {
985 866 if ( is_array( $value ) ) {
986 867 $temp_values = $value;
987 -
988 868 foreach ( $temp_values as $k => $v ) {
989 869 self::decode_specialchars( $value[ $k ] );
990 870 }
991 871 } else {
@@ -999,13 +879,13 @@
999 879 * Adapted from wp_specialchars_decode().
1000 880 *
1001 881 * @since 4.03.01
1002 882 *
1003 - * @param string $string The string to prep, passed by reference.
883 + * @param string $string The string to prep.
1004 884 */
1005 885 private static function decode_amp( &$string ) {
1006 886 // Don't bother if there are no entities - saves a lot of processing
1007 - if ( ! $string || ! str_contains( $string, '&' ) ) {
887 + if ( empty( $string ) || strpos( $string, '&' ) === false ) {
1008 888 return;
1009 889 }
1010 890
1011 891 $translation = array(
@@ -1043,15 +923,17 @@
1043 923 * Sanitize the value, and allow some HTML
1044 924 *
1045 925 * @since 2.0
1046 926 *
1047 - * @param string $value The value to sanitize.
1048 - * @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.
1049 929 *
1050 930 * @return string
1051 931 */
1052 932 public static function kses( $value, $allowed = array() ) {
1053 - return wp_kses( $value, self::allowed_html( $allowed ) );
933 + $allowed_html = self::allowed_html( $allowed );
934 +
935 + return wp_kses( $value, $allowed_html );
1054 936 }
1055 937
1056 938 /**
1057 939 * Sanitizes and echoes a given value.
@@ -1059,9 +941,8 @@
1059 941 * @since 6.18
1060 942 *
1061 943 * @param string $value The value to sanitize and output.
1062 944 * @param array|string $allowed Allowed HTML tags and attributes.
1063 - *
1064 945 * @return void
1065 946 */
1066 947 public static function kses_echo( $value, $allowed = array() ) {
1067 948 echo self::kses( $value, $allowed ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -1072,23 +953,21 @@
1072 953 *
1073 954 * @since 5.0.13
1074 955 *
1075 956 * @param string $html
1076 - *
1077 957 * @return string
1078 958 */
1079 959 public static function kses_submit_button( $html ) {
1080 - $included_button_action = str_contains( $html, '[button_action]' );
1081 - $included_back_hook = str_contains( $html, '[back_hook]' );
1082 - $included_draft_hook = str_contains( $html, '[draft_hook]' );
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]' );
1083 963 add_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1084 964 add_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1085 965 $html = self::kses( $html, 'all' );
1086 966 remove_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1087 967 remove_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1088 -
1089 968 if ( $included_button_action ) {
1090 - if ( str_contains( $html, '<input type="submit"' ) ) {
969 + if ( false !== strpos( $html, '<input type="submit"' ) ) {
1091 970 $pattern = '/(<input type="submit")([^>]*)(\/>)/';
1092 971 $html = preg_replace( $pattern, '$1$2[button_action] $3', $html, 1 );
1093 972 } else {
1094 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
@@ -1094,17 +973,14 @@
1094 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
1095 974 $html = preg_replace( $pattern, '$1$2$3$4$5$6$7 [button_action]$8$9$10', $html, 1 );
1096 975 }
1097 976 }
1098 -
1099 977 if ( $included_back_hook ) {
1100 978 $html = str_replace( 'class="frm_prev_page"', 'class="frm_prev_page" [back_hook]', $html );
1101 979 }
1102 -
1103 980 if ( $included_draft_hook ) {
1104 - 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 );
1105 982 }
1106 -
1107 983 return $html;
1108 984 }
1109 985
1110 986 /**
@@ -1110,9 +986,8 @@
1110 986 /**
1111 987 * @since 5.0.13
1112 988 *
1113 989 * @param array $allowed_attr
1114 - *
1115 990 * @return array
1116 991 */
1117 992 public static function allow_visibility_style( $allowed_attr ) {
1118 993 $allowed_attr[] = 'visibility';
@@ -1122,9 +997,8 @@
1122 997 /**
1123 998 * @since 5.0.13
1124 999 *
1125 1000 * @param array $allowed_html
1126 - *
1127 1001 * @return array
1128 1002 */
1129 1003 public static function add_allowed_submit_button_tags( $allowed_html ) {
1130 1004 $allowed_html['input'] = array(
@@ -1141,22 +1015,17 @@
1141 1015 }
1142 1016
1143 1017 /**
1144 1018 * @since 2.05.03
1145 - *
1146 - * @param array|string $allowed
1147 - *
1148 - * @return array
1149 1019 */
1150 1020 private static function allowed_html( $allowed ) {
1151 1021 $html = self::safe_html();
1152 1022 $allowed_html = array();
1153 -
1154 1023 if ( $allowed === 'all' ) {
1155 1024 $allowed_html = $html;
1156 - } elseif ( $allowed ) {
1025 + } elseif ( ! empty( $allowed ) ) {
1157 1026 foreach ( (array) $allowed as $a ) {
1158 - $allowed_html[ $a ] = $html[ $a ] ?? array();
1027 + $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
1159 1028 }
1160 1029 }
1161 1030
1162 1031 return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
@@ -1163,10 +1032,8 @@
1163 1032 }
1164 1033
1165 1034 /**
1166 1035 * @since 2.05.03
1167 - *
1168 - * @return array
1169 1036 */
1170 1037 private static function safe_html() {
1171 1038 $allow_class = array(
1172 1039 'class' => true,
@@ -1318,16 +1185,14 @@
1318 1185 return;
1319 1186 }
1320 1187
1321 1188 $action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' );
1322 -
1323 - if ( ! $action_name ) {
1189 + if ( empty( $action_name ) ) {
1324 1190 return;
1325 1191 }
1326 1192
1327 1193 $new_action = self::get_param( $action_name, '', 'get', 'sanitize_text_field' );
1328 -
1329 - if ( $new_action ) {
1194 + if ( ! empty( $new_action ) ) {
1330 1195 $_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', self::get_server_value( 'REQUEST_URI' ) );
1331 1196 }
1332 1197 }
1333 1198
@@ -1334,23 +1199,21 @@
1334 1199 /**
1335 1200 * Check the WP query for a parameter
1336 1201 *
1337 1202 * @since 2.0
1338 - *
1339 - * @param array|string $value
1340 - * @param string $param
1341 - *
1342 1203 * @return array|string
1343 1204 */
1344 1205 public static function get_query_var( $value, $param ) {
1345 - // phpcs:ignore Universal.Operators.StrictComparisons
1346 1206 if ( $value != '' ) {
1347 1207 return $value;
1348 1208 }
1349 1209
1350 1210 global $wp_query;
1211 + if ( isset( $wp_query->query_vars[ $param ] ) ) {
1212 + $value = $wp_query->query_vars[ $param ];
1213 + }
1351 1214
1352 - return $wp_query->query_vars[ $param ] ?? $value;
1215 + return $value;
1353 1216 }
1354 1217
1355 1218 /**
1356 1219 * Try to show the SVG if possible. Otherwise, use the font icon.
@@ -1358,21 +1221,20 @@
1358 1221 * @since 4.0.02
1359 1222 *
1360 1223 * @param string $class
1361 1224 * @param array $atts
1362 - *
1363 1225 * @return string|null
1364 1226 */
1365 1227 public static function icon_by_class( $class, $atts = array() ) {
1366 1228 $echo = ! isset( $atts['echo'] ) || $atts['echo'];
1367 -
1368 1229 if ( isset( $atts['echo'] ) ) {
1369 1230 unset( $atts['echo'] );
1370 1231 }
1371 1232
1372 1233 $html_atts = self::array_to_html_params( $atts );
1373 - $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1374 1234
1235 + $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1236 +
1375 1237 // Replace icons that have been removed or renamed.
1376 1238 $deprecated = array(
1377 1239 'frm_clone_solid_icon' => 'frm_clone_icon',
1378 1240 'frm_keyalt_icon' => 'frm_key_icon',
@@ -1377,9 +1239,8 @@
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,24 +1247,21 @@
1386 1247
1387 1248 if ( $icon === $class ) {
1388 1249 $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
1389 1250 } else {
1390 - $class = str_contains( $icon, ' ' ) ? ' ' . $icon : '';
1391 -
1392 - if ( str_contains( $icon, ' ' ) ) {
1251 + $class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
1252 + if ( strpos( $icon, ' ' ) ) {
1393 1253 $icon = explode( ' ', $icon );
1394 1254 $icon = reset( $icon );
1395 1255 }
1396 -
1397 - $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use href="#' . esc_attr( $icon ) . '" /></svg>';
1256 + $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use xlink:href="#' . esc_attr( $icon ) . '" /></svg>';
1398 1257 }
1399 1258
1400 1259 if ( $echo ) {
1401 1260 echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1402 - return null;
1261 + } else {
1262 + return $icon;
1403 1263 }
1404 -
1405 - return $icon;
1406 1264 }
1407 1265
1408 1266 /**
1409 1267 * Run kses for icons. It needs to add a few filters first in order to preserve some custom style values.
@@ -1410,9 +1268,8 @@
1410 1268 *
1411 1269 * @since 5.0.13
1412 1270 *
1413 1271 * @param string $icon
1414 - *
1415 1272 * @return string
1416 1273 */
1417 1274 public static function kses_icon( $icon ) {
1418 1275 add_filter( 'safe_style_css', 'FrmAppHelper::allow_vars_in_styles' );
@@ -1428,15 +1285,13 @@
1428 1285 /**
1429 1286 * @since 5.0.13.1
1430 1287 *
1431 1288 * @param array $allowed_html
1432 - *
1433 1289 * @return array
1434 1290 */
1435 1291 public static function add_allowed_icon_tags( $allowed_html ) {
1436 1292 $allowed_html['svg']['data-open'] = true;
1437 1293 $allowed_html['svg']['title'] = true;
1438 - $allowed_html['svg']['tabindex'] = true;
1439 1294 return $allowed_html;
1440 1295 }
1441 1296
1442 1297 /**
@@ -1442,9 +1297,8 @@
1442 1297 /**
1443 1298 * @since 5.0.13
1444 1299 *
1445 1300 * @param array $allowed_attr
1446 - *
1447 1301 * @return array
1448 1302 */
1449 1303 public static function allow_vars_in_styles( $allowed_attr ) {
1450 1304 $allowed_attr[] = '--primary-700';
@@ -1457,9 +1311,9 @@
1457 1311 * @param bool $allow_css
1458 1312 * @param string $css_string
1459 1313 */
1460 1314 public static function allow_style( $allow_css, $css_string ) {
1461 - if ( ! $allow_css && str_starts_with( $css_string, '--primary-700:' ) ) {
1315 + if ( ! $allow_css && 0 === strpos( $css_string, '--primary-700:' ) ) {
1462 1316 $split = explode( ':', $css_string, 2 );
1463 1317 $allow_css = 2 === count( $split ) && self::is_a_valid_color( $split[1] );
1464 1318 }
1465 1319 return $allow_css;
@@ -1468,22 +1322,19 @@
1468 1322 /**
1469 1323 * @since 5.0.13
1470 1324 *
1471 1325 * @param string $value
1472 - *
1473 1326 * @return bool
1474 1327 */
1475 1328 private static function is_a_valid_color( $value ) {
1476 1329 $match = 0;
1477 -
1478 - if ( str_starts_with( $value, 'rgba(' ) ) {
1330 + if ( 0 === strpos( $value, 'rgba(' ) ) {
1479 1331 $match = preg_match( '/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/', $value );
1480 - } elseif ( str_starts_with( $value, 'rgb(' ) ) {
1332 + } elseif ( 0 === strpos( $value, 'rgb(' ) ) {
1481 1333 $match = preg_match( '/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/', $value );
1482 - } elseif ( str_starts_with( $value, '#' ) ) {
1334 + } elseif ( 0 === strpos( $value, '#' ) ) {
1483 1335 $match = preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})\b$/', $value );
1484 1336 }
1485 -
1486 1337 return (bool) $match;
1487 1338 }
1488 1339
1489 1340 /**
@@ -1489,9 +1340,8 @@
1489 1340 /**
1490 1341 * Include svg images.
1491 1342 *
1492 1343 * @since 4.0.02
1493 - *
1494 1344 * @return void
1495 1345 */
1496 1346 public static function include_svg() {
1497 1347 if ( self::$included_svg ) {
@@ -1510,20 +1360,17 @@
1510 1360 * @since 5.0.13 added $echo parameter.
1511 1361 *
1512 1362 * @param array $atts
1513 1363 * @param bool $echo
1514 - *
1515 1364 * @return string|void
1516 1365 */
1517 1366 public static function array_to_html_params( $atts, $echo = false ) {
1518 1367 $callback = function () use ( $atts ) {
1519 - if ( ! $atts ) {
1520 - return;
1368 + if ( $atts ) {
1369 + foreach ( $atts as $key => $value ) {
1370 + echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1371 + }
1521 1372 }
1522 -
1523 - foreach ( $atts as $key => $value ) {
1524 - echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1525 - }
1526 1373 };
1527 1374 return self::clip( $callback, $echo );
1528 1375 }
1529 1376
@@ -1533,12 +1380,9 @@
1533 1380 * @since 5.0.13
1534 1381 *
1535 1382 * @param Closure $echo_function
1536 1383 * @param bool $echo
1537 - *
1538 1384 * @return string|null
1539 - *
1540 - * @psalm-return ($echo is true ? null : string)
1541 1385 */
1542 1386 public static function clip( $echo_function, $echo = false ) {
1543 1387 if ( ! $echo ) {
1544 1388 ob_start();
@@ -1547,9 +1391,13 @@
1547 1391 if ( is_callable( $echo_function ) ) {
1548 1392 $echo_function();
1549 1393 }
1550 1394
1551 - return $echo ? null : ob_get_clean();
1395 + if ( ! $echo ) {
1396 + $return = ob_get_contents();
1397 + ob_end_clean();
1398 + return $return;
1399 + }
1552 1400 }
1553 1401
1554 1402 /**
1555 1403 * @since 3.0
@@ -1554,18 +1402,15 @@
1554 1402 /**
1555 1403 * @since 3.0
1556 1404 *
1557 1405 * @param array $atts
1558 - *
1559 1406 * @return void
1560 1407 */
1561 1408 public static function get_admin_header( $atts ) {
1562 1409 $has_nav = ! empty( $atts['form'] ) && empty( $atts['is_template'] );
1563 -
1564 1410 if ( empty( $atts['close'] ) ) {
1565 1411 $atts['close'] = admin_url( 'admin.php?page=formidable' );
1566 1412 }
1567 -
1568 1413 if ( ! isset( $atts['import_link'] ) ) {
1569 1414 $atts['import_link'] = false;
1570 1415 }
1571 1416
@@ -1575,19 +1420,16 @@
1575 1420 /**
1576 1421 * @since 6.0
1577 1422 *
1578 1423 * @param string $type
1579 - *
1580 1424 * @return void
1581 1425 */
1582 1426 public static function import_link( $type = 'secondary' ) {
1583 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1584 1427 ?>
1585 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">
1586 1429 <?php esc_html_e( 'Import', 'formidable' ); ?>
1587 1430 </a>
1588 1431 <?php
1589 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1590 1432 }
1591 1433
1592 1434 /**
1593 1435 * Print applicable admin banner.
@@ -1594,9 +1436,8 @@
1594 1436 *
1595 1437 * @since 5.4.2
1596 1438 *
1597 1439 * @param bool $should_show_lite_upgrade
1598 - *
1599 1440 * @return void
1600 1441 */
1601 1442 public static function print_admin_banner( $should_show_lite_upgrade ) {
1602 1443 if ( ! current_user_can( 'administrator' ) ) {
@@ -1608,15 +1449,13 @@
1608 1449 // Print license warning or inbox banner and exit if either prints.
1609 1450 // And exit before printing the upgrade bar if it shouldn't be shown.
1610 1451 return;
1611 1452 }
1612 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1613 1453 ?>
1614 1454 <div class="frm-upgrade-bar">
1615 1455 <div class="frm-upgrade-bar-inner">
1616 1456 <?php
1617 1457 $cta_text = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_text' );
1618 -
1619 1458 if ( ! $cta_text ) {
1620 1459 $cta_text = __( 'upgrading to PRO', 'formidable' );
1621 1460 }
1622 1461
@@ -1621,13 +1460,17 @@
1621 1460 }
1622 1461
1623 1462 $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' );
1624 1463 $utm = array(
1625 - 'campaign' => 'settings-license',
1626 - 'content' => 'lite-banner',
1464 + 'medium' => 'settings-license',
1465 + 'content' => 'lite-banner',
1627 1466 );
1628 1467
1629 - $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 + }
1630 1473
1631 1474 printf(
1632 1475 /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */
1633 1476 esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ),
@@ -1638,9 +1481,8 @@
1638 1481 ?>
1639 1482 </div>
1640 1483 </div>
1641 1484 <?php
1642 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1643 1485 }
1644 1486
1645 1487 /**
1646 1488 * @since 5.4.2
@@ -1654,9 +1496,8 @@
1654 1496 /**
1655 1497 * Render a button for a new item (Form, Application, etc).
1656 1498 *
1657 1499 * @since 3.0
1658 - *
1659 1500 * @param array $atts {
1660 1501 * Details about the button.
1661 1502 *
1662 1503 * @type array $link_hook Custom link hook, calls do_action and exits early.
@@ -1663,9 +1504,8 @@
1663 1504 * @type string $new_link Href value, default #.
1664 1505 * @type string $class Custom class names, space separated.
1665 1506 * @type string $button_text Button text. Default "Add New".
1666 1507 * }
1667 - *
1668 1508 * @return void
1669 1509 */
1670 1510 public static function add_new_item_link( $atts ) {
1671 1511 if ( isset( $atts['link_hook'] ) ) {
@@ -1691,12 +1531,8 @@
1691 1531 }
1692 1532
1693 1533 /**
1694 1534 * @since 3.06
1695 - *
1696 - * @param array $atts
1697 - *
1698 - * @return void
1699 1535 */
1700 1536 public static function show_search_box( $atts ) {
1701 1537 $defaults = array(
1702 1538 'placeholder' => '',
@@ -1703,9 +1539,8 @@
1703 1539 'tosearch' => '',
1704 1540 'text' => __( 'Search', 'formidable' ),
1705 1541 'input_id' => '',
1706 1542 'value' => false,
1707 - 'class' => '',
1708 1543 );
1709 1544 $atts = array_merge( $defaults, $atts );
1710 1545
1711 1546 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
@@ -1712,9 +1547,8 @@
1712 1547 $atts['tosearch'] = 'frm-card';
1713 1548 }
1714 1549
1715 1550 $class = 'frm-search-input';
1716 -
1717 1551 if ( ! empty( $atts['tosearch'] ) ) {
1718 1552 $class .= ' frm-auto-search';
1719 1553 }
1720 1554
@@ -1738,15 +1572,14 @@
1738 1572
1739 1573 if ( ! empty( $atts['tosearch'] ) ) {
1740 1574 $input_atts['autocomplete'] = 'off';
1741 1575 }
1742 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1743 1576 ?>
1744 - <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>">
1577 + <p class="frm-search">
1745 1578 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
1746 1579 <?php echo esc_html( $atts['text'] ); ?>:
1747 1580 </label>
1748 - <?php self::icon_by_class( 'frmfont frm_search_icon frm_svg20' ); ?>
1581 + <span class="frmfont frm_search_icon"></span>
1749 1582 <input <?php self::array_to_html_params( $input_atts, true ); ?> />
1750 1583 <?php
1751 1584 if ( empty( $atts['tosearch'] ) ) {
1752 1585 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
@@ -1753,21 +1586,17 @@
1753 1586 }
1754 1587 ?>
1755 1588 </p>
1756 1589 <?php
1757 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1758 1590 }
1759 1591
1760 1592 /**
1761 - * @param string $type Hook type slug.
1762 - * @param object|null $object Optional related object.
1763 - *
1593 + * @param string $type
1764 1594 * @return void
1765 1595 */
1766 1596 public static function trigger_hook_load( $type, $object = null ) {
1767 1597 // Only load the form hooks once.
1768 1598 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
1769 -
1770 1599 if ( ! $hooks_loaded ) {
1771 1600 do_action( 'frm_load_' . $type . '_hooks' );
1772 1601 }
1773 1602 }
@@ -1826,14 +1655,14 @@
1826 1655 * True when value is 1, true, 'true', 'yes'
1827 1656 *
1828 1657 * @since 1.07.10
1829 1658 *
1830 - * @param bool|int|string $value The value to compare.
1659 + * @param string $value The value to compare.
1831 1660 *
1832 1661 * @return bool
1833 1662 */
1834 1663 public static function is_true( $value ) {
1835 - return true === $value || '1' === (string) $value || 'true' === $value || 'yes' === $value;
1664 + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value;
1836 1665 }
1837 1666
1838 1667 /**
1839 1668 * Gets all post from a specific post type.
@@ -1841,9 +1670,8 @@
1841 1670 *
1842 1671 * @since 4.10.01 Add `$post_type` argument.
1843 1672 *
1844 1673 * @param string $post_type Post type to query. Default is `page`.
1845 - *
1846 1674 * @return WP_Post[]
1847 1675 */
1848 1676 public static function get_pages( $post_type = 'page' ) {
1849 1677 $query = array(
@@ -1862,9 +1690,8 @@
1862 1690 *
1863 1691 * @since 5.0.09
1864 1692 *
1865 1693 * @param string $post_type Post type to query. Default is `page`.
1866 - *
1867 1694 * @return array
1868 1695 */
1869 1696 public static function get_post_ids_and_titles( $post_type = 'page' ) {
1870 1697 return FrmDb::get_results(
@@ -1889,9 +1716,10 @@
1889 1716 *
1890 1717 * @param array $args Selection arguments.
1891 1718 */
1892 1719 public static function maybe_autocomplete_pages_options( $args ) {
1893 - $args = self::preformat_selection_args( $args );
1720 + $args = self::preformat_selection_args( $args );
1721 +
1894 1722 $pages_count = wp_count_posts( $args['post_type'] );
1895 1723
1896 1724 if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) {
1897 1725 self::wp_pages_dropdown( $args );
@@ -1938,11 +1766,11 @@
1938 1766 'value_key' => 'value',
1939 1767 'label_key' => 'label',
1940 1768 );
1941 1769
1942 - $args = wp_parse_args( $args, $defaults );
1770 + $args = wp_parse_args( $args, $defaults );
1771 +
1943 1772 $html_attrs = array();
1944 -
1945 1773 if ( ! empty( $args['name'] ) ) {
1946 1774 $html_attrs['name'] = $args['name'];
1947 1775 }
1948 1776
@@ -1949,9 +1777,8 @@
1949 1777 if ( ! empty( $args['id'] ) ) {
1950 1778 $html_attrs['id'] = $args['id'];
1951 1779 }
1952 1780
1953 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1954 1781 if ( count( $args['source'] ) <= $args['dropdown_limit'] ) {
1955 1782 ?>
1956 1783 <select <?php self::array_to_html_params( $html_attrs, true ); ?>>
1957 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
@@ -1957,44 +1784,40 @@
1957 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1958 1785 <?php
1959 1786 foreach ( $args['source'] as $key => $source ) :
1960 1787 $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1961 -
1962 1788 if ( ! empty( $args['truncate'] ) ) {
1963 1789 $value_label['label'] = self::truncate( $value_label['label'], $args['truncate'] );
1964 1790 }
1965 1791 ?>
1966 - <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>
1967 1793 <?php endforeach; ?>
1968 1794 </select>
1969 1795 <?php
1970 - return;
1971 - }
1972 - // 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 );
1973 1801
1974 - $options = array();
1975 - $autocomplete_value = '';
1802 + if ( $value_label['value'] === $args['selected'] ) {
1803 + $autocomplete_value = $value_label['label'];
1804 + }
1976 1805
1977 - foreach ( $args['source'] as $key => $source ) {
1978 - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1979 -
1980 - if ( $value_label['value'] === $args['selected'] ) {
1981 - $autocomplete_value = $value_label['label'];
1806 + $options[] = $value_label;
1982 1807 }
1983 1808
1984 - $options[] = $value_label;
1985 - }
1986 -
1987 - $html_attrs['type'] = 'hidden';
1988 - $html_attrs['class'] = 'frm_autocomplete_value_input';
1989 - $html_attrs['value'] = $args['selected'];
1990 - ?>
1991 - <input type="text" class="frm-custom-search"
1992 - data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
1993 - placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1994 - value="<?php echo esc_attr( $autocomplete_value ); ?>" />
1995 - <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
1996 - <?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
1997 1820 }
1998 1821
1999 1822 /**
2000 1823 * Gets dropdown value and label from autodropdown option.
@@ -2003,15 +1826,14 @@
2003 1826 *
2004 1827 * @param array|string $option Autocomplete option.
2005 1828 * @param string $key Array key of the option.
2006 1829 * @param array $args See {@see FrmAppHelper::maybe_autocomplete_options()}.
2007 - *
2008 1830 * @return array
2009 1831 */
2010 1832 private static function get_dropdown_value_and_label_from_option( $option, $key, $args ) {
2011 1833 if ( is_array( $option ) ) {
2012 - $value = $option[ $args['value_key'] ] ?? '';
2013 - $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'] ] : '';
2014 1836 } else {
2015 1837 $value = $key;
2016 1838 $label = $option;
2017 1839 }
@@ -2028,9 +1850,8 @@
2028 1850 self::prep_page_dropdown_params( $page_id, $truncate, $args );
2029 1851
2030 1852 $pages = self::get_post_ids_and_titles( $args['post_type'] );
2031 1853 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
2032 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2033 1854 ?>
2034 1855 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
2035 1856 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
2036 1857 <?php foreach ( $pages as $page ) { ?>
@@ -2039,9 +1860,8 @@
2039 1860 </option>
2040 1861 <?php } ?>
2041 1862 </select>
2042 1863 <?php
2043 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2044 1864 }
2045 1865
2046 1866 /**
2047 1867 * Fill in missing parameters passed to wp_pages_dropdown().
@@ -2047,14 +1867,8 @@
2047 1867 * Fill in missing parameters passed to wp_pages_dropdown().
2048 1868 * This is for reverse compatibility with switching 3 params to 1.
2049 1869 *
2050 1870 * @since 4.03.06
2051 - *
2052 - * @param string $page_id Deprecated.
2053 - * @param bool $truncate Deprecated.
2054 - * @param mixed $args
2055 - *
2056 - * @return void
2057 1871 */
2058 1872 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
2059 1873 if ( ! is_array( $args ) ) {
2060 1874 $args = array(
@@ -2071,12 +1885,8 @@
2071 1885 * Filter to format args for page dropdown or autocomplete
2072 1886 *
2073 1887 * @since 4.03.06
2074 1888 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
2075 - *
2076 - * @param array $args
2077 - *
2078 - * @return array
2079 1889 */
2080 1890 private static function preformat_selection_args( $args ) {
2081 1891 $defaults = array(
2082 1892 'truncate' => false,
@@ -2089,18 +1899,13 @@
2089 1899
2090 1900 return array_merge( $defaults, $args );
2091 1901 }
2092 1902
2093 - /**
2094 - * @param int $post_id
2095 - *
2096 - * @return string
2097 - */
2098 1903 public static function post_edit_link( $post_id ) {
2099 1904 $post = get_post( $post_id );
2100 -
2101 1905 if ( $post ) {
2102 1906 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1907 +
2103 1908 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
2104 1909 }
2105 1910
2106 1911 return '';
@@ -2113,9 +1918,11 @@
2113 1918 *
2114 1919 * @return bool
2115 1920 */
2116 1921 public static function is_full_screen() {
2117 - 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();
2118 1925 }
2119 1926
2120 1927 /**
2121 1928 * Check if user is on the style editor or its alternative URL.
@@ -2125,9 +1932,8 @@
2125 1932 * @since 5.5.3
2126 1933 * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
2127 1934 *
2128 1935 * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
2129 - *
2130 1936 * @return bool
2131 1937 */
2132 1938 public static function is_style_editor_page( $view = '' ) {
2133 1939 if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
@@ -2164,9 +1970,8 @@
2164 1970 * @param array|string $capability
2165 1971 * @param string $multiple 'single' and 'multiple'.
2166 1972 */
2167 1973 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
2168 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2169 1974 ?>
2170 1975 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
2171 1976 <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?>
2172 1977 class="frm_multiselect">
@@ -2172,14 +1977,12 @@
2172 1977 class="frm_multiselect">
2173 1978 <?php self::roles_options( $capability ); ?>
2174 1979 </select>
2175 1980 <?php
2176 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2177 1981 }
2178 1982
2179 1983 /**
2180 1984 * @since 4.07
2181 - *
2182 1985 * @param array|string $selected
2183 1986 * @param string $current
2184 1987 */
2185 1988 private static function selected( $selected, $current ) {
@@ -2194,9 +1997,8 @@
2194 1997 * @param array|string $capability
2195 1998 */
2196 1999 public static function roles_options( $capability ) {
2197 2000 global $frm_vars;
2198 -
2199 2001 if ( isset( $frm_vars['editable_roles'] ) ) {
2200 2002 $editable_roles = $frm_vars['editable_roles'];
2201 2003 } else {
2202 2004 $editable_roles = get_editable_roles();
@@ -2205,9 +2007,9 @@
2205 2007
2206 2008 foreach ( $editable_roles as $role => $details ) {
2207 2009 $name = translate_user_role( $details['name'] );
2208 2010 ?>
2209 - <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>
2210 2012 <?php
2211 2013 unset( $role, $details );
2212 2014 }
2213 2015 }
@@ -2217,9 +2019,8 @@
2217 2019 *
2218 2020 * @since 5.0 Parameter `$type` supports `pro_only` value.
2219 2021 *
2220 2022 * @param string $type Supports `auto`, `pro`, or `pro_only`.
2221 - *
2222 2023 * @return array
2223 2024 */
2224 2025 public static function frm_capabilities( $type = 'auto' ) {
2225 2026 if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
@@ -2237,8 +2038,14 @@
2237 2038 * @param array<string,string> $pro_cap
2238 2039 */
2239 2040 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
2240 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 +
2241 2048 if ( 'pro_only' === $type ) {
2242 2049 return $pro_cap;
2243 2050 }
2244 2051
@@ -2284,18 +2091,21 @@
2284 2091 if ( $role === 'loggedin' || ! $role ) {
2285 2092 return is_user_logged_in();
2286 2093 }
2287 2094
2288 - if ( (int) $role === 1 ) {
2095 + if ( $role == 1 ) {
2289 2096 $role = 'administrator';
2290 2097 }
2291 2098
2292 - 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 );
2293 2104 }
2294 2105
2295 2106 /**
2296 2107 * @param array|string $needed_role
2297 - *
2298 2108 * @return bool
2299 2109 */
2300 2110 public static function user_has_permission( $needed_role ) {
2301 2111 if ( is_array( $needed_role ) ) {
@@ -2309,20 +2119,18 @@
2309 2119 }
2310 2120
2311 2121 $can = self::current_user_can( $needed_role );
2312 2122
2313 - if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ), true ) ) {
2123 + if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
2314 2124 return $can;
2315 2125 }
2316 2126
2317 2127 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
2318 -
2319 2128 foreach ( $roles as $role ) {
2320 2129 if ( current_user_can( $role ) ) {
2321 2130 return true;
2322 2131 }
2323 -
2324 - if ( $role === $needed_role ) {
2132 + if ( $role == $needed_role ) {
2325 2133 break;
2326 2134 }
2327 2135 }
2328 2136
@@ -2340,11 +2148,11 @@
2340 2148 if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
2341 2149 return;
2342 2150 }
2343 2151
2344 - $user = new WP_User( get_current_user_id() );
2152 + $user_id = get_current_user_id();
2153 + $user = new WP_User( $user_id );
2345 2154 $frm_roles = self::frm_capabilities();
2346 -
2347 2155 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2348 2156 $user->add_cap( $frm_role );
2349 2157 unset( $frm_role, $frm_role_description );
2350 2158 }
@@ -2355,22 +2163,18 @@
2355 2163 *
2356 2164 * @since 2.0.6
2357 2165 *
2358 2166 * @param string $cap
2359 - *
2360 2167 * @return void
2361 2168 */
2362 2169 public static function force_capability( $cap = 'frm_change_settings' ) {
2363 - if ( ! current_user_can( 'administrator' ) || current_user_can( $cap ) ) {
2364 - 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 + }
2365 2176 }
2366 -
2367 - $role = get_role( 'administrator' );
2368 - $frm_roles = self::frm_capabilities();
2369 -
2370 - foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2371 - $role->add_cap( $frm_role );
2372 - }
2373 2177 }
2374 2178
2375 2179 /**
2376 2180 * Check if the user has permission for action.
@@ -2378,22 +2182,17 @@
2378 2182 *
2379 2183 * @since 2.0
2380 2184 *
2381 2185 * @param string $permission
2382 - * @param string $show_message
2383 2186 */
2384 2187 public static function permission_check( $permission, $show_message = 'show' ) {
2385 2188 $permission_error = self::permission_nonce_error( $permission );
2386 -
2387 - if ( $permission_error === false ) {
2388 - return;
2189 + if ( $permission_error !== false ) {
2190 + if ( 'hide' == $show_message ) {
2191 + $permission_error = '';
2192 + }
2193 + wp_die( esc_html( $permission_error ) );
2389 2194 }
2390 -
2391 - if ( 'hide' === $show_message ) {
2392 - $permission_error = '';
2393 - }
2394 -
2395 - wp_die( esc_html( $permission_error ) );
2396 2195 }
2397 2196
2398 2197 /**
2399 2198 * Check user permission and nonce
@@ -2400,27 +2199,24 @@
2400 2199 *
2401 2200 * @since 2.0
2402 2201 *
2403 2202 * @param string $permission
2404 - * @param string $nonce_name
2405 - * @param string $nonce
2406 2203 *
2407 2204 * @return false|string The permission message or false if allowed
2408 2205 */
2409 2206 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
2410 - if ( $permission && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2207 + if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2411 2208 $frm_settings = self::get_settings();
2209 +
2412 2210 return $frm_settings->admin_permission;
2413 2211 }
2414 2212
2415 2213 $error = false;
2416 -
2417 - if ( ! $nonce_name ) {
2214 + if ( empty( $nonce_name ) ) {
2418 2215 return $error;
2419 2216 }
2420 2217
2421 2218 $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
2422 -
2423 2219 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
2424 2220 $frm_settings = self::get_settings();
2425 2221 $error = $frm_settings->admin_permission;
2426 2222 }
@@ -2427,14 +2223,8 @@
2427 2223
2428 2224 return $error;
2429 2225 }
2430 2226
2431 - /**
2432 - * @param array|string $values
2433 - * @param string $current
2434 - *
2435 - * @return void
2436 - */
2437 2227 public static function checked( $values, $current ) {
2438 2228 if ( self::check_selected( $values, $current ) ) {
2439 2229 echo ' checked="checked"';
2440 2230 }
@@ -2439,47 +2229,38 @@
2439 2229 echo ' checked="checked"';
2440 2230 }
2441 2231 }
2442 2232
2443 - /**
2444 - * @param array|string $values
2445 - * @param string|null $current
2446 - *
2447 - * @return bool
2448 - */
2449 2233 public static function check_selected( $values, $current ) {
2450 - $values = self::recursive_function_map( $values, 'trim' );
2451 - $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 +
2452 2237 $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) );
2453 2238
2454 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons
2455 - return is_array( $values ) ? in_array( $current, $values ) : $values == $current;
2239 + return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
2456 2240 }
2457 2241
2458 - /**
2459 - * @param array|string $value
2460 - * @param callable|string $function
2461 - *
2462 - * @return array|string
2463 - */
2464 2242 public static function recursive_function_map( $value, $function ) {
2465 2243 if ( is_array( $value ) ) {
2466 2244 $original_function = $function;
2467 - $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function );
2468 -
2469 - 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 {
2470 2253 foreach ( $value as $k => $v ) {
2471 2254 if ( ! is_array( $v ) ) {
2472 2255 $value[ $k ] = call_user_func( $original_function, $v );
2473 2256 }
2474 2257 }
2475 - } else {
2476 - $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2477 2258 }
2478 2259 } else {
2479 2260 $value = self::maybe_update_value_if_null( $value, $function );
2480 2261 $value = call_user_func( $function, $value );
2481 - }//end if
2262 + }
2482 2263
2483 2264 return $value;
2484 2265 }
2485 2266
@@ -2486,27 +2267,20 @@
2486 2267 /**
2487 2268 * Updates value to empty string if it is null and being passed to a string function.
2488 2269 *
2489 2270 * @since 6.8.4
2490 - *
2491 2271 * @param mixed $value
2492 2272 * @param string $function
2493 - *
2494 2273 * @return mixed
2495 2274 */
2496 2275 private static function maybe_update_value_if_null( $value, $function ) {
2497 2276 if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) {
2498 - return '';
2277 + $value = '';
2499 2278 }
2500 2279
2501 2280 return $value;
2502 2281 }
2503 2282
2504 - /**
2505 - * @param array $array
2506 - *
2507 - * @return bool
2508 - */
2509 2283 public static function is_assoc( $array ) {
2510 2284 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
2511 2285 }
2512 2286
@@ -2511,22 +2285,16 @@
2511 2285 }
2512 2286
2513 2287 /**
2514 2288 * Flatten a multi-dimensional array
2515 - *
2516 - * @param array $array
2517 - * @param string $keys
2518 - *
2519 - * @return array
2520 2289 */
2521 2290 public static function array_flatten( $array, $keys = 'keep' ) {
2522 2291 $return = array();
2523 -
2524 2292 foreach ( $array as $key => $value ) {
2525 2293 if ( is_array( $value ) ) {
2526 2294 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
2527 2295 } elseif ( $keys === 'keep' ) {
2528 - $return[ $key ] = $value;
2296 + $return[ $key ] = $value;
2529 2297 } else {
2530 2298 $return[] = $value;
2531 2299 }
2532 2300 }
@@ -2540,9 +2308,8 @@
2540 2308 * @since 6.16.1
2541 2309 *
2542 2310 * @param string $sep
2543 2311 * @param array $array
2544 - *
2545 2312 * @return string
2546 2313 */
2547 2314 public static function safe_implode( $sep, $array ) {
2548 2315 $array = self::array_flatten( $array );
@@ -2551,18 +2318,15 @@
2551 2318
2552 2319 /**
2553 2320 * @param string $text
2554 2321 * @param bool $is_rich_text
2555 - *
2556 2322 * @return string
2557 2323 */
2558 2324 public static function esc_textarea( $text, $is_rich_text = false ) {
2559 2325 $safe_text = str_replace( '&quot;', '"', $text );
2560 -
2561 2326 if ( ! $is_rich_text ) {
2562 2327 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
2563 2328 }
2564 -
2565 2329 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
2566 2330
2567 2331 /**
2568 2332 * @param string $safe_text
@@ -2574,59 +2338,44 @@
2574 2338 /**
2575 2339 * Add auto paragraphs to text areas
2576 2340 *
2577 2341 * @since 2.0
2578 - *
2579 - * @param mixed $content
2580 - *
2581 - * @return mixed
2582 2342 */
2583 2343 public static function use_wpautop( $content ) {
2584 2344 if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) {
2585 - return wpautop( str_replace( '<br>', '<br />', $content ) );
2345 + $content = wpautop( str_replace( '<br>', '<br />', $content ) );
2586 2346 }
2587 2347
2588 2348 return $content;
2589 2349 }
2590 2350
2591 - /**
2592 - * Replace quotes with their HTML entities.
2593 - *
2594 - * @param string $val
2595 - *
2596 - * @return string
2597 - */
2598 2351 public static function replace_quotes( $val ) {
2599 2352 // Replace double quotes.
2600 2353 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
2601 2354
2602 2355 // Replace single quotes.
2603 - 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;
2604 2359 }
2605 2360
2606 2361 /**
2607 - * @param string $handle
2608 - * @param int|string $default
2609 - *
2610 - * @return int|string
2362 + * @param string $handle
2611 2363 */
2612 2364 public static function script_version( $handle, $default = 0 ) {
2613 2365 global $wp_scripts;
2614 -
2615 2366 if ( ! $wp_scripts ) {
2616 2367 return $default;
2617 2368 }
2618 2369
2619 2370 $ver = $default;
2620 -
2621 2371 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
2622 2372 return $ver;
2623 2373 }
2624 2374
2625 2375 $query = $wp_scripts->registered[ $handle ];
2626 -
2627 2376 if ( is_object( $query ) && ! empty( $query->ver ) ) {
2628 - return $query->ver;
2377 + $ver = $query->ver;
2629 2378 }
2630 2379
2631 2380 return $ver;
2632 2381 }
@@ -2635,9 +2384,8 @@
2635 2384 * @since 5.0.13 added $echo param.
2636 2385 *
2637 2386 * @param string $url
2638 2387 * @param bool $echo
2639 - *
2640 2388 * @return string|null
2641 2389 */
2642 2390 public static function js_redirect( $url, $echo = false ) {
2643 2391 $callback = function () use ( $url ) {
@@ -2645,13 +2393,8 @@
2645 2393 };
2646 2394 return self::clip( $callback, $echo );
2647 2395 }
2648 2396
2649 - /**
2650 - * @param int|string $user_id
2651 - *
2652 - * @return int|string
2653 - */
2654 2397 public static function get_user_id_param( $user_id ) {
2655 2398 if ( ! $user_id || is_numeric( $user_id ) ) {
2656 2399 return $user_id;
2657 2400 }
@@ -2656,13 +2399,16 @@
2656 2399 return $user_id;
2657 2400 }
2658 2401
2659 2402 $user_id = sanitize_text_field( $user_id );
2660 -
2661 2403 if ( $user_id === 'current' ) {
2662 2404 $user_id = get_current_user_id();
2663 2405 } else {
2664 - $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 + }
2665 2411
2666 2412 if ( $user ) {
2667 2413 $user_id = $user->ID;
2668 2414 }
@@ -2674,9 +2420,8 @@
2674 2420
2675 2421 /**
2676 2422 * @param string $filename
2677 2423 * @param array $atts
2678 - *
2679 2424 * @return false|string
2680 2425 */
2681 2426 public static function get_file_contents( $filename, $atts = array() ) {
2682 2427 if ( ! is_file( $filename ) ) {
@@ -2685,9 +2430,12 @@
2685 2430
2686 2431 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
2687 2432 ob_start();
2688 2433 include $filename;
2689 - return ob_get_clean();
2434 + $contents = ob_get_contents();
2435 + ob_end_clean();
2436 +
2437 + return $contents;
2690 2438 }
2691 2439
2692 2440 /**
2693 2441 * @param string $name
@@ -2697,9 +2445,8 @@
2697 2445 * @param int $num_chars
2698 2446 */
2699 2447 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
2700 2448 $key = '';
2701 -
2702 2449 if ( $name ) {
2703 2450 $key = sanitize_key( $name );
2704 2451 $key = self::maybe_clear_long_key( $key, $column );
2705 2452 }
@@ -2719,31 +2466,31 @@
2719 2466 $column
2720 2467 );
2721 2468
2722 2469 // Create a unique field id if it has already been used.
2723 - if ( ! in_array( $key, $similar_keys, true ) ) {
2724 - return $key;
2725 - }
2470 + if ( in_array( $key, $similar_keys, true ) ) {
2471 + $key = self::maybe_truncate_key_before_appending( $column, $key );
2726 2472
2727 - $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 );
2728 2482
2729 - /**
2730 - * Allow for a custom separator between the attempted key and the generated suffix.
2731 - *
2732 - * @since 5.2.03
2733 - *
2734 - * @param string $separator. Default empty.
2735 - * @param string $key the key without the added suffix.
2736 - */
2737 - $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 ) );
2738 2488
2739 - $suffix = 2;
2740 - do {
2741 - $key_check = $key . $separator . $suffix;
2742 - ++$suffix;
2743 - } while ( in_array( $key_check, $similar_keys, true ) );
2489 + $key = $key_check;
2490 + }//end if
2744 2491
2745 - return $key_check;
2492 + return $key;
2746 2493 }
2747 2494
2748 2495 /**
2749 2496 * Avoid trying to append to a really long key,
@@ -2750,26 +2497,20 @@
2750 2497 * The database limit is 100 for form and field keys so we want to avoid getting too close.
2751 2498 *
2752 2499 * @param string $column
2753 2500 * @param string $key
2754 - *
2755 2501 * @return string
2756 2502 */
2757 2503 private static function maybe_truncate_key_before_appending( $column, $key ) {
2758 - if ( ! in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2759 - return $key;
2760 - }
2761 -
2762 - $max_key_length_before_truncating = 60;
2763 -
2764 - if ( strlen( $key ) > $max_key_length_before_truncating ) {
2765 - $key = substr( $key, 0, $max_key_length_before_truncating );
2766 -
2767 - if ( is_numeric( $key ) ) {
2768 - $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 + }
2769 2511 }
2770 2512 }
2771 -
2772 2513 return $key;
2773 2514 }
2774 2515
2775 2516 /**
@@ -2776,14 +2517,13 @@
2776 2517 * Possibly reset a key to avoid conflicts with column size limits.
2777 2518 *
2778 2519 * @param string $key
2779 2520 * @param string $column
2780 - *
2781 2521 * @return string either the original key value, or an empty string if the key was too long.
2782 2522 */
2783 2523 private static function maybe_clear_long_key( $key, $column ) {
2784 2524 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
2785 - return '';
2525 + $key = '';
2786 2526 }
2787 2527 return $key;
2788 2528 }
2789 2529
@@ -2790,22 +2530,20 @@
2790 2530 /**
2791 2531 * @since 6.21 This is changed from `private` to `public`.
2792 2532 *
2793 2533 * @param int $num_chars
2794 - *
2795 2534 * @return string
2796 2535 */
2797 2536 public static function generate_new_key( $num_chars ) {
2798 - $max_slug_value = 36 ** $num_chars;
2537 + $max_slug_value = pow( 36, $num_chars );
2799 2538
2800 2539 // We want to have at least 2 characters in the slug.
2801 2540 $min_slug_value = 37;
2802 - 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 );
2803 2542 }
2804 2543
2805 2544 /**
2806 2545 * @param string $key
2807 - *
2808 2546 * @return string
2809 2547 */
2810 2548 private static function prevent_numeric_and_reserved_keys( $key ) {
2811 2549 if ( is_numeric( $key ) ) {
@@ -2819,14 +2557,12 @@
2819 2557 'editlink',
2820 2558 'siteurl',
2821 2559 'evenodd',
2822 2560 );
2823 -
2824 2561 if ( in_array( $key, $not_allowed, true ) ) {
2825 2562 $key .= 'a';
2826 2563 }
2827 2564 }
2828 -
2829 2565 return $key;
2830 2566 }
2831 2567
2832 2568 /**
@@ -2845,9 +2581,9 @@
2845 2581 if ( ! $record ) {
2846 2582 return false;
2847 2583 }
2848 2584
2849 - if ( ! $post_values ) {
2585 + if ( empty( $post_values ) ) {
2850 2586 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
2851 2587 }
2852 2588
2853 2589 $values = array(
@@ -2855,9 +2591,9 @@
2855 2591 'fields' => array(),
2856 2592 );
2857 2593
2858 2594 foreach ( array( 'name', 'description' ) as $var ) {
2859 - $default_val = $record->{$var} ?? '';
2595 + $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
2860 2596 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
2861 2597 unset( $var, $default_val );
2862 2598 }
2863 2599
@@ -2875,67 +2611,46 @@
2875 2611
2876 2612 return $values;
2877 2613 }
2878 2614
2879 - /**
2880 - * @param array|string $fields
2881 - * @param object $record
2882 - * @param array $values
2883 - * @param array $args
2884 - *
2885 - * @return void
2886 - */
2887 2615 private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
2888 - if ( ! $fields ) {
2889 - return;
2890 - }
2891 -
2892 - foreach ( (array) $fields as $field ) {
2893 - if ( ! self::is_admin_page() ) {
2894 - // Don't prep default values on the form settings page.
2895 - $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 );
2896 2624 }
2897 -
2898 - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id;
2899 - self::fill_field_defaults( $field, $record, $values, $args );
2900 2625 }
2901 2626 }
2902 2627
2903 - /**
2904 - * @param object $field
2905 - * @param object $record
2906 - * @param array $values
2907 - * @param array $args
2908 - *
2909 - * @return void
2910 - */
2911 2628 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
2912 2629 $post_values = $args['post_values'];
2913 2630
2914 2631 if ( $args['default'] ) {
2915 2632 $meta_value = $field->default_value;
2916 - } 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'] ) {
2917 2634 if ( ! isset( $field->field_options['custom_field'] ) ) {
2918 2635 $field->field_options['custom_field'] = '';
2919 2636 }
2920 -
2921 - $meta_value = FrmProEntryMetaHelper::get_post_value(
2922 - $record->post_id,
2923 - $field->field_options['post_field'],
2924 - $field->field_options['custom_field'],
2925 - array(
2926 - 'truncate' => false,
2927 - 'type' => $field->type,
2928 - 'form_id' => $field->form_id,
2929 - 'field' => $field,
2930 - )
2931 - );
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 + );
2932 2648 } else {
2933 2649 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
2934 2650 }//end if
2935 2651
2936 - $field_type = $post_values['field_options'][ 'type_' . $field->id ] ?? $field->type;
2937 -
2652 + $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
2938 2653 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
2939 2654 $new_value = $post_values['item_meta'][ $field->id ];
2940 2655 self::unserialize_or_decode( $new_value );
2941 2656 } else {
@@ -2950,9 +2665,9 @@
2950 2665 $args['field_type'] = $field_type;
2951 2666
2952 2667 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
2953 2668
2954 - if ( empty( $field_array['unique'] ) ) {
2669 + if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
2955 2670 $field_array['unique_msg'] = '';
2956 2671 }
2957 2672
2958 2673 $field_array = array_merge( (array) $field->field_options, $field_array );
@@ -3019,21 +2734,15 @@
3019 2734 }
3020 2735
3021 2736 /**
3022 2737 * Set to POST value or default
3023 - *
3024 - * @param array $post_values
3025 - * @param array $values
3026 - *
3027 - * @return void
3028 2738 */
3029 2739 private static function fill_form_defaults( $post_values, array &$values ) {
3030 2740 $form_defaults = FrmFormsHelper::get_default_opts();
3031 2741
3032 2742 foreach ( $form_defaults as $opt => $default ) {
3033 - // phpcs:ignore Universal.Operators.StrictComparisons
3034 2743 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
3035 - $values[ $opt ] = $post_values['options'][ $opt ] ?? $default;
2744 + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default;
3036 2745 }
3037 2746
3038 2747 unset( $opt, $default );
3039 2748 }
@@ -3043,9 +2752,9 @@
3043 2752 }
3044 2753
3045 2754 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
3046 2755 if ( ! isset( $values[ $h . '_html' ] ) ) {
3047 - $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 ) );
3048 2757 }
3049 2758 unset( $h );
3050 2759 }
3051 2760 }
@@ -3057,57 +2766,46 @@
3057 2766 *
3058 2767 * @return bool|int
3059 2768 */
3060 2769 public static function custom_style_value( $post_values ) {
3061 - if ( $post_values && isset( $post_values['options']['custom_style'] ) ) {
3062 - 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' );
3063 2775 }
3064 2776
3065 - $frm_settings = self::get_settings();
3066 - return $frm_settings->load_style !== 'none';
2777 + return $custom_style;
3067 2778 }
3068 2779
3069 2780 /**
3070 - * Truncate a string.
3071 - *
3072 - * Note: By default, this function will allow for a few additional characters more than $length.
3073 - * If a string has no spaces, it allows up to 50 additional characters. To force a true length limit,
3074 - * use $force_length_limit = true.
3075 - *
3076 2781 * @param mixed $original_string
3077 2782 * @param int|string $length
3078 2783 * @param int $minword
3079 2784 * @param string $continue
3080 - * @param bool $force_length_limit Force the final string to never exceed the length limit.
3081 - *
3082 2785 * @return string
3083 2786 */
3084 - 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 = '...' ) {
3085 2788 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
3086 2789 return '';
3087 2790 }
3088 2791
3089 - $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 ) );
3090 2795
3091 - if ( $length === 0 ) {
2796 + if ( $length == 0 ) {
3092 2797 return '';
3093 2798 }
3094 2799
3095 - $str = wp_strip_all_tags( (string) $original_string );
3096 - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3097 -
3098 2800 if ( $length <= 10 ) {
3099 2801 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
3100 -
3101 - if ( $force_length_limit ) {
3102 - return $sub;
3103 - }
3104 -
3105 2802 return $sub . ( $length < $original_len ? $continue : '' );
3106 2803 }
3107 2804
3108 - $sub = '';
3109 - $len = 0;
2805 + $sub = '';
2806 + $len = 0;
2807 +
3110 2808 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
3111 2809
3112 2810 if ( ! is_array( $words ) ) {
3113 2811 return $original_string;
@@ -3113,11 +2811,10 @@
3113 2811 return $original_string;
3114 2812 }
3115 2813
3116 2814 foreach ( $words as $word ) {
3117 - $part = ( $sub !== '' ? ' ' : '' ) . $word;
2815 + $part = ( $sub != '' ? ' ' : '' ) . $word;
3118 2816 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
3119 -
3120 2817 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
3121 2818 break;
3122 2819 }
3123 2820
@@ -3130,21 +2827,10 @@
3130 2827
3131 2828 unset( $total_len, $word );
3132 2829 }
3133 2830
3134 - $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 );
3135 2832
3136 - if ( $force_length_limit ) {
3137 - // Ensure the final string doesn't exceed the length limit.
3138 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3139 -
3140 - if ( $final_len > $length ) {
3141 - return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) );
3142 - }
3143 -
3144 - return $sub;
3145 - }
3146 -
3147 2833 return $sub . ( $len < $original_len ? $continue : '' );
3148 2834 }
3149 2835
3150 2836 /**
@@ -3151,51 +2837,30 @@
3151 2837 * If the string is still too long because there may not have been any spaces, force truncate.
3152 2838 *
3153 2839 * @since 6.5.4
3154 2840 *
3155 - * @param string $sub Current substring.
3156 - * @param int $length The length limit.
3157 - * @param bool $force_length_limit Force the string to not exceed the length limit.
3158 - *
2841 + * @param string $sub Current substring.
2842 + * @param int $length The length limit.
3159 2843 * @return string
3160 2844 */
3161 - private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit = false ) {
3162 - if ( ! $force_length_limit ) {
3163 - if ( strlen( $sub ) < $length + 50 ) {
3164 - // If the string isn't way over the limit, leave it.
3165 - return $sub;
3166 - }
3167 -
3168 - $first_space = strpos( $sub, ' ', $length );
3169 -
3170 - if ( false !== $first_space ) {
3171 - // Ignore anything with spaces.
3172 - return $sub;
3173 - }
3174 -
3175 - 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;
3176 2849 }
3177 2850
3178 - // When force_length_limit is true, ensure the string doesn't exceed the length.
3179 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3180 -
3181 - if ( $final_len > $length ) {
3182 - 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;
3183 2855 }
3184 2856
3185 - return $sub;
2857 + return substr( $sub, 0, $length + 10 );
3186 2858 }
3187 2859
3188 - /**
3189 - * @param array $function_names
3190 - * @param array $args
3191 - *
3192 - * @return mixed
3193 - */
3194 2860 public static function mb_function( $function_names, $args ) {
3195 2861 $mb_function_name = $function_names[0];
3196 2862 $function_name = $function_names[1];
3197 -
3198 2863 if ( function_exists( $mb_function_name ) ) {
3199 2864 $function_name = $mb_function_name;
3200 2865 }
3201 2866
@@ -3201,21 +2866,14 @@
3201 2866
3202 2867 return call_user_func_array( $function_name, $args );
3203 2868 }
3204 2869
3205 - /**
3206 - * @param string $date
3207 - * @param string $date_format
3208 - * @param string $time_format
3209 - *
3210 - * @return string
3211 - */
3212 2870 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
3213 - if ( ! $date ) {
2871 + if ( empty( $date ) ) {
3214 2872 return $date;
3215 2873 }
3216 2874
3217 - if ( ! $date_format ) {
2875 + if ( empty( $date_format ) ) {
3218 2876 $date_format = get_option( 'date_format' );
3219 2877 }
3220 2878
3221 2879 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
@@ -3223,10 +2881,10 @@
3223 2881 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
3224 2882 }
3225 2883
3226 2884 $formatted = self::get_localized_date( $date_format, $date );
3227 - $do_time = gmdate( 'H:i:s', strtotime( $date ) ) !== '00:00:00';
3228 2885
2886 + $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
3229 2887 if ( $do_time ) {
3230 2888 $formatted .= self::add_time_to_date( $time_format, $date );
3231 2889 }
3232 2890
@@ -3235,35 +2893,30 @@
3235 2893
3236 2894 /**
3237 2895 * @param string $time_format
3238 2896 * @param string $date
3239 - *
3240 2897 * @return string
3241 2898 */
3242 2899 private static function add_time_to_date( $time_format, $date ) {
3243 - if ( ! $time_format ) {
2900 + if ( empty( $time_format ) ) {
3244 2901 $time_format = get_option( 'time_format' );
3245 2902 }
3246 2903
3247 2904 $trimmed_format = trim( $time_format );
3248 -
3249 - if ( $time_format && $trimmed_format ) {
3250 - 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 );
3251 2908 }
3252 2909
3253 - return '';
2910 + return $time;
3254 2911 }
3255 2912
3256 2913 /**
3257 2914 * @since 2.0.8
3258 - *
3259 - * @param string $date_format
3260 - * @param string $date
3261 - *
3262 - * @return string
3263 2915 */
3264 2916 public static function get_localized_date( $date_format, $date ) {
3265 2917 $date = get_date_from_gmt( $date );
2918 +
3266 2919 return date_i18n( $date_format, strtotime( $date ) );
3267 2920 }
3268 2921
3269 2922 /**
@@ -3268,16 +2921,19 @@
3268 2921
3269 2922 /**
3270 2923 * Gets the time ago in words.
3271 2924 *
3272 - * @param int $from In seconds.
3273 - * @param int|string $to In seconds.
3274 - * @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.
3275 2927 *
3276 - * @return string Time ago.
2928 + * @return string $time_ago
3277 2929 */
3278 2930 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
3279 - $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 + }
3280 2936 $ago = new DateTime( '@' . $from );
3281 2937
3282 2938 // Get the time difference
3283 2939 $diff_object = $now->diff( $ago );
@@ -3291,9 +2947,8 @@
3291 2947
3292 2948 if ( ! is_numeric( $levels ) ) {
3293 2949 // Show time in specified unit.
3294 2950 $levels = self::get_unit( $levels );
3295 -
3296 2951 if ( isset( $time_strings[ $levels ] ) ) {
3297 2952 $diff = array(
3298 2953 $levels => self::time_format( $levels, $diff ),
3299 2954 );
@@ -3300,14 +2955,13 @@
3300 2955 $time_strings = array(
3301 2956 $levels => $time_strings[ $levels ],
3302 2957 );
3303 2958 }
3304 -
3305 2959 $levels = 1;
3306 2960 }
3307 2961
3308 2962 foreach ( $time_strings as $k => $v ) {
3309 - if ( ! empty( $diff[ $k ] ) ) {
2963 + if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
3310 2964 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
3311 2965 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
3312 2966 // Account for 0.
3313 2967 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
@@ -3315,21 +2969,17 @@
3315 2969 unset( $time_strings[ $k ] );
3316 2970 }
3317 2971 }
3318 2972
3319 - $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
3320 - $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 );
3321 2976
3322 - return implode( ' ', $time_strings );
2977 + return $time_ago_string;
3323 2978 }
3324 2979
3325 2980 /**
3326 2981 * @since 4.05.01
3327 - *
3328 - * @param string $unit
3329 - * @param array $diff
3330 - *
3331 - * @return int
3332 2982 */
3333 2983 private static function time_format( $unit, $diff ) {
3334 2984 $return = array(
3335 2985 'y' => 'y',
@@ -3334,14 +2984,14 @@
3334 2984 $return = array(
3335 2985 'y' => 'y',
3336 2986 'd' => 'days',
3337 2987 );
3338 -
3339 2988 if ( isset( $return[ $unit ] ) ) {
3340 2989 return $diff[ $return[ $unit ] ];
3341 2990 }
3342 2991
3343 2992 $total = $diff['days'] * self::convert_time( 'd', $unit );
2993 +
3344 2994 $times = array( 'h', 'i', 's' );
3345 2995
3346 2996 foreach ( $times as $time ) {
3347 2997 if ( ! isset( $diff[ $time ] ) ) {
@@ -3355,13 +3005,8 @@
3355 3005 }
3356 3006
3357 3007 /**
3358 3008 * @since 4.05.01
3359 - *
3360 - * @param string $from
3361 - * @param string $to
3362 - *
3363 - * @return int
3364 3009 */
3365 3010 private static function convert_time( $from, $to ) {
3366 3011 $convert = array(
3367 3012 's' => 1,
@@ -3377,26 +3022,20 @@
3377 3022 }
3378 3023
3379 3024 /**
3380 3025 * @since 4.05.01
3381 - *
3382 - * @param string $unit
3383 - *
3384 - * @return int|string
3385 3026 */
3386 3027 private static function get_unit( $unit ) {
3387 3028 $units = self::get_time_strings();
3388 -
3389 3029 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
3390 3030 return $unit;
3391 3031 }
3392 3032
3393 3033 foreach ( $units as $u => $strings ) {
3394 - if ( in_array( $unit, $strings, true ) ) {
3034 + if ( in_array( $unit, $strings ) ) {
3395 3035 return $u;
3396 3036 }
3397 3037 }
3398 -
3399 3038 return 1;
3400 3039 }
3401 3040
3402 3041 /**
@@ -3403,9 +3042,8 @@
3403 3042 * Get the translatable time strings. The untranslated version is a failsafe
3404 3043 * in case languages are changing for the unit set in the shortcode.
3405 3044 *
3406 3045 * @since 2.0.20
3407 - *
3408 3046 * @return array
3409 3047 */
3410 3048 private static function get_time_strings() {
3411 3049 return array(
@@ -3452,13 +3090,12 @@
3452 3090 /**
3453 3091 * @param int $r_count
3454 3092 * @param int $current_p
3455 3093 * @param int $p_size
3456 - *
3457 3094 * @return int
3458 3095 */
3459 3096 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
3460 - 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 );
3461 3098 }
3462 3099
3463 3100 /**
3464 3101 * @param int $r_count
@@ -3463,13 +3100,11 @@
3463 3100 /**
3464 3101 * @param int $r_count
3465 3102 * @param int $current_p
3466 3103 * @param int $p_size
3467 - *
3468 3104 * @return int
3469 3105 */
3470 3106 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
3471 - // phpcs:ignore Universal.Operators.StrictComparisons
3472 3107 if ( $current_p == 1 ) {
3473 3108 return 1;
3474 3109 }
3475 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
@@ -3475,22 +3110,17 @@
3475 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
3476 3111 }
3477 3112
3478 3113 /**
3479 - * @param array $json_vars
3480 - *
3481 3114 * @return array
3482 3115 */
3483 3116 public static function json_to_array( $json_vars ) {
3484 3117 $vars = array();
3485 -
3486 3118 foreach ( $json_vars as $jv ) {
3487 3119 $jv_name = explode( '[', $jv['name'] );
3488 3120 $last = count( $jv_name ) - 1;
3489 -
3490 3121 foreach ( $jv_name as $p => $n ) {
3491 3122 $name = trim( $n, ']' );
3492 -
3493 3123 if ( ! isset( $l1 ) ) {
3494 3124 $l1 = $name;
3495 3125 }
3496 3126
@@ -3501,9 +3131,9 @@
3501 3131 if ( ! isset( $l3 ) ) {
3502 3132 $l3 = $name;
3503 3133 }
3504 3134
3505 - $this_val = $p === $last ? $jv['value'] : array();
3135 + $this_val = $p == $last ? $jv['value'] : array();
3506 3136
3507 3137 switch ( $p ) {
3508 3138 case 0:
3509 3139 $l1 = $name;
@@ -3536,15 +3166,10 @@
3536 3166
3537 3167 /**
3538 3168 * @param string $name
3539 3169 * @param string $l1
3540 - * @param mixed $val
3541 - * @param array $vars
3542 - *
3543 - * @return void
3544 3170 */
3545 3171 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
3546 - // phpcs:ignore Universal.Operators.StrictComparisons
3547 3172 if ( $name == '' ) {
3548 3173 $vars[] = $val;
3549 3174 } elseif ( ! isset( $vars[ $l1 ] ) ) {
3550 3175 $vars[ $l1 ] = $val;
@@ -3550,26 +3175,19 @@
3550 3175 $vars[ $l1 ] = $val;
3551 3176 }
3552 3177 }
3553 3178
3554 - /**
3555 - * @param string $name
3556 - * @param string $class
3557 - * @param string $form_name
3558 - *
3559 - * @return void
3560 - */
3561 3179 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
3562 3180 $tooltips = array(
3563 3181 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
3564 - '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' ),
3565 3183 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3566 3184 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3567 - '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' ),
3568 3186 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
3569 3187 /* translators: %1$s: Form name, %2$s: Date */
3570 - '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
3571 - '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' ),
3572 3190 );
3573 3191
3574 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3575 3193 return;
@@ -3574,9 +3192,9 @@
3574 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3575 3193 return;
3576 3194 }
3577 3195
3578 - if ( 'open' === $class ) {
3196 + if ( 'open' == $class ) {
3579 3197 echo ' frm_help"';
3580 3198 } else {
3581 3199 echo ' class="frm_help"';
3582 3200 }
@@ -3582,9 +3200,9 @@
3582 3200 }
3583 3201
3584 3202 echo ' title="' . esc_attr( $tooltips[ $name ] );
3585 3203
3586 - if ( 'open' !== $class ) {
3204 + if ( 'open' != $class ) {
3587 3205 echo '"';
3588 3206 }
3589 3207 }
3590 3208
@@ -3589,28 +3207,20 @@
3589 3207 }
3590 3208
3591 3209 /**
3592 3210 * Add the current_page class to that page in the form nav
3593 - *
3594 - * @param int|string $page
3595 - * @param int|string $current_page
3596 - * @param array $action
3597 - *
3598 - * @return void
3599 3211 */
3600 3212 public static function select_current_page( $page, $current_page, $action = array() ) {
3601 - // phpcs:ignore Universal.Operators.StrictComparisons
3602 3213 if ( $current_page != $page ) {
3603 3214 return;
3604 3215 }
3605 3216
3606 3217 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
3607 -
3608 3218 if ( 'lite-reports' === $frm_action ) {
3609 3219 $frm_action = 'reports';
3610 3220 }
3611 3221
3612 - if ( ! $action || ( $frm_action && in_array( $frm_action, $action, true ) ) ) {
3222 + if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
3613 3223 echo ' class="current_page"';
3614 3224 }
3615 3225 }
3616 3226
@@ -3640,19 +3250,14 @@
3640 3250
3641 3251 // Add extra slashes for \r\n since WP strips them.
3642 3252 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
3643 3253
3644 - // Allow for &quot
3645 - return str_replace( '&quot;', '\\"', $post_content );
3254 + // allow for &quot
3255 + $post_content = str_replace( '&quot;', '\\"', $post_content );
3256 +
3257 + return $post_content;
3646 3258 }
3647 3259
3648 - /**
3649 - * @param array|string $val
3650 - * @param int|string $key
3651 - * @param array $post_content
3652 - *
3653 - * @return void
3654 - */
3655 3260 private static function prepare_action_slashes( $val, $key, &$post_content ) {
3656 3261 if ( ! isset( $post_content[ $key ] ) || is_numeric( $val ) ) {
3657 3262 return;
3658 3263 }
@@ -3661,17 +3266,15 @@
3661 3266 foreach ( $val as $k1 => $v1 ) {
3662 3267 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
3663 3268 unset( $k1, $v1 );
3664 3269 }
3270 + } else {
3271 + // Strip all slashes so everything is the same, no matter where the value is coming from
3272 + $val = stripslashes( $val );
3665 3273
3666 - return;
3274 + // Add backslashes before double quotes and forward slashes only
3275 + $post_content[ $key ] = addcslashes( $val, '"\\/' );
3667 3276 }
3668 -
3669 - // Strip all slashes so everything is the same, no matter where the value is coming from
3670 - $val = stripslashes( $val );
3671 -
3672 - // Add backslashes before double quotes and forward slashes only
3673 - $post_content[ $key ] = addcslashes( $val, '"\\/' );
3674 3277 }
3675 3278
3676 3279 /**
3677 3280 * Check for either json or serialized data. This is temporary while transitioning
@@ -3679,9 +3282,8 @@
3679 3282 *
3680 3283 * @since 4.02.03
3681 3284 *
3682 3285 * @param array|string $value
3683 - *
3684 3286 * @return void
3685 3287 */
3686 3288 public static function unserialize_or_decode( &$value ) {
3687 3289 if ( is_array( $value ) ) {
@@ -3687,9 +3289,13 @@
3687 3289 if ( is_array( $value ) ) {
3688 3290 return;
3689 3291 }
3690 3292
3691 - $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 + }
3692 3298 }
3693 3299
3694 3300 /**
3695 3301 * Safely unserialize an array if necessary.
@@ -3697,9 +3303,8 @@
3697 3303 *
3698 3304 * @since 6.2
3699 3305 *
3700 3306 * @param mixed $value
3701 - *
3702 3307 * @return mixed
3703 3308 */
3704 3309 public static function maybe_unserialize_array( $value ) {
3705 3310 if ( ! is_string( $value ) ) {
@@ -3706,15 +3311,18 @@
3706 3311 return $value;
3707 3312 }
3708 3313
3709 3314 // Since we only expect an array, skip anything that doesn't start with a:.
3710 - if ( ! is_serialized( $value ) || ! str_starts_with( $value, 'a:' ) ) {
3315 + if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
3711 3316 return $value;
3712 3317 }
3713 3318
3714 3319 $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
3320 + if ( is_array( $parsed ) ) {
3321 + $value = $parsed;
3322 + }
3715 3323
3716 - return is_array( $parsed ) ? $parsed : $value;
3324 + return $value;
3717 3325 }
3718 3326
3719 3327 /**
3720 3328 * Decode a JSON string.
@@ -3719,12 +3327,11 @@
3719 3327 /**
3720 3328 * Decode a JSON string.
3721 3329 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
3722 3330 *
3723 - * @param array|string|null $string
3724 - * @param bool $single_to_array
3725 - *
3726 - * @return array|string|null
3331 + * @param mixed $string
3332 + * @param bool $single_to_array
3333 + * @return mixed
3727 3334 */
3728 3335 public static function maybe_json_decode( $string, $single_to_array = true ) {
3729 3336 if ( is_array( $string ) || is_null( $string ) ) {
3730 3337 return $string;
@@ -3729,19 +3336,20 @@
3729 3336 if ( is_array( $string ) || is_null( $string ) ) {
3730 3337 return $string;
3731 3338 }
3732 3339
3733 - $new_string = json_decode( $string, true );
3734 - $single_value = false;
3735 -
3736 - if ( ! $single_to_array ) {
3737 - $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 + }
3738 3350 }
3739 3351
3740 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3741 - return $new_string;
3742 - }
3743 -
3744 3352 return $string;
3745 3353 }
3746 3354
3747 3355 /**
@@ -3747,9 +3355,8 @@
3747 3355 /**
3748 3356 * @since 6.2.3
3749 3357 *
3750 3358 * @param string $value
3751 - *
3752 3359 * @return string
3753 3360 */
3754 3361 public static function maybe_utf8_encode( $value ) {
3755 3362 $from_format = 'ISO-8859-1';
@@ -3758,15 +3365,13 @@
3758 3365 if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
3759 3366 if ( mb_check_encoding( $value, $from_format ) ) {
3760 3367 return mb_convert_encoding( $value, $to_format, $from_format );
3761 3368 }
3762 -
3763 3369 return $value;
3764 3370 }
3765 3371
3766 3372 if ( function_exists( 'iconv' ) ) {
3767 3373 $converted = iconv( $from_format, $to_format, $value );
3768 -
3769 3374 // Value is false if $value is not ISO-8859-1.
3770 3375 if ( false !== $converted ) {
3771 3376 return $converted;
3772 3377 }
@@ -3778,12 +3383,8 @@
3778 3383 /**
3779 3384 * Reformat the json serialized array in name => value array.
3780 3385 *
3781 3386 * @since 4.02.03
3782 - *
3783 - * @param array $form
3784 - *
3785 - * @return void
3786 3387 */
3787 3388 public static function format_form_data( &$form ) {
3788 3389 $formatted = array();
3789 3390
@@ -3790,21 +3391,18 @@
3790 3391 foreach ( $form as $input ) {
3791 3392 if ( ! isset( $input['name'] ) ) {
3792 3393 continue;
3793 3394 }
3794 -
3795 3395 $key = $input['name'];
3796 -
3797 - 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 {
3798 3403 $formatted[ $key ] = $input['value'];
3799 - continue;
3800 3404 }
3801 -
3802 - if ( is_array( $formatted[ $key ] ) ) {
3803 - $formatted[ $key ][] = $input['value'];
3804 - } else {
3805 - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3806 - }
3807 3405 }
3808 3406
3809 3407 parse_str( http_build_query( $formatted ), $form );
3810 3408 }
@@ -3812,13 +3410,15 @@
3812 3410 /**
3813 3411 * @since 4.02.03
3814 3412 *
3815 3413 * @param array|string $value
3816 - *
3817 3414 * @return string
3818 3415 */
3819 3416 public static function maybe_json_encode( $value ) {
3820 - return is_array( $value ) ? wp_json_encode( $value ) : $value;
3417 + if ( is_array( $value ) ) {
3418 + $value = wp_json_encode( $value );
3419 + }
3420 + return $value;
3821 3421 }
3822 3422
3823 3423 /**
3824 3424 * Echo The javascript to open and highlight the Formidable menu
@@ -3825,19 +3425,18 @@
3825 3425 *
3826 3426 * @since 1.07.10
3827 3427 *
3828 3428 * @param string $post_type The name of the post type that may need to be highlighted.
3829 - *
3830 3429 * @return void
3831 3430 */
3832 3431 public static function maybe_highlight_menu( $post_type ) {
3833 3432 global $post;
3834 3433
3835 - if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] !== $post_type ) {
3434 + if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
3836 3435 return;
3837 3436 }
3838 3437
3839 - if ( is_object( $post ) && $post->post_type !== $post_type ) {
3438 + if ( is_object( $post ) && $post->post_type != $post_type ) {
3840 3439 return;
3841 3440 }
3842 3441
3843 3442 self::load_admin_wide_js();
@@ -3849,13 +3448,13 @@
3849 3448 *
3850 3449 * @since 2.0
3851 3450 *
3852 3451 * @param bool $load
3853 - *
3854 3452 * @return void
3855 3453 */
3856 3454 public static function load_admin_wide_js( $load = true ) {
3857 - 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 );
3858 3457
3859 3458 $global_strings = array(
3860 3459 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
3861 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
@@ -3861,9 +3460,9 @@
3861 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
3862 3461 'url' => self::plugin_url(),
3863 3462 'app_url' => 'https://formidableforms.com/',
3864 3463 'applicationsUrl' => admin_url( 'admin.php?page=formidable-applications' ),
3865 - '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' ),
3866 3465 'loading' => __( 'Loading&hellip;', 'formidable' ),
3867 3466 'nonce' => wp_create_nonce( 'frm_ajax' ),
3868 3467 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
3869 3468 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(),
@@ -3876,9 +3475,8 @@
3876 3475 }
3877 3476
3878 3477 /**
3879 3478 * @since 2.0.9
3880 - *
3881 3479 * @return void
3882 3480 */
3883 3481 public static function load_font_style() {
3884 3482 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
@@ -3885,9 +3483,8 @@
3885 3483 }
3886 3484
3887 3485 /**
3888 3486 * @param string $location
3889 - *
3890 3487 * @return void
3891 3488 */
3892 3489 public static function localize_script( $location ) {
3893 3490 global $wp_scripts, $wp_version;
@@ -3910,9 +3507,8 @@
3910 3507 'include_resend_email' => false,
3911 3508 );
3912 3509
3913 3510 $data = $wp_scripts->get_data( 'formidable', 'data' );
3914 -
3915 3511 if ( ! $data ) {
3916 3512 wp_localize_script( 'formidable', 'frm_js', $script_strings );
3917 3513 }
3918 3514
@@ -3919,9 +3515,9 @@
3919 3515 if ( $location === 'admin' ) {
3920 3516 $admin_script_strings = array(
3921 3517 'desc' => __( '(Click to add description)', 'formidable' ),
3922 3518 'blank' => __( '(Blank)', 'formidable' ),
3923 - 'no_label' => self::get_no_label_text(),
3519 + 'no_label' => __( '(no label)', 'formidable' ),
3924 3520 'ok' => __( 'OK', 'formidable' ),
3925 3521 'cancel' => __( 'Cancel', 'formidable' ),
3926 3522 'default_label' => __( 'Default', 'formidable' ),
3927 3523 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3929,9 +3525,9 @@
3929 3525 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3930 3526 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3931 3527 'confirm' => __( 'Are you sure?', 'formidable' ),
3932 3528 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3933 - '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' ),
3934 3530 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3935 3531 'default_unique' => FrmFieldsHelper::default_unique_msg(),
3936 3532 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3937 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
@@ -3937,9 +3533,9 @@
3937 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
3938 3534 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3939 3535 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3940 3536 'new_option' => __( 'New Option', 'formidable' ),
3941 - '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' ),
3942 3538 'enter_password' => __( 'Enter Password', 'formidable' ),
3943 3539 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3944 3540 'import_complete' => __( 'Import Complete', 'formidable' ),
3945 3541 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
@@ -3953,15 +3549,13 @@
3953 3549 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
3954 3550 /* translators: %d is the number of allowed actions per form */
3955 3551 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ),
3956 3552 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ),
3957 - 'only_one_payment_action' => __( 'This form already has a payment action, and is currently limited to a single payment action.', 'formidable' ),
3958 - '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
3959 3553 'unsafe_params' => FrmFormsHelper::reserved_words(),
3960 3554 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
3961 - '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' ), '****' ),
3962 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. */
3963 - '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' ), '****' ),
3964 3558 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3965 3559 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3966 3560 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3967 3561 'install' => __( 'Install', 'formidable' ),
@@ -3982,14 +3576,11 @@
3982 3576 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
3983 3577 'noTitleText' => FrmFormsHelper::get_no_title_text(),
3984 3578
3985 3579 // In older versions this event listener causes the section to immediately close again
3986 - // 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+.
3987 3581 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ),
3988 3582 );
3989 -
3990 - self::add_form_builder_modal_data( $admin_script_strings );
3991 -
3992 3583 /**
3993 3584 * @param array $admin_script_strings
3994 3585 */
3995 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
@@ -3994,9 +3585,8 @@
3994 3585 */
3995 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3996 3587
3997 3588 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
3998 -
3999 3589 if ( ! $data ) {
4000 3590 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
4001 3591 }
4002 3592 }//end if
@@ -4002,91 +3592,8 @@
4002 3592 }//end if
4003 3593 }
4004 3594
4005 3595 /**
4006 - * @param array $admin_script_strings
4007 - *
4008 - * @return void
4009 - */
4010 - private static function add_form_builder_modal_data( &$admin_script_strings ) {
4011 - if ( ! self::is_form_builder_page() || self::pro_is_installed() ) {
4012 - return;
4013 - }
4014 -
4015 - $stripe_connected = FrmStrpLiteConnectHelper::at_least_one_mode_is_setup();
4016 - $square_connected = FrmSquareLiteConnectHelper::at_least_one_mode_is_setup();
4017 - $paypal_connected = FrmPayPalLiteConnectHelper::at_least_one_mode_is_setup();
4018 - $gateway_connected = $stripe_connected || $square_connected || $paypal_connected;
4019 - $payments_settings_url = FrmStrpLiteAppController::get_payments_settings_url();
4020 -
4021 - if ( ! $gateway_connected ) {
4022 - // This modal shows when user clicks on one of the pricing fields and no payment gateways configured.
4023 - $admin_script_strings['paymentsSettingsModal'] = array(
4024 - 'title' => __( 'Setup a Payment Gateway first', 'formidable' ),
4025 - 'msg' => __( 'To use the payment fields, please install and configure a payment gateway in your account settings.', 'formidable' ),
4026 - 'closeText' => __( 'Close', 'formidable' ),
4027 - 'actionUrl' => $payments_settings_url,
4028 - 'actionText' => __( 'Go to Payment Settings', 'formidable' ),
4029 - 'noCenter' => true,
4030 - );
4031 - }
4032 -
4033 - // This modal shows on load once after upgrading the plugin.
4034 - $show_pricing_fields_modal = get_option( 'frm_show_pricing_fields_modal' );
4035 -
4036 - if ( ! $show_pricing_fields_modal ) {
4037 - return;
4038 - }
4039 -
4040 - $admin_script_strings['pricingFieldsModal'] = array(
4041 - 'title' => esc_html__( 'Start Accepting Payments Today!', 'formidable' ),
4042 - 'img' => esc_url( self::plugin_url() . '/images/upsell/pricing-fields.png' ),
4043 - 'noCenter' => true,
4044 - );
4045 -
4046 - if ( $gateway_connected ) {
4047 - $gateway_texts = array();
4048 -
4049 - if ( $stripe_connected ) {
4050 - $gateway_texts['stripe'] = esc_html__( 'Stripe', 'formidable' );
4051 - }
4052 -
4053 - if ( $square_connected ) {
4054 - $gateway_texts['square'] = esc_html__( 'Square', 'formidable' );
4055 - }
4056 -
4057 - if ( $paypal_connected ) {
4058 - $gateway_texts['paypal'] = esc_html__( 'PayPal', 'formidable' );
4059 - }
4060 -
4061 - $admin_script_strings['pricingFieldsModal']['msg'] = sprintf(
4062 - // translators: %s: Stripe, Square, or PayPal.
4063 - esc_html__( 'You already have %s connected, so these have already been unlocked.', 'formidable' ),
4064 - esc_html( implode( ' ' . esc_html__( 'and', 'formidable' ) . ' ', $gateway_texts ) )
4065 - );
4066 - } else {
4067 - $admin_script_strings['pricingFieldsModal']['closeText'] = __( 'I\'ll do it later!', 'formidable' );
4068 - $admin_script_strings['pricingFieldsModal']['actionText'] = __( 'Setup Payments Now', 'formidable' );
4069 - $admin_script_strings['pricingFieldsModal']['actionUrl'] = $payments_settings_url;
4070 - // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4071 - $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' );
4072 - }//end if
4073 -
4074 - delete_option( 'frm_show_pricing_fields_modal' );
4075 - }
4076 -
4077 - /**
4078 - * Get the no label text.
4079 - *
4080 - * @since 6.25.1
4081 - *
4082 - * @return string
4083 - */
4084 - public static function get_no_label_text() {
4085 - return __( '(no label)', 'formidable' );
4086 - }
4087 -
4088 - /**
4089 3596 * @since 6.5
4090 3597 *
4091 3598 * @return string
4092 3599 */
@@ -4128,9 +3635,8 @@
4128 3635 *
4129 3636 * @since 1.07.10
4130 3637 *
4131 3638 * @param float $min_version The version the add-on requires.
4132 - *
4133 3639 * @return void
4134 3640 */
4135 3641 public static function min_version_notice( $min_version ) {
4136 3642 $frm_version = self::plugin_version();
@@ -4140,11 +3646,11 @@
4140 3646 return;
4141 3647 }
4142 3648
4143 3649 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
4144 - 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
4145 - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
4146 - '</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>';
4147 3653 }
4148 3654
4149 3655 /**
4150 3656 * If Pro is far outdated, show a message.
@@ -4150,10 +3656,8 @@
4150 3656 * If Pro is far outdated, show a message.
4151 3657 *
4152 3658 * @since 4.0.01
4153 3659 *
4154 - * @param string $min_version
4155 - *
4156 3660 * @return void
4157 3661 */
4158 3662 public static function min_pro_version_notice( $min_version ) {
4159 3663 if ( ! self::is_formidable_admin() ) {
@@ -4163,14 +3667,25 @@
4163 3667
4164 3668 self::php_version_notice();
4165 3669
4166 3670 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
4167 -
4168 3671 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
4169 3672 return;
4170 3673 }
4171 3674
4172 - 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
4173 3688 }
4174 3689
4175 3690 /**
4176 3691 * If Pro is installed, check the version number.
@@ -4177,9 +3692,8 @@
4177 3692 *
4178 3693 * @since 4.0.01
4179 3694 *
4180 3695 * @param string $min_version
4181 - *
4182 3696 * @return bool
4183 3697 */
4184 3698 public static function meets_min_pro_version( $min_version ) {
4185 3699 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
@@ -4188,19 +3702,16 @@
4188 3702 /**
4189 3703 * Show a message if the PHP version is below the recommendations.
4190 3704 *
4191 3705 * @since 4.0.02
4192 - *
4193 3706 * @return void
4194 3707 */
4195 3708 private static function php_version_notice() {
4196 3709 $message = array();
4197 -
4198 3710 if ( version_compare( phpversion(), '7.0', '<' ) ) {
4199 - $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' );
4200 3712 }
4201 3713
4202 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4203 3714 foreach ( $message as $m ) {
4204 3715 ?>
4205 3716 <div class="frm-banner-alert frm_error_style frm_previous_install">
4206 3717 <?php echo esc_html( $m ); ?>
@@ -4206,14 +3717,12 @@
4206 3717 <?php echo esc_html( $m ); ?>
4207 3718 </div>
4208 3719 <?php
4209 3720 }
4210 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4211 3721 }
4212 3722
4213 3723 /**
4214 3724 * @param string $type
4215 - *
4216 3725 * @return array<string,string>
4217 3726 */
4218 3727 public static function locales( $type = 'date' ) {
4219 3728 $locales = array(
@@ -4307,12 +3816,12 @@
4307 3816 'zu' => __( 'Zulu', 'formidable' ),
4308 3817 );
4309 3818
4310 3819 if ( $type === 'captcha' ) {
4311 - // Remove the languages unavailable for the captcha
3820 + // remove the languages unavailable for the captcha
4312 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' );
4313 3822 } else {
4314 - // Remove the languages unavailable for the datepicker
3823 + // remove the languages unavailable for the datepicker
4315 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' );
4316 3825 }
4317 3826
4318 3827 $locales = array_diff_key( $locales, array_flip( $unset ) );
@@ -4323,13 +3832,14 @@
4323 3832 * @since 5.4.5 Added $args parameter with type.
4324 3833 *
4325 3834 * @param array<string,string> $locales
4326 3835 * @param array $args {
4327 - *
4328 3836 * @type string $type
4329 3837 * }
4330 3838 */
4331 - return apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3839 + $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3840 +
3841 + return $locales;
4332 3842 }
4333 3843
4334 3844 /**
4335 3845 * @return string
@@ -4336,14 +3846,12 @@
4336 3846 */
4337 3847 public static function get_menu_icon_class() {
4338 3848 if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
4339 3849 $settings = FrmProAppHelper::get_settings();
4340 -
4341 3850 if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
4342 3851 return $settings->menu_icon;
4343 3852 }
4344 3853 }
4345 -
4346 3854 return 'frmfont frm_logo_icon';
4347 3855 }
4348 3856
4349 3857 /**
@@ -4361,9 +3869,10 @@
4361 3869 * @type array $input_attrs Attributes of value input.
4362 3870 * }
4363 3871 */
4364 3872 public static function images_dropdown( $args ) {
4365 - $args = self::fill_default_images_dropdown_args( $args );
3873 + $args = self::fill_default_images_dropdown_args( $args );
3874 +
4366 3875 $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
4367 3876 ob_start();
4368 3877 include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
4369 3878 $output = ob_get_clean();
@@ -4384,9 +3893,8 @@
4384 3893 *
4385 3894 * @since 5.0.04
4386 3895 *
4387 3896 * @param array $args The arguments.
4388 - *
4389 3897 * @return array
4390 3898 */
4391 3899 private static function fill_default_images_dropdown_args( $args ) {
4392 3900 $defaults = array(
@@ -4399,8 +3907,14 @@
4399 3907
4400 3908 $new_args['options'] = (array) $new_args['options'];
4401 3909 $new_args['input_attrs'] = (array) $new_args['input_attrs'];
4402 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 +
4403 3917 /**
4404 3918 * Allows modifying the arguments of images_dropdown() method.
4405 3919 *
4406 3920 * @since 5.0.04
@@ -4416,9 +3930,8 @@
4416 3930 *
4417 3931 * @since 5.0.04
4418 3932 *
4419 3933 * @param array $args The arguments.
4420 - *
4421 3934 * @return string
4422 3935 */
4423 3936 private static function get_images_dropdown_input_attrs( $args ) {
4424 3937 $input_attrs = $args['input_attrs'];
@@ -4425,9 +3938,8 @@
4425 3938 $input_attrs['type'] = 'radio';
4426 3939 $input_attrs['name'] = $args['name'];
4427 3940
4428 3941 $input_attrs_str = '';
4429 -
4430 3942 foreach ( $input_attrs as $key => $input_attr ) {
4431 3943 $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
4432 3944 }
4433 3945
@@ -4443,13 +3955,8 @@
4443 3955 }
4444 3956
4445 3957 /**
4446 3958 * @since 6.7.1
4447 - *
4448 - * @param array $option Option data.
4449 - * @param array $args The arguments of images_dropdown() method.
4450 - *
4451 - * @return array
4452 3959 */
4453 3960 public static function get_images_dropdown_atts( $option, $args ) {
4454 3961 $image = self::get_images_dropdown_option_image( $option, $args );
4455 3962 $classes = self::get_images_dropdown_option_classes( $option, $args );
@@ -4463,9 +3970,8 @@
4463 3970 * @since 5.0.04
4464 3971 *
4465 3972 * @param array $option Option data.
4466 3973 * @param array $args The arguments of images_dropdown() method.
4467 - *
4468 3974 * @return string
4469 3975 */
4470 3976 private static function get_images_dropdown_option_image( $option, $args ) {
4471 3977 $image = self::icon_by_class(
@@ -4494,9 +4000,8 @@
4494 4000 * @since 5.0.04
4495 4001 *
4496 4002 * @param array $option Option data.
4497 4003 * @param array $args The arguments of images_dropdown() method.
4498 - *
4499 4004 * @return string
4500 4005 */
4501 4006 private static function get_images_dropdown_option_classes( $option, $args ) {
4502 4007 $classes = '';
@@ -4524,19 +4029,17 @@
4524 4029 * @since 5.0.04
4525 4030 *
4526 4031 * @param array $option Option data.
4527 4032 * @param array $args The arguments of images_dropdown() method.
4528 - *
4529 4033 * @return string
4530 4034 */
4531 4035 private static function get_images_dropdown_option_html_attrs( $option, $args ) {
4532 4036 $html_attrs = '';
4533 -
4534 4037 if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
4535 4038 $html_attrs_arr = array();
4536 4039
4537 4040 foreach ( $option['custom_attrs'] as $key => $value ) {
4538 - if ( in_array( $key, array( 'type', 'class', 'data-value' ), true ) ) {
4041 + if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
4539 4042 continue;
4540 4043 }
4541 4044
4542 4045 $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
@@ -4594,13 +4097,14 @@
4594 4097 * @since 5.0.07
4595 4098 *
4596 4099 * @param array $values
4597 4100 * @param array $keys
4598 - *
4599 4101 * @return array
4600 4102 */
4601 4103 public static function maybe_filter_array( $values, $keys ) {
4602 - if ( self::allow_unfiltered_html() ) {
4104 + $allow_unfiltered_html = self::allow_unfiltered_html();
4105 +
4106 + if ( $allow_unfiltered_html ) {
4603 4107 return $values;
4604 4108 }
4605 4109
4606 4110 foreach ( $keys as $key ) {
@@ -4619,14 +4123,13 @@
4619 4123 * @since 5.0.13
4620 4124 *
4621 4125 * @param string $value
4622 4126 * @param array|string $allowed 'all' for everything included as defaults.
4623 - *
4624 4127 * @return string
4625 4128 */
4626 4129 public static function maybe_kses( $value, $allowed = 'all' ) {
4627 4130 if ( self::should_never_allow_unfiltered_html() ) {
4628 - return self::kses( $value, $allowed );
4131 + $value = self::kses( $value, $allowed );
4629 4132 }
4630 4133 return $value;
4631 4134 }
4632 4135
@@ -4636,18 +4139,17 @@
4636 4139 * @since 6.11.2
4637 4140 *
4638 4141 * @param string $key
4639 4142 * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed.
4640 - *
4641 4143 * @return bool
4642 4144 */
4643 4145 public static function input_key_is_safe( $key, $context = 'display' ) {
4644 4146 if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) {
4645 4147 $safe = true;
4646 - } elseif ( str_starts_with( $key, 'data-' ) ) {
4148 + } elseif ( 0 === strpos( $key, 'data-' ) ) {
4647 4149 // Allow all data attributes.
4648 4150 $safe = true;
4649 - } elseif ( str_starts_with( $key, 'aria-' ) ) {
4151 + } elseif ( 0 === strpos( $key, 'aria-' ) ) {
4650 4152 // Allow all aria attributes.
4651 4153 $safe = true;
4652 4154 } else {
4653 4155 $safe_keys = array(
@@ -4689,9 +4191,16 @@
4689 4191
4690 4192 /**
4691 4193 * @since 5.0.16
4692 4194 *
4693 - * @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
4694 4203 *
4695 4204 * @return array
4696 4205 */
4697 4206 public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
@@ -4699,9 +4208,8 @@
4699 4208 'medium' => $medium,
4700 4209 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
4701 4210 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
4702 4211 'screenshot' => 'landing.png',
4703 - 'learn-more' => self::get_doc_url( 'landing-page-forms', 'form-landing-page-settings', false ),
4704 4212 );
4705 4213 return self::get_upgrade_data_params( 'landing', $params );
4706 4214 }
4707 4215
@@ -4708,9 +4216,8 @@
4708 4216 /**
4709 4217 * @since 5.0.17
4710 4218 *
4711 4219 * @param string $feature
4712 - *
4713 4220 * @return bool
4714 4221 */
4715 4222 public static function show_new_feature( $feature ) {
4716 4223 $link = FrmAddonsController::install_link( $feature );
@@ -4717,21 +4224,16 @@
4717 4224 return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
4718 4225 }
4719 4226
4720 4227 /**
4721 - * Enhances upgrade data parameters with installation link and plan requirement information.
4722 - *
4723 4228 * @since 5.0.17
4724 4229 *
4725 - * @param string $plugin The plugin slug to get installation data for.
4726 - * @param array $params Initial parameters for the upgrade data.
4727 - * @param bool $detailed Whether to include detailed information.
4728 - *
4729 - * @return array Modified parameters with installation data.
4230 + * @param string $plugin
4231 + * @param array $params
4232 + * @return array
4730 4233 */
4731 - public static function get_upgrade_data_params( $plugin, $params, $detailed = false ) {
4234 + public static function get_upgrade_data_params( $plugin, $params ) {
4732 4235 $link = FrmAddonsController::install_link( $plugin );
4733 -
4734 4236 if ( ! $link ) {
4735 4237 return $params;
4736 4238 }
4737 4239
@@ -4737,20 +4239,15 @@
4737 4239
4738 4240 if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
4739 4241 $params['oneclick'] = json_encode( $link );
4740 4242 unset( $params['message'] );
4741 -
4742 4243 if ( ! isset( $params['medium'] ) ) {
4743 4244 $params['medium'] = $plugin;
4744 4245 }
4745 4246 } else {
4746 - $params['requires'] = $params['requires'] ?? FrmFormsHelper::get_plan_required( $link );
4247 + $params['requires'] = FrmFormsHelper::get_plan_required( $link );
4747 4248 }
4748 4249
4749 - if ( $detailed ) {
4750 - $params['plugin-status'] = $link['status'] ?? '';
4751 - }
4752 -
4753 4250 return $params;
4754 4251 }
4755 4252
4756 4253 /**
@@ -4759,9 +4256,8 @@
4759 4256 *
4760 4257 * @since 5.0.17
4761 4258 *
4762 4259 * @param string $text
4763 - *
4764 4260 * @return bool
4765 4261 */
4766 4262 public static function ctype_xdigit( $text ) {
4767 4263 if ( function_exists( 'ctype_xdigit' ) ) {
@@ -4776,14 +4272,12 @@
4776 4272 * @since 5.2.01
4777 4273 */
4778 4274 public static function set_current_screen_and_hook_suffix() {
4779 4275 global $hook_suffix;
4780 -
4781 4276 if ( is_null( $hook_suffix ) ) {
4782 4277 // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
4783 4278 $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
4784 4279 }
4785 -
4786 4280 set_current_screen();
4787 4281 }
4788 4282
4789 4283 /**
@@ -4790,9 +4284,9 @@
4790 4284 * Shows pill text.
4791 4285 *
4792 4286 * @since 5.2.02
4793 4287 *
4794 - * @param string|null $text Text in the pill. Default is NEW.
4288 + * @param string $text Text in the pill. Default is NEW.
4795 4289 */
4796 4290 public static function show_pill_text( $text = null ) {
4797 4291 if ( null === $text ) {
4798 4292 $text = __( 'NEW', 'formidable' );
@@ -4805,9 +4299,8 @@
4805 4299 *
4806 4300 * @since 5.2.07
4807 4301 *
4808 4302 * @param mixed $num Number.
4809 - *
4810 4303 * @return false|int Returns `false` if the passed parameter is not number.
4811 4304 */
4812 4305 public static function count_decimals( $num ) {
4813 4306 if ( ! is_numeric( $num ) ) {
@@ -4815,9 +4308,8 @@
4815 4308 }
4816 4309
4817 4310 $num = (string) $num;
4818 4311 $parts = explode( '.', $num );
4819 -
4820 4312 if ( 1 === count( $parts ) ) {
4821 4313 return 0;
4822 4314 }
4823 4315
@@ -4899,20 +4391,17 @@
4899 4391 * @since 5.5.5
4900 4392 *
4901 4393 * @param string $url
4902 4394 * @param string $expected_extension
4903 - *
4904 4395 * @return bool
4905 4396 */
4906 4397 public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
4907 - $file_is_in_expected_s3_bucket = str_starts_with( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4908 -
4398 + $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4909 4399 if ( ! $file_is_in_expected_s3_bucket ) {
4910 4400 return false;
4911 4401 }
4912 4402
4913 4403 $parsed = parse_url( $url );
4914 -
4915 4404 if ( ! is_array( $parsed ) ) {
4916 4405 // URL is malformed.
4917 4406 return false;
4918 4407 }
@@ -4918,10 +4407,14 @@
4918 4407 }
4919 4408
4920 4409 $path = $parsed['path'];
4921 4410 $ext = pathinfo( $path, PATHINFO_EXTENSION );
4922 - // The URL isn't to an XML file.
4923 - 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;
4924 4417 }
4925 4418
4926 4419 /**
4927 4420 * Display a dismissable warning message and save its dismissal state.
@@ -4929,9 +4422,8 @@
4929 4422 * @since 6.3
4930 4423 *
4931 4424 * @param string $message The warning message to display.
4932 4425 * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
4933 - *
4934 4426 * @return void
4935 4427 */
4936 4428 public static function add_dismissable_warning_message( $message = '', $option = '' ) {
4937 4429 if ( ! $message || ! $option ) {
@@ -4974,9 +4466,8 @@
4974 4466 *
4975 4467 * @since 6.3
4976 4468 *
4977 4469 * @param string $option The unique identifier for the dismissal state of the message.
4978 - *
4979 4470 * @return void
4980 4471 */
4981 4472 public static function dismiss_warning_message( $option = '' ) {
4982 4473 self::permission_check( 'frm_change_settings' );
@@ -4982,9 +4473,9 @@
4982 4473 self::permission_check( 'frm_change_settings' );
4983 4474 check_ajax_referer( 'frm_ajax', 'nonce' );
4984 4475
4985 4476 if ( $option ) {
4986 - update_option( $option, true, false );
4477 + update_option( $option, true, 'no' );
4987 4478 }
4988 4479
4989 4480 wp_send_json_success();
4990 4481 }
@@ -4998,8 +4489,17 @@
4998 4489 * @return string
4999 4490 */
5000 4491 public static function copy_for_lite_license() {
5001 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 +
5002 4502 return apply_filters( 'frm_license_type_text', $message );
5003 4503 }
5004 4504
5005 4505 /**
@@ -5005,9 +4505,8 @@
5005 4505 /**
5006 4506 * Removes scripts that are unnecessarily loaded across the pages!
5007 4507 *
5008 4508 * @since 6.9
5009 - *
5010 4509 * @return void
5011 4510 */
5012 4511 public static function dequeue_extra_global_scripts() {
5013 4512 wp_dequeue_script( 'frm-surveys-admin' );
@@ -5025,21 +4524,18 @@
5025 4524 * @return void
5026 4525 */
5027 4526 public static function tooltip_icon( $tooltip_text, $atts = array() ) {
5028 4527 $atts['title'] = $tooltip_text;
5029 -
5030 4528 if ( isset( $atts['class'] ) ) {
5031 4529 $atts['class'] .= ' frm_help';
5032 4530 } else {
5033 4531 $atts['class'] = 'frm_help';
5034 4532 }
5035 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5036 4533 ?>
5037 4534 <span <?php self::array_to_html_params( $atts, true ); ?>>
5038 4535 <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?>
5039 4536 </span>
5040 4537 <?php
5041 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5042 4538 }
5043 4539
5044 4540 /**
5045 4541 * Prints errors for settings in onboarding wizard or template settings.
@@ -5060,10 +4556,8 @@
5060 4556 )
5061 4557 );
5062 4558
5063 4559 $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden';
5064 -
5065 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5066 4560 ?>
5067 4561 <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>">
5068 4562 <?php
5069 4563 if ( is_array( $args['errors'] ) ) {
@@ -5077,9 +4571,8 @@
5077 4571 }
5078 4572 ?>
5079 4573 </span>
5080 4574 <?php
5081 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5082 4575 }
5083 4576
5084 4577 /**
5085 4578 * Check if GDPR is enabled.
@@ -5102,62 +4595,6 @@
5102 4595 */
5103 4596 public static function no_gdpr_cookies() {
5104 4597 $frm_settings = self::get_settings();
5105 4598 return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies;
5106 - }
5107 -
5108 - /**
5109 - * Check if a string is valid UTF-8.
5110 - *
5111 - * @since 6.24
5112 - *
5113 - * @param string|null $string The string to check.
5114 - *
5115 - * @return bool
5116 - */
5117 - public static function is_valid_utf8( $string ) {
5118 - if ( is_null( $string ) ) {
5119 - // Return true so we do not attempt to change encoding on a null value.
5120 - return true;
5121 - }
5122 -
5123 - // wp_is_valid_utf8 is added in WP 6.9.
5124 - if ( function_exists( 'wp_is_valid_utf8' ) ) {
5125 - return wp_is_valid_utf8( $string );
5126 - }
5127 -
5128 - // As of WP 6.9, seems_utf8 is deprecated.
5129 - return function_exists( 'seems_utf8' ) ? seems_utf8( $string ) : false;
5130 - }
5131 -
5132 - /**
5133 - * Get a documentation URL with UTM parameters and affiliate tracking.
5134 - *
5135 - * @since 6.26
5136 - *
5137 - * @param string $path The relative path to append to the base URL.
5138 - * @param string $campaign The campaign to use for UTM parameters.
5139 - * @param bool $add_kb_base Whether to prepend 'knowledgebase/' to the path. Default true.
5140 - *
5141 - * @return string The processed URL with UTM parameters and affiliate tracking.
5142 - */
5143 - public static function get_doc_url( $path, $campaign, $add_kb_base = true ) {
5144 - $path = trim( $path, '/' );
5145 -
5146 - if ( $add_kb_base ) {
5147 - $path = 'knowledgebase/' . $path;
5148 - }
5149 -
5150 - return self::maybe_add_missing_utm( 'https://formidableforms.com/' . $path, array( 'campaign' => $campaign ) );
5151 - }
5152 -
5153 - /**
5154 - * @since 5.0.16
5155 - * @deprecated 6.26
5156 - *
5157 - * @return bool
5158 - */
5159 - public static function show_landing_pages() {
5160 - _deprecated_function( __METHOD__, '6.26' );
5161 - return true;
5162 4599 }
5163 4600 }