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