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 -1004 6.306.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 = 105;
13 + public static $db_version = 103;
14 14
15 15 /**
16 16 * Used by the API add-on.
17 17 *
@@ -28,9 +28,9 @@
28 28 * @since 2.0
29 29 *
30 30 * @var string
31 31 */
32 - public static $plug_version = '6.30';
32 + public static $plug_version = '6.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,9 +1380,8 @@
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 1385 */
1540 1386 public static function clip( $echo_function, $echo = false ) {
1541 1387 if ( ! $echo ) {
@@ -1545,9 +1391,13 @@
1545 1391 if ( is_callable( $echo_function ) ) {
1546 1392 $echo_function();
1547 1393 }
1548 1394
1549 - return $echo ? null : ob_get_clean();
1395 + if ( ! $echo ) {
1396 + $return = ob_get_contents();
1397 + ob_end_clean();
1398 + return $return;
1399 + }
1550 1400 }
1551 1401
1552 1402 /**
1553 1403 * @since 3.0
@@ -1552,18 +1402,15 @@
1552 1402 /**
1553 1403 * @since 3.0
1554 1404 *
1555 1405 * @param array $atts
1556 - *
1557 1406 * @return void
1558 1407 */
1559 1408 public static function get_admin_header( $atts ) {
1560 1409 $has_nav = ! empty( $atts['form'] ) && empty( $atts['is_template'] );
1561 -
1562 1410 if ( empty( $atts['close'] ) ) {
1563 1411 $atts['close'] = admin_url( 'admin.php?page=formidable' );
1564 1412 }
1565 -
1566 1413 if ( ! isset( $atts['import_link'] ) ) {
1567 1414 $atts['import_link'] = false;
1568 1415 }
1569 1416
@@ -1573,19 +1420,16 @@
1573 1420 /**
1574 1421 * @since 6.0
1575 1422 *
1576 1423 * @param string $type
1577 - *
1578 1424 * @return void
1579 1425 */
1580 1426 public static function import_link( $type = 'secondary' ) {
1581 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1582 1427 ?>
1583 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">
1584 1429 <?php esc_html_e( 'Import', 'formidable' ); ?>
1585 1430 </a>
1586 1431 <?php
1587 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1588 1432 }
1589 1433
1590 1434 /**
1591 1435 * Print applicable admin banner.
@@ -1592,9 +1436,8 @@
1592 1436 *
1593 1437 * @since 5.4.2
1594 1438 *
1595 1439 * @param bool $should_show_lite_upgrade
1596 - *
1597 1440 * @return void
1598 1441 */
1599 1442 public static function print_admin_banner( $should_show_lite_upgrade ) {
1600 1443 if ( ! current_user_can( 'administrator' ) ) {
@@ -1606,15 +1449,13 @@
1606 1449 // Print license warning or inbox banner and exit if either prints.
1607 1450 // And exit before printing the upgrade bar if it shouldn't be shown.
1608 1451 return;
1609 1452 }
1610 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1611 1453 ?>
1612 1454 <div class="frm-upgrade-bar">
1613 1455 <div class="frm-upgrade-bar-inner">
1614 1456 <?php
1615 1457 $cta_text = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_text' );
1616 -
1617 1458 if ( ! $cta_text ) {
1618 1459 $cta_text = __( 'upgrading to PRO', 'formidable' );
1619 1460 }
1620 1461
@@ -1619,13 +1460,17 @@
1619 1460 }
1620 1461
1621 1462 $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' );
1622 1463 $utm = array(
1623 - 'campaign' => 'settings-license',
1624 - 'content' => 'lite-banner',
1464 + 'medium' => 'settings-license',
1465 + 'content' => 'lite-banner',
1625 1466 );
1626 1467
1627 - $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 + }
1628 1473
1629 1474 printf(
1630 1475 /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */
1631 1476 esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ),
@@ -1636,9 +1481,8 @@
1636 1481 ?>
1637 1482 </div>
1638 1483 </div>
1639 1484 <?php
1640 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1641 1485 }
1642 1486
1643 1487 /**
1644 1488 * @since 5.4.2
@@ -1652,9 +1496,8 @@
1652 1496 /**
1653 1497 * Render a button for a new item (Form, Application, etc).
1654 1498 *
1655 1499 * @since 3.0
1656 - *
1657 1500 * @param array $atts {
1658 1501 * Details about the button.
1659 1502 *
1660 1503 * @type array $link_hook Custom link hook, calls do_action and exits early.
@@ -1661,9 +1504,8 @@
1661 1504 * @type string $new_link Href value, default #.
1662 1505 * @type string $class Custom class names, space separated.
1663 1506 * @type string $button_text Button text. Default "Add New".
1664 1507 * }
1665 - *
1666 1508 * @return void
1667 1509 */
1668 1510 public static function add_new_item_link( $atts ) {
1669 1511 if ( isset( $atts['link_hook'] ) ) {
@@ -1689,12 +1531,8 @@
1689 1531 }
1690 1532
1691 1533 /**
1692 1534 * @since 3.06
1693 - *
1694 - * @param array $atts
1695 - *
1696 - * @return void
1697 1535 */
1698 1536 public static function show_search_box( $atts ) {
1699 1537 $defaults = array(
1700 1538 'placeholder' => '',
@@ -1701,9 +1539,8 @@
1701 1539 'tosearch' => '',
1702 1540 'text' => __( 'Search', 'formidable' ),
1703 1541 'input_id' => '',
1704 1542 'value' => false,
1705 - 'class' => '',
1706 1543 );
1707 1544 $atts = array_merge( $defaults, $atts );
1708 1545
1709 1546 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
@@ -1710,9 +1547,8 @@
1710 1547 $atts['tosearch'] = 'frm-card';
1711 1548 }
1712 1549
1713 1550 $class = 'frm-search-input';
1714 -
1715 1551 if ( ! empty( $atts['tosearch'] ) ) {
1716 1552 $class .= ' frm-auto-search';
1717 1553 }
1718 1554
@@ -1736,15 +1572,14 @@
1736 1572
1737 1573 if ( ! empty( $atts['tosearch'] ) ) {
1738 1574 $input_atts['autocomplete'] = 'off';
1739 1575 }
1740 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1741 1576 ?>
1742 - <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>">
1577 + <p class="frm-search">
1743 1578 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
1744 1579 <?php echo esc_html( $atts['text'] ); ?>:
1745 1580 </label>
1746 - <?php self::icon_by_class( 'frmfont frm_search_icon frm_svg20' ); ?>
1581 + <span class="frmfont frm_search_icon"></span>
1747 1582 <input <?php self::array_to_html_params( $input_atts, true ); ?> />
1748 1583 <?php
1749 1584 if ( empty( $atts['tosearch'] ) ) {
1750 1585 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
@@ -1751,21 +1586,17 @@
1751 1586 }
1752 1587 ?>
1753 1588 </p>
1754 1589 <?php
1755 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1756 1590 }
1757 1591
1758 1592 /**
1759 - * @param string $type Hook type slug.
1760 - * @param object|null $object Optional related object.
1761 - *
1593 + * @param string $type
1762 1594 * @return void
1763 1595 */
1764 1596 public static function trigger_hook_load( $type, $object = null ) {
1765 1597 // Only load the form hooks once.
1766 1598 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
1767 -
1768 1599 if ( ! $hooks_loaded ) {
1769 1600 do_action( 'frm_load_' . $type . '_hooks' );
1770 1601 }
1771 1602 }
@@ -1824,14 +1655,14 @@
1824 1655 * True when value is 1, true, 'true', 'yes'
1825 1656 *
1826 1657 * @since 1.07.10
1827 1658 *
1828 - * @param bool|int|string $value The value to compare.
1659 + * @param string $value The value to compare.
1829 1660 *
1830 1661 * @return bool
1831 1662 */
1832 1663 public static function is_true( $value ) {
1833 - return true === $value || '1' === (string) $value || 'true' === $value || 'yes' === $value;
1664 + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value;
1834 1665 }
1835 1666
1836 1667 /**
1837 1668 * Gets all post from a specific post type.
@@ -1839,9 +1670,8 @@
1839 1670 *
1840 1671 * @since 4.10.01 Add `$post_type` argument.
1841 1672 *
1842 1673 * @param string $post_type Post type to query. Default is `page`.
1843 - *
1844 1674 * @return WP_Post[]
1845 1675 */
1846 1676 public static function get_pages( $post_type = 'page' ) {
1847 1677 $query = array(
@@ -1860,9 +1690,8 @@
1860 1690 *
1861 1691 * @since 5.0.09
1862 1692 *
1863 1693 * @param string $post_type Post type to query. Default is `page`.
1864 - *
1865 1694 * @return array
1866 1695 */
1867 1696 public static function get_post_ids_and_titles( $post_type = 'page' ) {
1868 1697 return FrmDb::get_results(
@@ -1887,9 +1716,10 @@
1887 1716 *
1888 1717 * @param array $args Selection arguments.
1889 1718 */
1890 1719 public static function maybe_autocomplete_pages_options( $args ) {
1891 - $args = self::preformat_selection_args( $args );
1720 + $args = self::preformat_selection_args( $args );
1721 +
1892 1722 $pages_count = wp_count_posts( $args['post_type'] );
1893 1723
1894 1724 if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) {
1895 1725 self::wp_pages_dropdown( $args );
@@ -1936,11 +1766,11 @@
1936 1766 'value_key' => 'value',
1937 1767 'label_key' => 'label',
1938 1768 );
1939 1769
1940 - $args = wp_parse_args( $args, $defaults );
1770 + $args = wp_parse_args( $args, $defaults );
1771 +
1941 1772 $html_attrs = array();
1942 -
1943 1773 if ( ! empty( $args['name'] ) ) {
1944 1774 $html_attrs['name'] = $args['name'];
1945 1775 }
1946 1776
@@ -1947,9 +1777,8 @@
1947 1777 if ( ! empty( $args['id'] ) ) {
1948 1778 $html_attrs['id'] = $args['id'];
1949 1779 }
1950 1780
1951 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1952 1781 if ( count( $args['source'] ) <= $args['dropdown_limit'] ) {
1953 1782 ?>
1954 1783 <select <?php self::array_to_html_params( $html_attrs, true ); ?>>
1955 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
@@ -1955,44 +1784,40 @@
1955 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1956 1785 <?php
1957 1786 foreach ( $args['source'] as $key => $source ) :
1958 1787 $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1959 -
1960 1788 if ( ! empty( $args['truncate'] ) ) {
1961 1789 $value_label['label'] = self::truncate( $value_label['label'], $args['truncate'] );
1962 1790 }
1963 1791 ?>
1964 - <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
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>
1965 1793 <?php endforeach; ?>
1966 1794 </select>
1967 1795 <?php
1968 - return;
1969 - }
1970 - // 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 );
1971 1801
1972 - $options = array();
1973 - $autocomplete_value = '';
1802 + if ( $value_label['value'] === $args['selected'] ) {
1803 + $autocomplete_value = $value_label['label'];
1804 + }
1974 1805
1975 - foreach ( $args['source'] as $key => $source ) {
1976 - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1977 -
1978 - if ( $value_label['value'] === $args['selected'] ) {
1979 - $autocomplete_value = $value_label['label'];
1806 + $options[] = $value_label;
1980 1807 }
1981 1808
1982 - $options[] = $value_label;
1983 - }
1984 -
1985 - $html_attrs['type'] = 'hidden';
1986 - $html_attrs['class'] = 'frm_autocomplete_value_input';
1987 - $html_attrs['value'] = $args['selected'];
1988 - ?>
1989 - <input type="text" class="frm-custom-search"
1990 - data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
1991 - placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1992 - value="<?php echo esc_attr( $autocomplete_value ); ?>" />
1993 - <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
1994 - <?php
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
1995 1820 }
1996 1821
1997 1822 /**
1998 1823 * Gets dropdown value and label from autodropdown option.
@@ -2001,15 +1826,14 @@
2001 1826 *
2002 1827 * @param array|string $option Autocomplete option.
2003 1828 * @param string $key Array key of the option.
2004 1829 * @param array $args See {@see FrmAppHelper::maybe_autocomplete_options()}.
2005 - *
2006 1830 * @return array
2007 1831 */
2008 1832 private static function get_dropdown_value_and_label_from_option( $option, $key, $args ) {
2009 1833 if ( is_array( $option ) ) {
2010 - $value = $option[ $args['value_key'] ] ?? '';
2011 - $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'] ] : '';
2012 1836 } else {
2013 1837 $value = $key;
2014 1838 $label = $option;
2015 1839 }
@@ -2026,9 +1850,8 @@
2026 1850 self::prep_page_dropdown_params( $page_id, $truncate, $args );
2027 1851
2028 1852 $pages = self::get_post_ids_and_titles( $args['post_type'] );
2029 1853 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
2030 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2031 1854 ?>
2032 1855 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
2033 1856 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
2034 1857 <?php foreach ( $pages as $page ) { ?>
@@ -2037,9 +1860,8 @@
2037 1860 </option>
2038 1861 <?php } ?>
2039 1862 </select>
2040 1863 <?php
2041 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2042 1864 }
2043 1865
2044 1866 /**
2045 1867 * Fill in missing parameters passed to wp_pages_dropdown().
@@ -2045,14 +1867,8 @@
2045 1867 * Fill in missing parameters passed to wp_pages_dropdown().
2046 1868 * This is for reverse compatibility with switching 3 params to 1.
2047 1869 *
2048 1870 * @since 4.03.06
2049 - *
2050 - * @param string $page_id Deprecated.
2051 - * @param bool $truncate Deprecated.
2052 - * @param mixed $args
2053 - *
2054 - * @return void
2055 1871 */
2056 1872 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
2057 1873 if ( ! is_array( $args ) ) {
2058 1874 $args = array(
@@ -2069,12 +1885,8 @@
2069 1885 * Filter to format args for page dropdown or autocomplete
2070 1886 *
2071 1887 * @since 4.03.06
2072 1888 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
2073 - *
2074 - * @param array $args
2075 - *
2076 - * @return array
2077 1889 */
2078 1890 private static function preformat_selection_args( $args ) {
2079 1891 $defaults = array(
2080 1892 'truncate' => false,
@@ -2087,18 +1899,13 @@
2087 1899
2088 1900 return array_merge( $defaults, $args );
2089 1901 }
2090 1902
2091 - /**
2092 - * @param int $post_id
2093 - *
2094 - * @return string
2095 - */
2096 1903 public static function post_edit_link( $post_id ) {
2097 1904 $post = get_post( $post_id );
2098 -
2099 1905 if ( $post ) {
2100 1906 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1907 +
2101 1908 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
2102 1909 }
2103 1910
2104 1911 return '';
@@ -2111,9 +1918,11 @@
2111 1918 *
2112 1919 * @return bool
2113 1920 */
2114 1921 public static function is_full_screen() {
2115 - return self::is_form_builder_page() || self::is_style_editor_page() || self::is_full_screen_view_builder_page();
1922 + return self::is_form_builder_page() ||
1923 + self::is_style_editor_page() ||
1924 + self::is_full_screen_view_builder_page();
2116 1925 }
2117 1926
2118 1927 /**
2119 1928 * Check if user is on the style editor or its alternative URL.
@@ -2123,9 +1932,8 @@
2123 1932 * @since 5.5.3
2124 1933 * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
2125 1934 *
2126 1935 * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
2127 - *
2128 1936 * @return bool
2129 1937 */
2130 1938 public static function is_style_editor_page( $view = '' ) {
2131 1939 if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
@@ -2162,9 +1970,8 @@
2162 1970 * @param array|string $capability
2163 1971 * @param string $multiple 'single' and 'multiple'.
2164 1972 */
2165 1973 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
2166 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2167 1974 ?>
2168 1975 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
2169 1976 <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?>
2170 1977 class="frm_multiselect">
@@ -2170,14 +1977,12 @@
2170 1977 class="frm_multiselect">
2171 1978 <?php self::roles_options( $capability ); ?>
2172 1979 </select>
2173 1980 <?php
2174 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2175 1981 }
2176 1982
2177 1983 /**
2178 1984 * @since 4.07
2179 - *
2180 1985 * @param array|string $selected
2181 1986 * @param string $current
2182 1987 */
2183 1988 private static function selected( $selected, $current ) {
@@ -2192,9 +1997,8 @@
2192 1997 * @param array|string $capability
2193 1998 */
2194 1999 public static function roles_options( $capability ) {
2195 2000 global $frm_vars;
2196 -
2197 2001 if ( isset( $frm_vars['editable_roles'] ) ) {
2198 2002 $editable_roles = $frm_vars['editable_roles'];
2199 2003 } else {
2200 2004 $editable_roles = get_editable_roles();
@@ -2203,9 +2007,9 @@
2203 2007
2204 2008 foreach ( $editable_roles as $role => $details ) {
2205 2009 $name = translate_user_role( $details['name'] );
2206 2010 ?>
2207 - <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>
2208 2012 <?php
2209 2013 unset( $role, $details );
2210 2014 }
2211 2015 }
@@ -2215,9 +2019,8 @@
2215 2019 *
2216 2020 * @since 5.0 Parameter `$type` supports `pro_only` value.
2217 2021 *
2218 2022 * @param string $type Supports `auto`, `pro`, or `pro_only`.
2219 - *
2220 2023 * @return array
2221 2024 */
2222 2025 public static function frm_capabilities( $type = 'auto' ) {
2223 2026 if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
@@ -2235,8 +2038,14 @@
2235 2038 * @param array<string,string> $pro_cap
2236 2039 */
2237 2040 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
2238 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 +
2239 2048 if ( 'pro_only' === $type ) {
2240 2049 return $pro_cap;
2241 2050 }
2242 2051
@@ -2282,18 +2091,21 @@
2282 2091 if ( $role === 'loggedin' || ! $role ) {
2283 2092 return is_user_logged_in();
2284 2093 }
2285 2094
2286 - if ( (int) $role === 1 ) {
2095 + if ( $role == 1 ) {
2287 2096 $role = 'administrator';
2288 2097 }
2289 2098
2290 - 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 );
2291 2104 }
2292 2105
2293 2106 /**
2294 2107 * @param array|string $needed_role
2295 - *
2296 2108 * @return bool
2297 2109 */
2298 2110 public static function user_has_permission( $needed_role ) {
2299 2111 if ( is_array( $needed_role ) ) {
@@ -2307,20 +2119,18 @@
2307 2119 }
2308 2120
2309 2121 $can = self::current_user_can( $needed_role );
2310 2122
2311 - if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ), true ) ) {
2123 + if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
2312 2124 return $can;
2313 2125 }
2314 2126
2315 2127 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
2316 -
2317 2128 foreach ( $roles as $role ) {
2318 2129 if ( current_user_can( $role ) ) {
2319 2130 return true;
2320 2131 }
2321 -
2322 - if ( $role === $needed_role ) {
2132 + if ( $role == $needed_role ) {
2323 2133 break;
2324 2134 }
2325 2135 }
2326 2136
@@ -2338,11 +2148,11 @@
2338 2148 if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
2339 2149 return;
2340 2150 }
2341 2151
2342 - $user = new WP_User( get_current_user_id() );
2152 + $user_id = get_current_user_id();
2153 + $user = new WP_User( $user_id );
2343 2154 $frm_roles = self::frm_capabilities();
2344 -
2345 2155 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2346 2156 $user->add_cap( $frm_role );
2347 2157 unset( $frm_role, $frm_role_description );
2348 2158 }
@@ -2353,22 +2163,18 @@
2353 2163 *
2354 2164 * @since 2.0.6
2355 2165 *
2356 2166 * @param string $cap
2357 - *
2358 2167 * @return void
2359 2168 */
2360 2169 public static function force_capability( $cap = 'frm_change_settings' ) {
2361 - if ( ! current_user_can( 'administrator' ) || current_user_can( $cap ) ) {
2362 - 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 + }
2363 2176 }
2364 -
2365 - $role = get_role( 'administrator' );
2366 - $frm_roles = self::frm_capabilities();
2367 -
2368 - foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2369 - $role->add_cap( $frm_role );
2370 - }
2371 2177 }
2372 2178
2373 2179 /**
2374 2180 * Check if the user has permission for action.
@@ -2376,22 +2182,17 @@
2376 2182 *
2377 2183 * @since 2.0
2378 2184 *
2379 2185 * @param string $permission
2380 - * @param string $show_message
2381 2186 */
2382 2187 public static function permission_check( $permission, $show_message = 'show' ) {
2383 2188 $permission_error = self::permission_nonce_error( $permission );
2384 -
2385 - if ( $permission_error === false ) {
2386 - return;
2189 + if ( $permission_error !== false ) {
2190 + if ( 'hide' == $show_message ) {
2191 + $permission_error = '';
2192 + }
2193 + wp_die( esc_html( $permission_error ) );
2387 2194 }
2388 -
2389 - if ( 'hide' === $show_message ) {
2390 - $permission_error = '';
2391 - }
2392 -
2393 - wp_die( esc_html( $permission_error ) );
2394 2195 }
2395 2196
2396 2197 /**
2397 2198 * Check user permission and nonce
@@ -2398,27 +2199,24 @@
2398 2199 *
2399 2200 * @since 2.0
2400 2201 *
2401 2202 * @param string $permission
2402 - * @param string $nonce_name
2403 - * @param string $nonce
2404 2203 *
2405 2204 * @return false|string The permission message or false if allowed
2406 2205 */
2407 2206 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
2408 - if ( $permission && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2207 + if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2409 2208 $frm_settings = self::get_settings();
2209 +
2410 2210 return $frm_settings->admin_permission;
2411 2211 }
2412 2212
2413 2213 $error = false;
2414 -
2415 - if ( ! $nonce_name ) {
2214 + if ( empty( $nonce_name ) ) {
2416 2215 return $error;
2417 2216 }
2418 2217
2419 2218 $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
2420 -
2421 2219 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
2422 2220 $frm_settings = self::get_settings();
2423 2221 $error = $frm_settings->admin_permission;
2424 2222 }
@@ -2425,14 +2223,8 @@
2425 2223
2426 2224 return $error;
2427 2225 }
2428 2226
2429 - /**
2430 - * @param array|string $values
2431 - * @param string $current
2432 - *
2433 - * @return void
2434 - */
2435 2227 public static function checked( $values, $current ) {
2436 2228 if ( self::check_selected( $values, $current ) ) {
2437 2229 echo ' checked="checked"';
2438 2230 }
@@ -2437,47 +2229,38 @@
2437 2229 echo ' checked="checked"';
2438 2230 }
2439 2231 }
2440 2232
2441 - /**
2442 - * @param array|string $values
2443 - * @param string|null $current
2444 - *
2445 - * @return bool
2446 - */
2447 2233 public static function check_selected( $values, $current ) {
2448 - $values = self::recursive_function_map( $values, 'trim' );
2449 - $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 +
2450 2237 $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) );
2451 2238
2452 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons
2453 - return is_array( $values ) ? in_array( $current, $values ) : $values == $current;
2239 + return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
2454 2240 }
2455 2241
2456 - /**
2457 - * @param array|string $value
2458 - * @param callable|string $function
2459 - *
2460 - * @return array|string
2461 - */
2462 2242 public static function recursive_function_map( $value, $function ) {
2463 2243 if ( is_array( $value ) ) {
2464 2244 $original_function = $function;
2465 - $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function );
2466 -
2467 - 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 {
2468 2253 foreach ( $value as $k => $v ) {
2469 2254 if ( ! is_array( $v ) ) {
2470 2255 $value[ $k ] = call_user_func( $original_function, $v );
2471 2256 }
2472 2257 }
2473 - } else {
2474 - $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2475 2258 }
2476 2259 } else {
2477 2260 $value = self::maybe_update_value_if_null( $value, $function );
2478 2261 $value = call_user_func( $function, $value );
2479 - }//end if
2262 + }
2480 2263
2481 2264 return $value;
2482 2265 }
2483 2266
@@ -2484,27 +2267,20 @@
2484 2267 /**
2485 2268 * Updates value to empty string if it is null and being passed to a string function.
2486 2269 *
2487 2270 * @since 6.8.4
2488 - *
2489 2271 * @param mixed $value
2490 2272 * @param string $function
2491 - *
2492 2273 * @return mixed
2493 2274 */
2494 2275 private static function maybe_update_value_if_null( $value, $function ) {
2495 2276 if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) {
2496 - return '';
2277 + $value = '';
2497 2278 }
2498 2279
2499 2280 return $value;
2500 2281 }
2501 2282
2502 - /**
2503 - * @param array $array
2504 - *
2505 - * @return bool
2506 - */
2507 2283 public static function is_assoc( $array ) {
2508 2284 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
2509 2285 }
2510 2286
@@ -2509,22 +2285,16 @@
2509 2285 }
2510 2286
2511 2287 /**
2512 2288 * Flatten a multi-dimensional array
2513 - *
2514 - * @param array $array
2515 - * @param string $keys
2516 - *
2517 - * @return array
2518 2289 */
2519 2290 public static function array_flatten( $array, $keys = 'keep' ) {
2520 2291 $return = array();
2521 -
2522 2292 foreach ( $array as $key => $value ) {
2523 2293 if ( is_array( $value ) ) {
2524 2294 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
2525 2295 } elseif ( $keys === 'keep' ) {
2526 - $return[ $key ] = $value;
2296 + $return[ $key ] = $value;
2527 2297 } else {
2528 2298 $return[] = $value;
2529 2299 }
2530 2300 }
@@ -2538,9 +2308,8 @@
2538 2308 * @since 6.16.1
2539 2309 *
2540 2310 * @param string $sep
2541 2311 * @param array $array
2542 - *
2543 2312 * @return string
2544 2313 */
2545 2314 public static function safe_implode( $sep, $array ) {
2546 2315 $array = self::array_flatten( $array );
@@ -2549,18 +2318,15 @@
2549 2318
2550 2319 /**
2551 2320 * @param string $text
2552 2321 * @param bool $is_rich_text
2553 - *
2554 2322 * @return string
2555 2323 */
2556 2324 public static function esc_textarea( $text, $is_rich_text = false ) {
2557 2325 $safe_text = str_replace( '&quot;', '"', $text );
2558 -
2559 2326 if ( ! $is_rich_text ) {
2560 2327 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
2561 2328 }
2562 -
2563 2329 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
2564 2330
2565 2331 /**
2566 2332 * @param string $safe_text
@@ -2572,59 +2338,44 @@
2572 2338 /**
2573 2339 * Add auto paragraphs to text areas
2574 2340 *
2575 2341 * @since 2.0
2576 - *
2577 - * @param mixed $content
2578 - *
2579 - * @return mixed
2580 2342 */
2581 2343 public static function use_wpautop( $content ) {
2582 2344 if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) {
2583 - return wpautop( str_replace( '<br>', '<br />', $content ) );
2345 + $content = wpautop( str_replace( '<br>', '<br />', $content ) );
2584 2346 }
2585 2347
2586 2348 return $content;
2587 2349 }
2588 2350
2589 - /**
2590 - * Replace quotes with their HTML entities.
2591 - *
2592 - * @param string $val
2593 - *
2594 - * @return string
2595 - */
2596 2351 public static function replace_quotes( $val ) {
2597 2352 // Replace double quotes.
2598 2353 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
2599 2354
2600 2355 // Replace single quotes.
2601 - 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;
2602 2359 }
2603 2360
2604 2361 /**
2605 - * @param string $handle
2606 - * @param int|string $default
2607 - *
2608 - * @return int|string
2362 + * @param string $handle
2609 2363 */
2610 2364 public static function script_version( $handle, $default = 0 ) {
2611 2365 global $wp_scripts;
2612 -
2613 2366 if ( ! $wp_scripts ) {
2614 2367 return $default;
2615 2368 }
2616 2369
2617 2370 $ver = $default;
2618 -
2619 2371 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
2620 2372 return $ver;
2621 2373 }
2622 2374
2623 2375 $query = $wp_scripts->registered[ $handle ];
2624 -
2625 2376 if ( is_object( $query ) && ! empty( $query->ver ) ) {
2626 - return $query->ver;
2377 + $ver = $query->ver;
2627 2378 }
2628 2379
2629 2380 return $ver;
2630 2381 }
@@ -2633,9 +2384,8 @@
2633 2384 * @since 5.0.13 added $echo param.
2634 2385 *
2635 2386 * @param string $url
2636 2387 * @param bool $echo
2637 - *
2638 2388 * @return string|null
2639 2389 */
2640 2390 public static function js_redirect( $url, $echo = false ) {
2641 2391 $callback = function () use ( $url ) {
@@ -2643,13 +2393,8 @@
2643 2393 };
2644 2394 return self::clip( $callback, $echo );
2645 2395 }
2646 2396
2647 - /**
2648 - * @param int|string $user_id
2649 - *
2650 - * @return int|string
2651 - */
2652 2397 public static function get_user_id_param( $user_id ) {
2653 2398 if ( ! $user_id || is_numeric( $user_id ) ) {
2654 2399 return $user_id;
2655 2400 }
@@ -2654,13 +2399,16 @@
2654 2399 return $user_id;
2655 2400 }
2656 2401
2657 2402 $user_id = sanitize_text_field( $user_id );
2658 -
2659 2403 if ( $user_id === 'current' ) {
2660 2404 $user_id = get_current_user_id();
2661 2405 } else {
2662 - $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 + }
2663 2411
2664 2412 if ( $user ) {
2665 2413 $user_id = $user->ID;
2666 2414 }
@@ -2672,9 +2420,8 @@
2672 2420
2673 2421 /**
2674 2422 * @param string $filename
2675 2423 * @param array $atts
2676 - *
2677 2424 * @return false|string
2678 2425 */
2679 2426 public static function get_file_contents( $filename, $atts = array() ) {
2680 2427 if ( ! is_file( $filename ) ) {
@@ -2683,9 +2430,12 @@
2683 2430
2684 2431 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
2685 2432 ob_start();
2686 2433 include $filename;
2687 - return ob_get_clean();
2434 + $contents = ob_get_contents();
2435 + ob_end_clean();
2436 +
2437 + return $contents;
2688 2438 }
2689 2439
2690 2440 /**
2691 2441 * @param string $name
@@ -2695,9 +2445,8 @@
2695 2445 * @param int $num_chars
2696 2446 */
2697 2447 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
2698 2448 $key = '';
2699 -
2700 2449 if ( $name ) {
2701 2450 $key = sanitize_key( $name );
2702 2451 $key = self::maybe_clear_long_key( $key, $column );
2703 2452 }
@@ -2717,31 +2466,31 @@
2717 2466 $column
2718 2467 );
2719 2468
2720 2469 // Create a unique field id if it has already been used.
2721 - if ( ! in_array( $key, $similar_keys, true ) ) {
2722 - return $key;
2723 - }
2470 + if ( in_array( $key, $similar_keys, true ) ) {
2471 + $key = self::maybe_truncate_key_before_appending( $column, $key );
2724 2472
2725 - $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 );
2726 2482
2727 - /**
2728 - * Allow for a custom separator between the attempted key and the generated suffix.
2729 - *
2730 - * @since 5.2.03
2731 - *
2732 - * @param string $separator. Default empty.
2733 - * @param string $key the key without the added suffix.
2734 - */
2735 - $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2483 + $suffix = 2;
2484 + do {
2485 + $key_check = $key . $separator . $suffix;
2486 + ++$suffix;
2487 + } while ( in_array( $key_check, $similar_keys, true ) );
2736 2488
2737 - $suffix = 2;
2738 - do {
2739 - $key_check = $key . $separator . $suffix;
2740 - ++$suffix;
2741 - } while ( in_array( $key_check, $similar_keys, true ) );
2489 + $key = $key_check;
2490 + }//end if
2742 2491
2743 - return $key_check;
2492 + return $key;
2744 2493 }
2745 2494
2746 2495 /**
2747 2496 * Avoid trying to append to a really long key,
@@ -2748,26 +2497,20 @@
2748 2497 * The database limit is 100 for form and field keys so we want to avoid getting too close.
2749 2498 *
2750 2499 * @param string $column
2751 2500 * @param string $key
2752 - *
2753 2501 * @return string
2754 2502 */
2755 2503 private static function maybe_truncate_key_before_appending( $column, $key ) {
2756 - if ( ! in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2757 - return $key;
2758 - }
2759 -
2760 - $max_key_length_before_truncating = 60;
2761 -
2762 - if ( strlen( $key ) > $max_key_length_before_truncating ) {
2763 - $key = substr( $key, 0, $max_key_length_before_truncating );
2764 -
2765 - if ( is_numeric( $key ) ) {
2766 - $key .= 'a';
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 + }
2767 2511 }
2768 2512 }
2769 -
2770 2513 return $key;
2771 2514 }
2772 2515
2773 2516 /**
@@ -2774,14 +2517,13 @@
2774 2517 * Possibly reset a key to avoid conflicts with column size limits.
2775 2518 *
2776 2519 * @param string $key
2777 2520 * @param string $column
2778 - *
2779 2521 * @return string either the original key value, or an empty string if the key was too long.
2780 2522 */
2781 2523 private static function maybe_clear_long_key( $key, $column ) {
2782 2524 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
2783 - return '';
2525 + $key = '';
2784 2526 }
2785 2527 return $key;
2786 2528 }
2787 2529
@@ -2788,22 +2530,20 @@
2788 2530 /**
2789 2531 * @since 6.21 This is changed from `private` to `public`.
2790 2532 *
2791 2533 * @param int $num_chars
2792 - *
2793 2534 * @return string
2794 2535 */
2795 2536 public static function generate_new_key( $num_chars ) {
2796 - $max_slug_value = 36 ** $num_chars;
2537 + $max_slug_value = pow( 36, $num_chars );
2797 2538
2798 2539 // We want to have at least 2 characters in the slug.
2799 2540 $min_slug_value = 37;
2800 - 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 );
2801 2542 }
2802 2543
2803 2544 /**
2804 2545 * @param string $key
2805 - *
2806 2546 * @return string
2807 2547 */
2808 2548 private static function prevent_numeric_and_reserved_keys( $key ) {
2809 2549 if ( is_numeric( $key ) ) {
@@ -2817,14 +2557,12 @@
2817 2557 'editlink',
2818 2558 'siteurl',
2819 2559 'evenodd',
2820 2560 );
2821 -
2822 2561 if ( in_array( $key, $not_allowed, true ) ) {
2823 2562 $key .= 'a';
2824 2563 }
2825 2564 }
2826 -
2827 2565 return $key;
2828 2566 }
2829 2567
2830 2568 /**
@@ -2843,9 +2581,9 @@
2843 2581 if ( ! $record ) {
2844 2582 return false;
2845 2583 }
2846 2584
2847 - if ( ! $post_values ) {
2585 + if ( empty( $post_values ) ) {
2848 2586 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
2849 2587 }
2850 2588
2851 2589 $values = array(
@@ -2853,9 +2591,9 @@
2853 2591 'fields' => array(),
2854 2592 );
2855 2593
2856 2594 foreach ( array( 'name', 'description' ) as $var ) {
2857 - $default_val = $record->{$var} ?? '';
2595 + $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
2858 2596 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
2859 2597 unset( $var, $default_val );
2860 2598 }
2861 2599
@@ -2873,67 +2611,46 @@
2873 2611
2874 2612 return $values;
2875 2613 }
2876 2614
2877 - /**
2878 - * @param array|string $fields
2879 - * @param object $record
2880 - * @param array $values
2881 - * @param array $args
2882 - *
2883 - * @return void
2884 - */
2885 2615 private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
2886 - if ( ! $fields ) {
2887 - return;
2888 - }
2889 -
2890 - foreach ( (array) $fields as $field ) {
2891 - if ( ! self::is_admin_page() ) {
2892 - // Don't prep default values on the form settings page.
2893 - $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
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 );
2894 2624 }
2895 -
2896 - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id;
2897 - self::fill_field_defaults( $field, $record, $values, $args );
2898 2625 }
2899 2626 }
2900 2627
2901 - /**
2902 - * @param object $field
2903 - * @param object $record
2904 - * @param array $values
2905 - * @param array $args
2906 - *
2907 - * @return void
2908 - */
2909 2628 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
2910 2629 $post_values = $args['post_values'];
2911 2630
2912 2631 if ( $args['default'] ) {
2913 2632 $meta_value = $field->default_value;
2914 - } 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'] ) {
2915 2634 if ( ! isset( $field->field_options['custom_field'] ) ) {
2916 2635 $field->field_options['custom_field'] = '';
2917 2636 }
2918 -
2919 - $meta_value = FrmProEntryMetaHelper::get_post_value(
2920 - $record->post_id,
2921 - $field->field_options['post_field'],
2922 - $field->field_options['custom_field'],
2923 - array(
2924 - 'truncate' => false,
2925 - 'type' => $field->type,
2926 - 'form_id' => $field->form_id,
2927 - 'field' => $field,
2928 - )
2929 - );
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 + );
2930 2648 } else {
2931 2649 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
2932 2650 }//end if
2933 2651
2934 - $field_type = $post_values['field_options'][ 'type_' . $field->id ] ?? $field->type;
2935 -
2652 + $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
2936 2653 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
2937 2654 $new_value = $post_values['item_meta'][ $field->id ];
2938 2655 self::unserialize_or_decode( $new_value );
2939 2656 } else {
@@ -2948,9 +2665,9 @@
2948 2665 $args['field_type'] = $field_type;
2949 2666
2950 2667 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
2951 2668
2952 - if ( empty( $field_array['unique'] ) ) {
2669 + if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
2953 2670 $field_array['unique_msg'] = '';
2954 2671 }
2955 2672
2956 2673 $field_array = array_merge( (array) $field->field_options, $field_array );
@@ -3017,21 +2734,15 @@
3017 2734 }
3018 2735
3019 2736 /**
3020 2737 * Set to POST value or default
3021 - *
3022 - * @param array $post_values
3023 - * @param array $values
3024 - *
3025 - * @return void
3026 2738 */
3027 2739 private static function fill_form_defaults( $post_values, array &$values ) {
3028 2740 $form_defaults = FrmFormsHelper::get_default_opts();
3029 2741
3030 2742 foreach ( $form_defaults as $opt => $default ) {
3031 - // phpcs:ignore Universal.Operators.StrictComparisons
3032 2743 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
3033 - $values[ $opt ] = $post_values['options'][ $opt ] ?? $default;
2744 + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default;
3034 2745 }
3035 2746
3036 2747 unset( $opt, $default );
3037 2748 }
@@ -3041,9 +2752,9 @@
3041 2752 }
3042 2753
3043 2754 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
3044 2755 if ( ! isset( $values[ $h . '_html' ] ) ) {
3045 - $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 ) );
3046 2757 }
3047 2758 unset( $h );
3048 2759 }
3049 2760 }
@@ -3055,57 +2766,46 @@
3055 2766 *
3056 2767 * @return bool|int
3057 2768 */
3058 2769 public static function custom_style_value( $post_values ) {
3059 - if ( $post_values && isset( $post_values['options']['custom_style'] ) ) {
3060 - return absint( $post_values['options']['custom_style'] );
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' );
3061 2775 }
3062 2776
3063 - $frm_settings = self::get_settings();
3064 - return $frm_settings->load_style !== 'none';
2777 + return $custom_style;
3065 2778 }
3066 2779
3067 2780 /**
3068 - * Truncate a string.
3069 - *
3070 - * Note: By default, this function will allow for a few additional characters more than $length.
3071 - * If a string has no spaces, it allows up to 50 additional characters. To force a true length limit,
3072 - * use $force_length_limit = true.
3073 - *
3074 2781 * @param mixed $original_string
3075 2782 * @param int|string $length
3076 2783 * @param int $minword
3077 2784 * @param string $continue
3078 - * @param bool $force_length_limit Force the final string to never exceed the length limit.
3079 - *
3080 2785 * @return string
3081 2786 */
3082 - 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 = '...' ) {
3083 2788 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
3084 2789 return '';
3085 2790 }
3086 2791
3087 - $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 ) );
3088 2795
3089 - if ( $length === 0 ) {
2796 + if ( $length == 0 ) {
3090 2797 return '';
3091 2798 }
3092 2799
3093 - $str = wp_strip_all_tags( (string) $original_string );
3094 - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3095 -
3096 2800 if ( $length <= 10 ) {
3097 2801 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
3098 -
3099 - if ( $force_length_limit ) {
3100 - return $sub;
3101 - }
3102 -
3103 2802 return $sub . ( $length < $original_len ? $continue : '' );
3104 2803 }
3105 2804
3106 - $sub = '';
3107 - $len = 0;
2805 + $sub = '';
2806 + $len = 0;
2807 +
3108 2808 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
3109 2809
3110 2810 if ( ! is_array( $words ) ) {
3111 2811 return $original_string;
@@ -3111,11 +2811,10 @@
3111 2811 return $original_string;
3112 2812 }
3113 2813
3114 2814 foreach ( $words as $word ) {
3115 - $part = ( $sub !== '' ? ' ' : '' ) . $word;
2815 + $part = ( $sub != '' ? ' ' : '' ) . $word;
3116 2816 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
3117 -
3118 2817 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
3119 2818 break;
3120 2819 }
3121 2820
@@ -3128,21 +2827,10 @@
3128 2827
3129 2828 unset( $total_len, $word );
3130 2829 }
3131 2830
3132 - $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 );
3133 2832
3134 - if ( $force_length_limit ) {
3135 - // Ensure the final string doesn't exceed the length limit.
3136 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3137 -
3138 - if ( $final_len > $length ) {
3139 - return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) );
3140 - }
3141 -
3142 - return $sub;
3143 - }
3144 -
3145 2833 return $sub . ( $len < $original_len ? $continue : '' );
3146 2834 }
3147 2835
3148 2836 /**
@@ -3149,51 +2837,30 @@
3149 2837 * If the string is still too long because there may not have been any spaces, force truncate.
3150 2838 *
3151 2839 * @since 6.5.4
3152 2840 *
3153 - * @param string $sub Current substring.
3154 - * @param int $length The length limit.
3155 - * @param bool $force_length_limit Force the string to not exceed the length limit.
3156 - *
2841 + * @param string $sub Current substring.
2842 + * @param int $length The length limit.
3157 2843 * @return string
3158 2844 */
3159 - private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit = false ) {
3160 - if ( ! $force_length_limit ) {
3161 - if ( strlen( $sub ) < $length + 50 ) {
3162 - // If the string isn't way over the limit, leave it.
3163 - return $sub;
3164 - }
3165 -
3166 - $first_space = strpos( $sub, ' ', $length );
3167 -
3168 - if ( false !== $first_space ) {
3169 - // Ignore anything with spaces.
3170 - return $sub;
3171 - }
3172 -
3173 - return substr( $sub, 0, $length + 10 );
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;
3174 2849 }
3175 2850
3176 - // When force_length_limit is true, ensure the string doesn't exceed the length.
3177 - $final_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub ) );
3178 -
3179 - if ( $final_len > $length ) {
3180 - return self::mb_function( array( 'mb_substr', 'substr' ), array( $sub, 0, $length ) );
2851 + $first_space = strpos( $sub, ' ', $length );
2852 + if ( false !== $first_space ) {
2853 + // Ignore anything with spaces.
2854 + return $sub;
3181 2855 }
3182 2856
3183 - return $sub;
2857 + return substr( $sub, 0, $length + 10 );
3184 2858 }
3185 2859
3186 - /**
3187 - * @param array $function_names
3188 - * @param array $args
3189 - *
3190 - * @return mixed
3191 - */
3192 2860 public static function mb_function( $function_names, $args ) {
3193 2861 $mb_function_name = $function_names[0];
3194 2862 $function_name = $function_names[1];
3195 -
3196 2863 if ( function_exists( $mb_function_name ) ) {
3197 2864 $function_name = $mb_function_name;
3198 2865 }
3199 2866
@@ -3199,21 +2866,14 @@
3199 2866
3200 2867 return call_user_func_array( $function_name, $args );
3201 2868 }
3202 2869
3203 - /**
3204 - * @param string $date
3205 - * @param string $date_format
3206 - * @param string $time_format
3207 - *
3208 - * @return string
3209 - */
3210 2870 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
3211 - if ( ! $date ) {
2871 + if ( empty( $date ) ) {
3212 2872 return $date;
3213 2873 }
3214 2874
3215 - if ( ! $date_format ) {
2875 + if ( empty( $date_format ) ) {
3216 2876 $date_format = get_option( 'date_format' );
3217 2877 }
3218 2878
3219 2879 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
@@ -3221,10 +2881,10 @@
3221 2881 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
3222 2882 }
3223 2883
3224 2884 $formatted = self::get_localized_date( $date_format, $date );
3225 - $do_time = gmdate( 'H:i:s', strtotime( $date ) ) !== '00:00:00';
3226 2885
2886 + $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
3227 2887 if ( $do_time ) {
3228 2888 $formatted .= self::add_time_to_date( $time_format, $date );
3229 2889 }
3230 2890
@@ -3233,35 +2893,30 @@
3233 2893
3234 2894 /**
3235 2895 * @param string $time_format
3236 2896 * @param string $date
3237 - *
3238 2897 * @return string
3239 2898 */
3240 2899 private static function add_time_to_date( $time_format, $date ) {
3241 - if ( ! $time_format ) {
2900 + if ( empty( $time_format ) ) {
3242 2901 $time_format = get_option( 'time_format' );
3243 2902 }
3244 2903
3245 2904 $trimmed_format = trim( $time_format );
3246 -
3247 - if ( $time_format && $trimmed_format ) {
3248 - 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 );
3249 2908 }
3250 2909
3251 - return '';
2910 + return $time;
3252 2911 }
3253 2912
3254 2913 /**
3255 2914 * @since 2.0.8
3256 - *
3257 - * @param string $date_format
3258 - * @param string $date
3259 - *
3260 - * @return string
3261 2915 */
3262 2916 public static function get_localized_date( $date_format, $date ) {
3263 2917 $date = get_date_from_gmt( $date );
2918 +
3264 2919 return date_i18n( $date_format, strtotime( $date ) );
3265 2920 }
3266 2921
3267 2922 /**
@@ -3266,16 +2921,19 @@
3266 2921
3267 2922 /**
3268 2923 * Gets the time ago in words.
3269 2924 *
3270 - * @param int $from In seconds.
3271 - * @param int|string $to In seconds.
3272 - * @param int|string $levels Number of time units to include or a specific unit.
2925 + * @param int $from In seconds.
2926 + * @param int|string $to In seconds.
3273 2927 *
3274 - * @return string Time ago.
2928 + * @return string $time_ago
3275 2929 */
3276 2930 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
3277 - $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 + }
3278 2936 $ago = new DateTime( '@' . $from );
3279 2937
3280 2938 // Get the time difference
3281 2939 $diff_object = $now->diff( $ago );
@@ -3289,9 +2947,8 @@
3289 2947
3290 2948 if ( ! is_numeric( $levels ) ) {
3291 2949 // Show time in specified unit.
3292 2950 $levels = self::get_unit( $levels );
3293 -
3294 2951 if ( isset( $time_strings[ $levels ] ) ) {
3295 2952 $diff = array(
3296 2953 $levels => self::time_format( $levels, $diff ),
3297 2954 );
@@ -3298,14 +2955,13 @@
3298 2955 $time_strings = array(
3299 2956 $levels => $time_strings[ $levels ],
3300 2957 );
3301 2958 }
3302 -
3303 2959 $levels = 1;
3304 2960 }
3305 2961
3306 2962 foreach ( $time_strings as $k => $v ) {
3307 - if ( ! empty( $diff[ $k ] ) ) {
2963 + if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
3308 2964 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
3309 2965 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
3310 2966 // Account for 0.
3311 2967 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
@@ -3313,21 +2969,17 @@
3313 2969 unset( $time_strings[ $k ] );
3314 2970 }
3315 2971 }
3316 2972
3317 - $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
3318 - $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
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 );
3319 2976
3320 - return implode( ' ', $time_strings );
2977 + return $time_ago_string;
3321 2978 }
3322 2979
3323 2980 /**
3324 2981 * @since 4.05.01
3325 - *
3326 - * @param string $unit
3327 - * @param array $diff
3328 - *
3329 - * @return int
3330 2982 */
3331 2983 private static function time_format( $unit, $diff ) {
3332 2984 $return = array(
3333 2985 'y' => 'y',
@@ -3332,14 +2984,14 @@
3332 2984 $return = array(
3333 2985 'y' => 'y',
3334 2986 'd' => 'days',
3335 2987 );
3336 -
3337 2988 if ( isset( $return[ $unit ] ) ) {
3338 2989 return $diff[ $return[ $unit ] ];
3339 2990 }
3340 2991
3341 2992 $total = $diff['days'] * self::convert_time( 'd', $unit );
2993 +
3342 2994 $times = array( 'h', 'i', 's' );
3343 2995
3344 2996 foreach ( $times as $time ) {
3345 2997 if ( ! isset( $diff[ $time ] ) ) {
@@ -3353,13 +3005,8 @@
3353 3005 }
3354 3006
3355 3007 /**
3356 3008 * @since 4.05.01
3357 - *
3358 - * @param string $from
3359 - * @param string $to
3360 - *
3361 - * @return int
3362 3009 */
3363 3010 private static function convert_time( $from, $to ) {
3364 3011 $convert = array(
3365 3012 's' => 1,
@@ -3375,26 +3022,20 @@
3375 3022 }
3376 3023
3377 3024 /**
3378 3025 * @since 4.05.01
3379 - *
3380 - * @param string $unit
3381 - *
3382 - * @return int|string
3383 3026 */
3384 3027 private static function get_unit( $unit ) {
3385 3028 $units = self::get_time_strings();
3386 -
3387 3029 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
3388 3030 return $unit;
3389 3031 }
3390 3032
3391 3033 foreach ( $units as $u => $strings ) {
3392 - if ( in_array( $unit, $strings, true ) ) {
3034 + if ( in_array( $unit, $strings ) ) {
3393 3035 return $u;
3394 3036 }
3395 3037 }
3396 -
3397 3038 return 1;
3398 3039 }
3399 3040
3400 3041 /**
@@ -3401,9 +3042,8 @@
3401 3042 * Get the translatable time strings. The untranslated version is a failsafe
3402 3043 * in case languages are changing for the unit set in the shortcode.
3403 3044 *
3404 3045 * @since 2.0.20
3405 - *
3406 3046 * @return array
3407 3047 */
3408 3048 private static function get_time_strings() {
3409 3049 return array(
@@ -3450,13 +3090,12 @@
3450 3090 /**
3451 3091 * @param int $r_count
3452 3092 * @param int $current_p
3453 3093 * @param int $p_size
3454 - *
3455 3094 * @return int
3456 3095 */
3457 3096 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
3458 - return $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size;
3097 + return ( $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size );
3459 3098 }
3460 3099
3461 3100 /**
3462 3101 * @param int $r_count
@@ -3461,13 +3100,11 @@
3461 3100 /**
3462 3101 * @param int $r_count
3463 3102 * @param int $current_p
3464 3103 * @param int $p_size
3465 - *
3466 3104 * @return int
3467 3105 */
3468 3106 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
3469 - // phpcs:ignore Universal.Operators.StrictComparisons
3470 3107 if ( $current_p == 1 ) {
3471 3108 return 1;
3472 3109 }
3473 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
@@ -3473,22 +3110,17 @@
3473 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
3474 3111 }
3475 3112
3476 3113 /**
3477 - * @param array $json_vars
3478 - *
3479 3114 * @return array
3480 3115 */
3481 3116 public static function json_to_array( $json_vars ) {
3482 3117 $vars = array();
3483 -
3484 3118 foreach ( $json_vars as $jv ) {
3485 3119 $jv_name = explode( '[', $jv['name'] );
3486 3120 $last = count( $jv_name ) - 1;
3487 -
3488 3121 foreach ( $jv_name as $p => $n ) {
3489 3122 $name = trim( $n, ']' );
3490 -
3491 3123 if ( ! isset( $l1 ) ) {
3492 3124 $l1 = $name;
3493 3125 }
3494 3126
@@ -3499,9 +3131,9 @@
3499 3131 if ( ! isset( $l3 ) ) {
3500 3132 $l3 = $name;
3501 3133 }
3502 3134
3503 - $this_val = $p === $last ? $jv['value'] : array();
3135 + $this_val = $p == $last ? $jv['value'] : array();
3504 3136
3505 3137 switch ( $p ) {
3506 3138 case 0:
3507 3139 $l1 = $name;
@@ -3534,15 +3166,10 @@
3534 3166
3535 3167 /**
3536 3168 * @param string $name
3537 3169 * @param string $l1
3538 - * @param mixed $val
3539 - * @param array $vars
3540 - *
3541 - * @return void
3542 3170 */
3543 3171 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
3544 - // phpcs:ignore Universal.Operators.StrictComparisons
3545 3172 if ( $name == '' ) {
3546 3173 $vars[] = $val;
3547 3174 } elseif ( ! isset( $vars[ $l1 ] ) ) {
3548 3175 $vars[ $l1 ] = $val;
@@ -3548,26 +3175,19 @@
3548 3175 $vars[ $l1 ] = $val;
3549 3176 }
3550 3177 }
3551 3178
3552 - /**
3553 - * @param string $name
3554 - * @param string $class
3555 - * @param string $form_name
3556 - *
3557 - * @return void
3558 - */
3559 3179 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
3560 3180 $tooltips = array(
3561 3181 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
3562 - 'email_to' => __( 'Add one or more recipient addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com. [default-email] is the address set in the global "Default Email Address" settings.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
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' ),
3563 3183 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3564 3184 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3565 - 'reply_to' => __( 'If you would like a different reply to address than the "from" address, add a single address here. FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
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' ),
3566 3186 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
3567 3187 /* translators: %1$s: Form name, %2$s: Date */
3568 - 'email_subject' => esc_attr( sprintf( __( 'If you leave the subject blank, the default will be used: %1$s Form submitted on %2$s', 'formidable' ), $form_name, self::site_name() ) ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3569 - 'new_tab' => __( 'This option will open the link in a new browser tab. Please note that some popup blockers may prevent this from happening, in which case the link will be displayed.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
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' ),
3570 3190 );
3571 3191
3572 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3573 3193 return;
@@ -3572,9 +3192,9 @@
3572 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3573 3193 return;
3574 3194 }
3575 3195
3576 - if ( 'open' === $class ) {
3196 + if ( 'open' == $class ) {
3577 3197 echo ' frm_help"';
3578 3198 } else {
3579 3199 echo ' class="frm_help"';
3580 3200 }
@@ -3580,9 +3200,9 @@
3580 3200 }
3581 3201
3582 3202 echo ' title="' . esc_attr( $tooltips[ $name ] );
3583 3203
3584 - if ( 'open' !== $class ) {
3204 + if ( 'open' != $class ) {
3585 3205 echo '"';
3586 3206 }
3587 3207 }
3588 3208
@@ -3587,28 +3207,20 @@
3587 3207 }
3588 3208
3589 3209 /**
3590 3210 * Add the current_page class to that page in the form nav
3591 - *
3592 - * @param int|string $page
3593 - * @param int|string $current_page
3594 - * @param array $action
3595 - *
3596 - * @return void
3597 3211 */
3598 3212 public static function select_current_page( $page, $current_page, $action = array() ) {
3599 - // phpcs:ignore Universal.Operators.StrictComparisons
3600 3213 if ( $current_page != $page ) {
3601 3214 return;
3602 3215 }
3603 3216
3604 3217 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
3605 -
3606 3218 if ( 'lite-reports' === $frm_action ) {
3607 3219 $frm_action = 'reports';
3608 3220 }
3609 3221
3610 - if ( ! $action || ( $frm_action && in_array( $frm_action, $action, true ) ) ) {
3222 + if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
3611 3223 echo ' class="current_page"';
3612 3224 }
3613 3225 }
3614 3226
@@ -3638,19 +3250,14 @@
3638 3250
3639 3251 // Add extra slashes for \r\n since WP strips them.
3640 3252 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
3641 3253
3642 - // Allow for &quot
3643 - return str_replace( '&quot;', '\\"', $post_content );
3254 + // allow for &quot
3255 + $post_content = str_replace( '&quot;', '\\"', $post_content );
3256 +
3257 + return $post_content;
3644 3258 }
3645 3259
3646 - /**
3647 - * @param array|string $val
3648 - * @param int|string $key
3649 - * @param array $post_content
3650 - *
3651 - * @return void
3652 - */
3653 3260 private static function prepare_action_slashes( $val, $key, &$post_content ) {
3654 3261 if ( ! isset( $post_content[ $key ] ) || is_numeric( $val ) ) {
3655 3262 return;
3656 3263 }
@@ -3659,17 +3266,15 @@
3659 3266 foreach ( $val as $k1 => $v1 ) {
3660 3267 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
3661 3268 unset( $k1, $v1 );
3662 3269 }
3270 + } else {
3271 + // Strip all slashes so everything is the same, no matter where the value is coming from
3272 + $val = stripslashes( $val );
3663 3273
3664 - return;
3274 + // Add backslashes before double quotes and forward slashes only
3275 + $post_content[ $key ] = addcslashes( $val, '"\\/' );
3665 3276 }
3666 -
3667 - // Strip all slashes so everything is the same, no matter where the value is coming from
3668 - $val = stripslashes( $val );
3669 -
3670 - // Add backslashes before double quotes and forward slashes only
3671 - $post_content[ $key ] = addcslashes( $val, '"\\/' );
3672 3277 }
3673 3278
3674 3279 /**
3675 3280 * Check for either json or serialized data. This is temporary while transitioning
@@ -3677,9 +3282,8 @@
3677 3282 *
3678 3283 * @since 4.02.03
3679 3284 *
3680 3285 * @param array|string $value
3681 - *
3682 3286 * @return void
3683 3287 */
3684 3288 public static function unserialize_or_decode( &$value ) {
3685 3289 if ( is_array( $value ) ) {
@@ -3685,9 +3289,13 @@
3685 3289 if ( is_array( $value ) ) {
3686 3290 return;
3687 3291 }
3688 3292
3689 - $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 + }
3690 3298 }
3691 3299
3692 3300 /**
3693 3301 * Safely unserialize an array if necessary.
@@ -3695,9 +3303,8 @@
3695 3303 *
3696 3304 * @since 6.2
3697 3305 *
3698 3306 * @param mixed $value
3699 - *
3700 3307 * @return mixed
3701 3308 */
3702 3309 public static function maybe_unserialize_array( $value ) {
3703 3310 if ( ! is_string( $value ) ) {
@@ -3704,15 +3311,18 @@
3704 3311 return $value;
3705 3312 }
3706 3313
3707 3314 // Since we only expect an array, skip anything that doesn't start with a:.
3708 - if ( ! is_serialized( $value ) || ! str_starts_with( $value, 'a:' ) ) {
3315 + if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
3709 3316 return $value;
3710 3317 }
3711 3318
3712 3319 $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
3320 + if ( is_array( $parsed ) ) {
3321 + $value = $parsed;
3322 + }
3713 3323
3714 - return is_array( $parsed ) ? $parsed : $value;
3324 + return $value;
3715 3325 }
3716 3326
3717 3327 /**
3718 3328 * Decode a JSON string.
@@ -3717,12 +3327,11 @@
3717 3327 /**
3718 3328 * Decode a JSON string.
3719 3329 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
3720 3330 *
3721 - * @param array|string|null $string
3722 - * @param bool $single_to_array
3723 - *
3724 - * @return array|string|null
3331 + * @param mixed $string
3332 + * @param bool $single_to_array
3333 + * @return mixed
3725 3334 */
3726 3335 public static function maybe_json_decode( $string, $single_to_array = true ) {
3727 3336 if ( is_array( $string ) || is_null( $string ) ) {
3728 3337 return $string;
@@ -3727,19 +3336,20 @@
3727 3336 if ( is_array( $string ) || is_null( $string ) ) {
3728 3337 return $string;
3729 3338 }
3730 3339
3731 - $new_string = json_decode( $string, true );
3732 - $single_value = false;
3733 -
3734 - if ( ! $single_to_array ) {
3735 - $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
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 + }
3736 3350 }
3737 3351
3738 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3739 - return $new_string;
3740 - }
3741 -
3742 3352 return $string;
3743 3353 }
3744 3354
3745 3355 /**
@@ -3745,9 +3355,8 @@
3745 3355 /**
3746 3356 * @since 6.2.3
3747 3357 *
3748 3358 * @param string $value
3749 - *
3750 3359 * @return string
3751 3360 */
3752 3361 public static function maybe_utf8_encode( $value ) {
3753 3362 $from_format = 'ISO-8859-1';
@@ -3756,15 +3365,13 @@
3756 3365 if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
3757 3366 if ( mb_check_encoding( $value, $from_format ) ) {
3758 3367 return mb_convert_encoding( $value, $to_format, $from_format );
3759 3368 }
3760 -
3761 3369 return $value;
3762 3370 }
3763 3371
3764 3372 if ( function_exists( 'iconv' ) ) {
3765 3373 $converted = iconv( $from_format, $to_format, $value );
3766 -
3767 3374 // Value is false if $value is not ISO-8859-1.
3768 3375 if ( false !== $converted ) {
3769 3376 return $converted;
3770 3377 }
@@ -3776,12 +3383,8 @@
3776 3383 /**
3777 3384 * Reformat the json serialized array in name => value array.
3778 3385 *
3779 3386 * @since 4.02.03
3780 - *
3781 - * @param array $form
3782 - *
3783 - * @return void
3784 3387 */
3785 3388 public static function format_form_data( &$form ) {
3786 3389 $formatted = array();
3787 3390
@@ -3788,21 +3391,18 @@
3788 3391 foreach ( $form as $input ) {
3789 3392 if ( ! isset( $input['name'] ) ) {
3790 3393 continue;
3791 3394 }
3792 -
3793 3395 $key = $input['name'];
3794 -
3795 - 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 {
3796 3403 $formatted[ $key ] = $input['value'];
3797 - continue;
3798 3404 }
3799 -
3800 - if ( is_array( $formatted[ $key ] ) ) {
3801 - $formatted[ $key ][] = $input['value'];
3802 - } else {
3803 - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3804 - }
3805 3405 }
3806 3406
3807 3407 parse_str( http_build_query( $formatted ), $form );
3808 3408 }
@@ -3810,13 +3410,15 @@
3810 3410 /**
3811 3411 * @since 4.02.03
3812 3412 *
3813 3413 * @param array|string $value
3814 - *
3815 3414 * @return string
3816 3415 */
3817 3416 public static function maybe_json_encode( $value ) {
3818 - return is_array( $value ) ? wp_json_encode( $value ) : $value;
3417 + if ( is_array( $value ) ) {
3418 + $value = wp_json_encode( $value );
3419 + }
3420 + return $value;
3819 3421 }
3820 3422
3821 3423 /**
3822 3424 * Echo The javascript to open and highlight the Formidable menu
@@ -3823,19 +3425,18 @@
3823 3425 *
3824 3426 * @since 1.07.10
3825 3427 *
3826 3428 * @param string $post_type The name of the post type that may need to be highlighted.
3827 - *
3828 3429 * @return void
3829 3430 */
3830 3431 public static function maybe_highlight_menu( $post_type ) {
3831 3432 global $post;
3832 3433
3833 - if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] !== $post_type ) {
3434 + if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
3834 3435 return;
3835 3436 }
3836 3437
3837 - if ( is_object( $post ) && $post->post_type !== $post_type ) {
3438 + if ( is_object( $post ) && $post->post_type != $post_type ) {
3838 3439 return;
3839 3440 }
3840 3441
3841 3442 self::load_admin_wide_js();
@@ -3847,13 +3448,13 @@
3847 3448 *
3848 3449 * @since 2.0
3849 3450 *
3850 3451 * @param bool $load
3851 - *
3852 3452 * @return void
3853 3453 */
3854 3454 public static function load_admin_wide_js( $load = true ) {
3855 - wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), self::plugin_version() );
3455 + $version = self::plugin_version();
3456 + wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
3856 3457
3857 3458 $global_strings = array(
3858 3459 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
3859 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
@@ -3859,9 +3460,9 @@
3859 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
3860 3461 'url' => self::plugin_url(),
3861 3462 'app_url' => 'https://formidableforms.com/',
3862 3463 'applicationsUrl' => admin_url( 'admin.php?page=formidable-applications' ),
3863 - 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3464 + 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ),
3864 3465 'loading' => __( 'Loading&hellip;', 'formidable' ),
3865 3466 'nonce' => wp_create_nonce( 'frm_ajax' ),
3866 3467 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
3867 3468 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(),
@@ -3874,9 +3475,8 @@
3874 3475 }
3875 3476
3876 3477 /**
3877 3478 * @since 2.0.9
3878 - *
3879 3479 * @return void
3880 3480 */
3881 3481 public static function load_font_style() {
3882 3482 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
@@ -3883,9 +3483,8 @@
3883 3483 }
3884 3484
3885 3485 /**
3886 3486 * @param string $location
3887 - *
3888 3487 * @return void
3889 3488 */
3890 3489 public static function localize_script( $location ) {
3891 3490 global $wp_scripts, $wp_version;
@@ -3908,9 +3507,8 @@
3908 3507 'include_resend_email' => false,
3909 3508 );
3910 3509
3911 3510 $data = $wp_scripts->get_data( 'formidable', 'data' );
3912 -
3913 3511 if ( ! $data ) {
3914 3512 wp_localize_script( 'formidable', 'frm_js', $script_strings );
3915 3513 }
3916 3514
@@ -3917,9 +3515,9 @@
3917 3515 if ( $location === 'admin' ) {
3918 3516 $admin_script_strings = array(
3919 3517 'desc' => __( '(Click to add description)', 'formidable' ),
3920 3518 'blank' => __( '(Blank)', 'formidable' ),
3921 - 'no_label' => self::get_no_label_text(),
3519 + 'no_label' => __( '(no label)', 'formidable' ),
3922 3520 'ok' => __( 'OK', 'formidable' ),
3923 3521 'cancel' => __( 'Cancel', 'formidable' ),
3924 3522 'default_label' => __( 'Default', 'formidable' ),
3925 3523 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3927,9 +3525,9 @@
3927 3525 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3928 3526 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3929 3527 'confirm' => __( 'Are you sure?', 'formidable' ),
3930 3528 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3931 - 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
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' ),
3932 3530 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3933 3531 'default_unique' => FrmFieldsHelper::default_unique_msg(),
3934 3532 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3935 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
@@ -3935,9 +3533,9 @@
3935 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
3936 3534 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3937 3535 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3938 3536 'new_option' => __( 'New Option', 'formidable' ),
3939 - 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
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' ),
3940 3538 'enter_password' => __( 'Enter Password', 'formidable' ),
3941 3539 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3942 3540 'import_complete' => __( 'Import Complete', 'formidable' ),
3943 3541 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
@@ -3953,11 +3551,11 @@
3953 3551 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ),
3954 3552 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ),
3955 3553 'unsafe_params' => FrmFormsHelper::reserved_words(),
3956 3554 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
3957 - 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3555 + 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
3958 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. */
3959 - 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
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' ), '****' ),
3960 3558 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3961 3559 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3962 3560 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3963 3561 'install' => __( 'Install', 'formidable' ),
@@ -3978,14 +3576,11 @@
3978 3576 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
3979 3577 'noTitleText' => FrmFormsHelper::get_no_title_text(),
3980 3578
3981 3579 // In older versions this event listener causes the section to immediately close again
3982 - // When the h3 element is clicked. It's only required in WP 6.7+.
3580 + // when the h3 element is clicked. It's only required in WP 6.7+.
3983 3581 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ),
3984 3582 );
3985 -
3986 - self::add_form_builder_modal_data( $admin_script_strings );
3987 -
3988 3583 /**
3989 3584 * @param array $admin_script_strings
3990 3585 */
3991 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
@@ -3990,9 +3585,8 @@
3990 3585 */
3991 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3992 3587
3993 3588 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
3994 -
3995 3589 if ( ! $data ) {
3996 3590 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
3997 3591 }
3998 3592 }//end if
@@ -3998,86 +3592,8 @@
3998 3592 }//end if
3999 3593 }
4000 3594
4001 3595 /**
4002 - * @param array $admin_script_strings
4003 - *
4004 - * @return void
4005 - */
4006 - private static function add_form_builder_modal_data( &$admin_script_strings ) {
4007 - if ( ! self::is_form_builder_page() || self::pro_is_installed() ) {
4008 - return;
4009 - }
4010 -
4011 - $stripe_connected = FrmStrpLiteConnectHelper::at_least_one_mode_is_setup();
4012 - $square_connected = FrmSquareLiteConnectHelper::at_least_one_mode_is_setup();
4013 - $gateway_connected = $stripe_connected || $square_connected;
4014 - $payments_settings_url = FrmStrpLiteAppController::get_payments_settings_url();
4015 -
4016 - if ( ! $gateway_connected ) {
4017 - // This modal shows when user clicks on one of the pricing fields and no payment gateways configured.
4018 - $admin_script_strings['paymentsSettingsModal'] = array(
4019 - 'title' => __( 'Setup a Payment Gateway first', 'formidable' ),
4020 - 'msg' => __( 'To use the payment fields, please install and configure a payment gateway in your account settings.', 'formidable' ),
4021 - 'closeText' => __( 'Close', 'formidable' ),
4022 - 'actionUrl' => $payments_settings_url,
4023 - 'actionText' => __( 'Go to Payment Settings', 'formidable' ),
4024 - 'noCenter' => true,
4025 - );
4026 - }
4027 -
4028 - // This modal shows on load once after upgrading the plugin.
4029 - $show_pricing_fields_modal = get_option( 'frm_show_pricing_fields_modal' );
4030 -
4031 - if ( ! $show_pricing_fields_modal ) {
4032 - return;
4033 - }
4034 -
4035 - $admin_script_strings['pricingFieldsModal'] = array(
4036 - 'title' => esc_html__( 'Start Accepting Payments Today!', 'formidable' ),
4037 - 'img' => esc_url( self::plugin_url() . '/images/upsell/pricing-fields.png' ),
4038 - 'noCenter' => true,
4039 - );
4040 -
4041 - if ( $gateway_connected ) {
4042 - $gateway_texts = array();
4043 -
4044 - if ( $stripe_connected ) {
4045 - $gateway_texts['stripe'] = esc_html__( 'Stripe', 'formidable' );
4046 - }
4047 -
4048 - if ( $square_connected ) {
4049 - $gateway_texts['square'] = esc_html__( 'Square', 'formidable' );
4050 - }
4051 -
4052 - $admin_script_strings['pricingFieldsModal']['msg'] = sprintf(
4053 - // translators: %s: Stripe or Square.
4054 - esc_html__( 'You already have %s connected, so these have already been unlocked.', 'formidable' ),
4055 - esc_html( implode( ' ' . esc_html__( 'and', 'formidable' ) . ' ', $gateway_texts ) )
4056 - );
4057 - } else {
4058 - $admin_script_strings['pricingFieldsModal']['closeText'] = __( 'I\'ll do it later!', 'formidable' );
4059 - $admin_script_strings['pricingFieldsModal']['actionText'] = __( 'Setup Payments Now', 'formidable' );
4060 - $admin_script_strings['pricingFieldsModal']['actionUrl'] = $payments_settings_url;
4061 - // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4062 - $admin_script_strings['pricingFieldsModal']['msg'] = __( 'We\'ve unlocked Product, Quantity, and Total fields for Lite users! You can now transform your forms into checkout pages. To start collecting revenue, simply connect your preferred payment gateway (Stripe, or Square) in your settings.', 'formidable' );
4063 - }//end if
4064 -
4065 - delete_option( 'frm_show_pricing_fields_modal' );
4066 - }
4067 -
4068 - /**
4069 - * Get the no label text.
4070 - *
4071 - * @since 6.25.1
4072 - *
4073 - * @return string
4074 - */
4075 - public static function get_no_label_text() {
4076 - return __( '(no label)', 'formidable' );
4077 - }
4078 -
4079 - /**
4080 3596 * @since 6.5
4081 3597 *
4082 3598 * @return string
4083 3599 */
@@ -4119,9 +3635,8 @@
4119 3635 *
4120 3636 * @since 1.07.10
4121 3637 *
4122 3638 * @param float $min_version The version the add-on requires.
4123 - *
4124 3639 * @return void
4125 3640 */
4126 3641 public static function min_version_notice( $min_version ) {
4127 3642 $frm_version = self::plugin_version();
@@ -4131,11 +3646,11 @@
4131 3646 return;
4132 3647 }
4133 3648
4134 3649 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
4135 - echo '<tr class="plugin-update-tr active"><th colspan="' . absint( $wp_list_table->get_column_count() ) . '" class="check-column plugin-update colspanchange"><div class="update-message">' . // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4136 - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
4137 - '</div></td></tr>';
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>';
4138 3653 }
4139 3654
4140 3655 /**
4141 3656 * If Pro is far outdated, show a message.
@@ -4141,10 +3656,8 @@
4141 3656 * If Pro is far outdated, show a message.
4142 3657 *
4143 3658 * @since 4.0.01
4144 3659 *
4145 - * @param string $min_version
4146 - *
4147 3660 * @return void
4148 3661 */
4149 3662 public static function min_pro_version_notice( $min_version ) {
4150 3663 if ( ! self::is_formidable_admin() ) {
@@ -4154,14 +3667,25 @@
4154 3667
4155 3668 self::php_version_notice();
4156 3669
4157 3670 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
4158 -
4159 3671 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
4160 3672 return;
4161 3673 }
4162 3674
4163 - 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
4164 3688 }
4165 3689
4166 3690 /**
4167 3691 * If Pro is installed, check the version number.
@@ -4168,9 +3692,8 @@
4168 3692 *
4169 3693 * @since 4.0.01
4170 3694 *
4171 3695 * @param string $min_version
4172 - *
4173 3696 * @return bool
4174 3697 */
4175 3698 public static function meets_min_pro_version( $min_version ) {
4176 3699 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
@@ -4179,19 +3702,16 @@
4179 3702 /**
4180 3703 * Show a message if the PHP version is below the recommendations.
4181 3704 *
4182 3705 * @since 4.0.02
4183 - *
4184 3706 * @return void
4185 3707 */
4186 3708 private static function php_version_notice() {
4187 3709 $message = array();
4188 -
4189 3710 if ( version_compare( phpversion(), '7.0', '<' ) ) {
4190 - $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
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' );
4191 3712 }
4192 3713
4193 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4194 3714 foreach ( $message as $m ) {
4195 3715 ?>
4196 3716 <div class="frm-banner-alert frm_error_style frm_previous_install">
4197 3717 <?php echo esc_html( $m ); ?>
@@ -4197,14 +3717,12 @@
4197 3717 <?php echo esc_html( $m ); ?>
4198 3718 </div>
4199 3719 <?php
4200 3720 }
4201 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4202 3721 }
4203 3722
4204 3723 /**
4205 3724 * @param string $type
4206 - *
4207 3725 * @return array<string,string>
4208 3726 */
4209 3727 public static function locales( $type = 'date' ) {
4210 3728 $locales = array(
@@ -4298,12 +3816,12 @@
4298 3816 'zu' => __( 'Zulu', 'formidable' ),
4299 3817 );
4300 3818
4301 3819 if ( $type === 'captcha' ) {
4302 - // Remove the languages unavailable for the captcha
3820 + // remove the languages unavailable for the captcha
4303 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' );
4304 3822 } else {
4305 - // Remove the languages unavailable for the datepicker
3823 + // remove the languages unavailable for the datepicker
4306 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' );
4307 3825 }
4308 3826
4309 3827 $locales = array_diff_key( $locales, array_flip( $unset ) );
@@ -4314,13 +3832,14 @@
4314 3832 * @since 5.4.5 Added $args parameter with type.
4315 3833 *
4316 3834 * @param array<string,string> $locales
4317 3835 * @param array $args {
4318 - *
4319 3836 * @type string $type
4320 3837 * }
4321 3838 */
4322 - return apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3839 + $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3840 +
3841 + return $locales;
4323 3842 }
4324 3843
4325 3844 /**
4326 3845 * @return string
@@ -4327,14 +3846,12 @@
4327 3846 */
4328 3847 public static function get_menu_icon_class() {
4329 3848 if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
4330 3849 $settings = FrmProAppHelper::get_settings();
4331 -
4332 3850 if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
4333 3851 return $settings->menu_icon;
4334 3852 }
4335 3853 }
4336 -
4337 3854 return 'frmfont frm_logo_icon';
4338 3855 }
4339 3856
4340 3857 /**
@@ -4352,9 +3869,10 @@
4352 3869 * @type array $input_attrs Attributes of value input.
4353 3870 * }
4354 3871 */
4355 3872 public static function images_dropdown( $args ) {
4356 - $args = self::fill_default_images_dropdown_args( $args );
3873 + $args = self::fill_default_images_dropdown_args( $args );
3874 +
4357 3875 $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
4358 3876 ob_start();
4359 3877 include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
4360 3878 $output = ob_get_clean();
@@ -4375,9 +3893,8 @@
4375 3893 *
4376 3894 * @since 5.0.04
4377 3895 *
4378 3896 * @param array $args The arguments.
4379 - *
4380 3897 * @return array
4381 3898 */
4382 3899 private static function fill_default_images_dropdown_args( $args ) {
4383 3900 $defaults = array(
@@ -4390,8 +3907,14 @@
4390 3907
4391 3908 $new_args['options'] = (array) $new_args['options'];
4392 3909 $new_args['input_attrs'] = (array) $new_args['input_attrs'];
4393 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 +
4394 3917 /**
4395 3918 * Allows modifying the arguments of images_dropdown() method.
4396 3919 *
4397 3920 * @since 5.0.04
@@ -4407,9 +3930,8 @@
4407 3930 *
4408 3931 * @since 5.0.04
4409 3932 *
4410 3933 * @param array $args The arguments.
4411 - *
4412 3934 * @return string
4413 3935 */
4414 3936 private static function get_images_dropdown_input_attrs( $args ) {
4415 3937 $input_attrs = $args['input_attrs'];
@@ -4416,9 +3938,8 @@
4416 3938 $input_attrs['type'] = 'radio';
4417 3939 $input_attrs['name'] = $args['name'];
4418 3940
4419 3941 $input_attrs_str = '';
4420 -
4421 3942 foreach ( $input_attrs as $key => $input_attr ) {
4422 3943 $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
4423 3944 }
4424 3945
@@ -4434,13 +3955,8 @@
4434 3955 }
4435 3956
4436 3957 /**
4437 3958 * @since 6.7.1
4438 - *
4439 - * @param array $option Option data.
4440 - * @param array $args The arguments of images_dropdown() method.
4441 - *
4442 - * @return array
4443 3959 */
4444 3960 public static function get_images_dropdown_atts( $option, $args ) {
4445 3961 $image = self::get_images_dropdown_option_image( $option, $args );
4446 3962 $classes = self::get_images_dropdown_option_classes( $option, $args );
@@ -4454,9 +3970,8 @@
4454 3970 * @since 5.0.04
4455 3971 *
4456 3972 * @param array $option Option data.
4457 3973 * @param array $args The arguments of images_dropdown() method.
4458 - *
4459 3974 * @return string
4460 3975 */
4461 3976 private static function get_images_dropdown_option_image( $option, $args ) {
4462 3977 $image = self::icon_by_class(
@@ -4485,9 +4000,8 @@
4485 4000 * @since 5.0.04
4486 4001 *
4487 4002 * @param array $option Option data.
4488 4003 * @param array $args The arguments of images_dropdown() method.
4489 - *
4490 4004 * @return string
4491 4005 */
4492 4006 private static function get_images_dropdown_option_classes( $option, $args ) {
4493 4007 $classes = '';
@@ -4515,19 +4029,17 @@
4515 4029 * @since 5.0.04
4516 4030 *
4517 4031 * @param array $option Option data.
4518 4032 * @param array $args The arguments of images_dropdown() method.
4519 - *
4520 4033 * @return string
4521 4034 */
4522 4035 private static function get_images_dropdown_option_html_attrs( $option, $args ) {
4523 4036 $html_attrs = '';
4524 -
4525 4037 if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
4526 4038 $html_attrs_arr = array();
4527 4039
4528 4040 foreach ( $option['custom_attrs'] as $key => $value ) {
4529 - if ( in_array( $key, array( 'type', 'class', 'data-value' ), true ) ) {
4041 + if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
4530 4042 continue;
4531 4043 }
4532 4044
4533 4045 $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
@@ -4585,13 +4097,14 @@
4585 4097 * @since 5.0.07
4586 4098 *
4587 4099 * @param array $values
4588 4100 * @param array $keys
4589 - *
4590 4101 * @return array
4591 4102 */
4592 4103 public static function maybe_filter_array( $values, $keys ) {
4593 - if ( self::allow_unfiltered_html() ) {
4104 + $allow_unfiltered_html = self::allow_unfiltered_html();
4105 +
4106 + if ( $allow_unfiltered_html ) {
4594 4107 return $values;
4595 4108 }
4596 4109
4597 4110 foreach ( $keys as $key ) {
@@ -4610,14 +4123,13 @@
4610 4123 * @since 5.0.13
4611 4124 *
4612 4125 * @param string $value
4613 4126 * @param array|string $allowed 'all' for everything included as defaults.
4614 - *
4615 4127 * @return string
4616 4128 */
4617 4129 public static function maybe_kses( $value, $allowed = 'all' ) {
4618 4130 if ( self::should_never_allow_unfiltered_html() ) {
4619 - return self::kses( $value, $allowed );
4131 + $value = self::kses( $value, $allowed );
4620 4132 }
4621 4133 return $value;
4622 4134 }
4623 4135
@@ -4627,18 +4139,17 @@
4627 4139 * @since 6.11.2
4628 4140 *
4629 4141 * @param string $key
4630 4142 * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed.
4631 - *
4632 4143 * @return bool
4633 4144 */
4634 4145 public static function input_key_is_safe( $key, $context = 'display' ) {
4635 4146 if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) {
4636 4147 $safe = true;
4637 - } elseif ( str_starts_with( $key, 'data-' ) ) {
4148 + } elseif ( 0 === strpos( $key, 'data-' ) ) {
4638 4149 // Allow all data attributes.
4639 4150 $safe = true;
4640 - } elseif ( str_starts_with( $key, 'aria-' ) ) {
4151 + } elseif ( 0 === strpos( $key, 'aria-' ) ) {
4641 4152 // Allow all aria attributes.
4642 4153 $safe = true;
4643 4154 } else {
4644 4155 $safe_keys = array(
@@ -4680,9 +4191,16 @@
4680 4191
4681 4192 /**
4682 4193 * @since 5.0.16
4683 4194 *
4684 - * @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
4685 4203 *
4686 4204 * @return array
4687 4205 */
4688 4206 public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
@@ -4690,9 +4208,8 @@
4690 4208 'medium' => $medium,
4691 4209 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
4692 4210 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
4693 4211 'screenshot' => 'landing.png',
4694 - 'learn-more' => self::get_doc_url( 'landing-page-forms', 'form-landing-page-settings', false ),
4695 4212 );
4696 4213 return self::get_upgrade_data_params( 'landing', $params );
4697 4214 }
4698 4215
@@ -4699,9 +4216,8 @@
4699 4216 /**
4700 4217 * @since 5.0.17
4701 4218 *
4702 4219 * @param string $feature
4703 - *
4704 4220 * @return bool
4705 4221 */
4706 4222 public static function show_new_feature( $feature ) {
4707 4223 $link = FrmAddonsController::install_link( $feature );
@@ -4708,21 +4224,16 @@
4708 4224 return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
4709 4225 }
4710 4226
4711 4227 /**
4712 - * Enhances upgrade data parameters with installation link and plan requirement information.
4713 - *
4714 4228 * @since 5.0.17
4715 4229 *
4716 - * @param string $plugin The plugin slug to get installation data for.
4717 - * @param array $params Initial parameters for the upgrade data.
4718 - * @param bool $detailed Whether to include detailed information.
4719 - *
4720 - * @return array Modified parameters with installation data.
4230 + * @param string $plugin
4231 + * @param array $params
4232 + * @return array
4721 4233 */
4722 - public static function get_upgrade_data_params( $plugin, $params, $detailed = false ) {
4234 + public static function get_upgrade_data_params( $plugin, $params ) {
4723 4235 $link = FrmAddonsController::install_link( $plugin );
4724 -
4725 4236 if ( ! $link ) {
4726 4237 return $params;
4727 4238 }
4728 4239
@@ -4728,20 +4239,15 @@
4728 4239
4729 4240 if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
4730 4241 $params['oneclick'] = json_encode( $link );
4731 4242 unset( $params['message'] );
4732 -
4733 4243 if ( ! isset( $params['medium'] ) ) {
4734 4244 $params['medium'] = $plugin;
4735 4245 }
4736 4246 } else {
4737 - $params['requires'] = $params['requires'] ?? FrmFormsHelper::get_plan_required( $link );
4247 + $params['requires'] = FrmFormsHelper::get_plan_required( $link );
4738 4248 }
4739 4249
4740 - if ( $detailed ) {
4741 - $params['plugin-status'] = $link['status'] ?? '';
4742 - }
4743 -
4744 4250 return $params;
4745 4251 }
4746 4252
4747 4253 /**
@@ -4750,9 +4256,8 @@
4750 4256 *
4751 4257 * @since 5.0.17
4752 4258 *
4753 4259 * @param string $text
4754 - *
4755 4260 * @return bool
4756 4261 */
4757 4262 public static function ctype_xdigit( $text ) {
4758 4263 if ( function_exists( 'ctype_xdigit' ) ) {
@@ -4767,14 +4272,12 @@
4767 4272 * @since 5.2.01
4768 4273 */
4769 4274 public static function set_current_screen_and_hook_suffix() {
4770 4275 global $hook_suffix;
4771 -
4772 4276 if ( is_null( $hook_suffix ) ) {
4773 4277 // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
4774 4278 $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
4775 4279 }
4776 -
4777 4280 set_current_screen();
4778 4281 }
4779 4282
4780 4283 /**
@@ -4781,9 +4284,9 @@
4781 4284 * Shows pill text.
4782 4285 *
4783 4286 * @since 5.2.02
4784 4287 *
4785 - * @param string|null $text Text in the pill. Default is NEW.
4288 + * @param string $text Text in the pill. Default is NEW.
4786 4289 */
4787 4290 public static function show_pill_text( $text = null ) {
4788 4291 if ( null === $text ) {
4789 4292 $text = __( 'NEW', 'formidable' );
@@ -4796,9 +4299,8 @@
4796 4299 *
4797 4300 * @since 5.2.07
4798 4301 *
4799 4302 * @param mixed $num Number.
4800 - *
4801 4303 * @return false|int Returns `false` if the passed parameter is not number.
4802 4304 */
4803 4305 public static function count_decimals( $num ) {
4804 4306 if ( ! is_numeric( $num ) ) {
@@ -4806,9 +4308,8 @@
4806 4308 }
4807 4309
4808 4310 $num = (string) $num;
4809 4311 $parts = explode( '.', $num );
4810 -
4811 4312 if ( 1 === count( $parts ) ) {
4812 4313 return 0;
4813 4314 }
4814 4315
@@ -4890,20 +4391,17 @@
4890 4391 * @since 5.5.5
4891 4392 *
4892 4393 * @param string $url
4893 4394 * @param string $expected_extension
4894 - *
4895 4395 * @return bool
4896 4396 */
4897 4397 public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
4898 - $file_is_in_expected_s3_bucket = str_starts_with( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4899 -
4398 + $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4900 4399 if ( ! $file_is_in_expected_s3_bucket ) {
4901 4400 return false;
4902 4401 }
4903 4402
4904 4403 $parsed = parse_url( $url );
4905 -
4906 4404 if ( ! is_array( $parsed ) ) {
4907 4405 // URL is malformed.
4908 4406 return false;
4909 4407 }
@@ -4909,10 +4407,14 @@
4909 4407 }
4910 4408
4911 4409 $path = $parsed['path'];
4912 4410 $ext = pathinfo( $path, PATHINFO_EXTENSION );
4913 - // The URL isn't to an XML file.
4914 - 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;
4915 4417 }
4916 4418
4917 4419 /**
4918 4420 * Display a dismissable warning message and save its dismissal state.
@@ -4920,9 +4422,8 @@
4920 4422 * @since 6.3
4921 4423 *
4922 4424 * @param string $message The warning message to display.
4923 4425 * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
4924 - *
4925 4426 * @return void
4926 4427 */
4927 4428 public static function add_dismissable_warning_message( $message = '', $option = '' ) {
4928 4429 if ( ! $message || ! $option ) {
@@ -4965,9 +4466,8 @@
4965 4466 *
4966 4467 * @since 6.3
4967 4468 *
4968 4469 * @param string $option The unique identifier for the dismissal state of the message.
4969 - *
4970 4470 * @return void
4971 4471 */
4972 4472 public static function dismiss_warning_message( $option = '' ) {
4973 4473 self::permission_check( 'frm_change_settings' );
@@ -4973,9 +4473,9 @@
4973 4473 self::permission_check( 'frm_change_settings' );
4974 4474 check_ajax_referer( 'frm_ajax', 'nonce' );
4975 4475
4976 4476 if ( $option ) {
4977 - update_option( $option, true, false );
4477 + update_option( $option, true, 'no' );
4978 4478 }
4979 4479
4980 4480 wp_send_json_success();
4981 4481 }
@@ -4989,8 +4489,17 @@
4989 4489 * @return string
4990 4490 */
4991 4491 public static function copy_for_lite_license() {
4992 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 +
4993 4502 return apply_filters( 'frm_license_type_text', $message );
4994 4503 }
4995 4504
4996 4505 /**
@@ -4996,9 +4505,8 @@
4996 4505 /**
4997 4506 * Removes scripts that are unnecessarily loaded across the pages!
4998 4507 *
4999 4508 * @since 6.9
5000 - *
5001 4509 * @return void
5002 4510 */
5003 4511 public static function dequeue_extra_global_scripts() {
5004 4512 wp_dequeue_script( 'frm-surveys-admin' );
@@ -5016,21 +4524,18 @@
5016 4524 * @return void
5017 4525 */
5018 4526 public static function tooltip_icon( $tooltip_text, $atts = array() ) {
5019 4527 $atts['title'] = $tooltip_text;
5020 -
5021 4528 if ( isset( $atts['class'] ) ) {
5022 4529 $atts['class'] .= ' frm_help';
5023 4530 } else {
5024 4531 $atts['class'] = 'frm_help';
5025 4532 }
5026 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5027 4533 ?>
5028 4534 <span <?php self::array_to_html_params( $atts, true ); ?>>
5029 4535 <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?>
5030 4536 </span>
5031 4537 <?php
5032 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5033 4538 }
5034 4539
5035 4540 /**
5036 4541 * Prints errors for settings in onboarding wizard or template settings.
@@ -5051,10 +4556,8 @@
5051 4556 )
5052 4557 );
5053 4558
5054 4559 $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden';
5055 -
5056 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5057 4560 ?>
5058 4561 <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>">
5059 4562 <?php
5060 4563 if ( is_array( $args['errors'] ) ) {
@@ -5068,9 +4571,8 @@
5068 4571 }
5069 4572 ?>
5070 4573 </span>
5071 4574 <?php
5072 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5073 4575 }
5074 4576
5075 4577 /**
5076 4578 * Check if GDPR is enabled.
@@ -5093,57 +4595,6 @@
5093 4595 */
5094 4596 public static function no_gdpr_cookies() {
5095 4597 $frm_settings = self::get_settings();
5096 4598 return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies;
5097 - }
5098 -
5099 - /**
5100 - * Check if a string is valid UTF-8.
5101 - *
5102 - * @since 6.24
5103 - *
5104 - * @param string $string The string to check.
5105 - *
5106 - * @return bool
5107 - */
5108 - public static function is_valid_utf8( $string ) {
5109 - // wp_is_valid_utf8 is added in WP 6.9.
5110 - if ( function_exists( 'wp_is_valid_utf8' ) ) {
5111 - return wp_is_valid_utf8( $string );
5112 - }
5113 -
5114 - // As of WP 6.9, seems_utf8 is deprecated.
5115 - return function_exists( 'seems_utf8' ) ? seems_utf8( $string ) : false;
5116 - }
5117 -
5118 - /**
5119 - * Get a documentation URL with UTM parameters and affiliate tracking.
5120 - *
5121 - * @since 6.26
5122 - *
5123 - * @param string $path The relative path to append to the base URL.
5124 - * @param string $campaign The campaign to use for UTM parameters.
5125 - * @param bool $add_kb_base Whether to prepend 'knowledgebase/' to the path. Default true.
5126 - *
5127 - * @return string The processed URL with UTM parameters and affiliate tracking.
5128 - */
5129 - public static function get_doc_url( $path, $campaign, $add_kb_base = true ) {
5130 - $path = trim( $path, '/' );
5131 -
5132 - if ( $add_kb_base ) {
5133 - $path = 'knowledgebase/' . $path;
5134 - }
5135 -
5136 - return self::maybe_add_missing_utm( 'https://formidableforms.com/' . $path, array( 'campaign' => $campaign ) );
5137 - }
5138 -
5139 - /**
5140 - * @since 5.0.16
5141 - * @deprecated 6.26
5142 - *
5143 - * @return bool
5144 - */
5145 - public static function show_landing_pages() {
5146 - _deprecated_function( __METHOD__, '6.26' );
5147 - return true;
5148 4599 }
5149 4600 }