PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.16.1
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.16.1
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/helpers/FrmAppHelper.php +436 -1224 6.336.16.1 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 = 106;
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.33';
36 + public static $plug_version = '6.16.1';
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,31 @@
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',
1370 + $upgrade_link = self::admin_upgrade_link(
1371 + array(
1372 + 'medium' => 'settings-license',
1373 + 'content' => 'lite-banner',
1374 + )
1627 1375 );
1628 -
1629 - $upgrade_link = $upgrade_link ? self::maybe_add_missing_utm( $upgrade_link, $utm ) : self::admin_upgrade_link( $utm );
1630 -
1631 1376 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' ),
1377 + /* translators: %1$s: Start link HTML, %2$s: End link HTML */
1378 + esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$supgrading to PRO%2$s.', 'formidable' ),
1634 1379 '<a href="' . esc_url( $upgrade_link ) . '">',
1635 - esc_html( $cta_text ),
1636 1380 '</a>'
1637 1381 );
1638 1382 ?>
1639 - </div>
1640 1383 </div>
1641 1384 <?php
1642 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1643 1385 }
1644 1386
1645 1387 /**
1646 1388 * @since 5.4.2
@@ -1654,9 +1396,8 @@
1654 1396 /**
1655 1397 * Render a button for a new item (Form, Application, etc).
1656 1398 *
1657 1399 * @since 3.0
1658 - *
1659 1400 * @param array $atts {
1660 1401 * Details about the button.
1661 1402 *
1662 1403 * @type array $link_hook Custom link hook, calls do_action and exits early.
@@ -1663,9 +1404,8 @@
1663 1404 * @type string $new_link Href value, default #.
1664 1405 * @type string $class Custom class names, space separated.
1665 1406 * @type string $button_text Button text. Default "Add New".
1666 1407 * }
1667 - *
1668 1408 * @return void
1669 1409 */
1670 1410 public static function add_new_item_link( $atts ) {
1671 1411 if ( isset( $atts['link_hook'] ) ) {
@@ -1691,12 +1431,8 @@
1691 1431 }
1692 1432
1693 1433 /**
1694 1434 * @since 3.06
1695 - *
1696 - * @param array $atts
1697 - *
1698 - * @return void
1699 1435 */
1700 1436 public static function show_search_box( $atts ) {
1701 1437 $defaults = array(
1702 1438 'placeholder' => '',
@@ -1703,9 +1439,8 @@
1703 1439 'tosearch' => '',
1704 1440 'text' => __( 'Search', 'formidable' ),
1705 1441 'input_id' => '',
1706 1442 'value' => false,
1707 - 'class' => '',
1708 1443 );
1709 1444 $atts = array_merge( $defaults, $atts );
1710 1445
1711 1446 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
@@ -1712,9 +1447,8 @@
1712 1447 $atts['tosearch'] = 'frm-card';
1713 1448 }
1714 1449
1715 1450 $class = 'frm-search-input';
1716 -
1717 1451 if ( ! empty( $atts['tosearch'] ) ) {
1718 1452 $class .= ' frm-auto-search';
1719 1453 }
1720 1454
@@ -1738,15 +1472,14 @@
1738 1472
1739 1473 if ( ! empty( $atts['tosearch'] ) ) {
1740 1474 $input_atts['autocomplete'] = 'off';
1741 1475 }
1742 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1743 1476 ?>
1744 - <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>">
1477 + <p class="frm-search">
1745 1478 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
1746 1479 <?php echo esc_html( $atts['text'] ); ?>:
1747 1480 </label>
1748 - <?php self::icon_by_class( 'frmfont frm_search_icon frm_svg20' ); ?>
1481 + <span class="frmfont frm_search_icon"></span>
1749 1482 <input <?php self::array_to_html_params( $input_atts, true ); ?> />
1750 1483 <?php
1751 1484 if ( empty( $atts['tosearch'] ) ) {
1752 1485 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
@@ -1753,21 +1486,17 @@
1753 1486 }
1754 1487 ?>
1755 1488 </p>
1756 1489 <?php
1757 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1758 1490 }
1759 1491
1760 1492 /**
1761 - * @param string $type Hook type slug.
1762 - * @param object|null $object Optional related object.
1763 - *
1493 + * @param string $type
1764 1494 * @return void
1765 1495 */
1766 1496 public static function trigger_hook_load( $type, $object = null ) {
1767 1497 // Only load the form hooks once.
1768 1498 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
1769 -
1770 1499 if ( ! $hooks_loaded ) {
1771 1500 do_action( 'frm_load_' . $type . '_hooks' );
1772 1501 }
1773 1502 }
@@ -1826,14 +1555,14 @@
1826 1555 * True when value is 1, true, 'true', 'yes'
1827 1556 *
1828 1557 * @since 1.07.10
1829 1558 *
1830 - * @param bool|int|string $value The value to compare.
1559 + * @param string $value The value to compare.
1831 1560 *
1832 1561 * @return bool
1833 1562 */
1834 1563 public static function is_true( $value ) {
1835 - return true === $value || '1' === (string) $value || 'true' === $value || 'yes' === $value;
1564 + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value;
1836 1565 }
1837 1566
1838 1567 /**
1839 1568 * Gets all post from a specific post type.
@@ -1841,9 +1570,8 @@
1841 1570 *
1842 1571 * @since 4.10.01 Add `$post_type` argument.
1843 1572 *
1844 1573 * @param string $post_type Post type to query. Default is `page`.
1845 - *
1846 1574 * @return WP_Post[]
1847 1575 */
1848 1576 public static function get_pages( $post_type = 'page' ) {
1849 1577 $query = array(
@@ -1862,9 +1590,8 @@
1862 1590 *
1863 1591 * @since 5.0.09
1864 1592 *
1865 1593 * @param string $post_type Post type to query. Default is `page`.
1866 - *
1867 1594 * @return array
1868 1595 */
1869 1596 public static function get_post_ids_and_titles( $post_type = 'page' ) {
1870 1597 return FrmDb::get_results(
@@ -1889,12 +1616,13 @@
1889 1616 *
1890 1617 * @param array $args Selection arguments.
1891 1618 */
1892 1619 public static function maybe_autocomplete_pages_options( $args ) {
1893 - $args = self::preformat_selection_args( $args );
1620 + $args = self::preformat_selection_args( $args );
1621 +
1894 1622 $pages_count = wp_count_posts( $args['post_type'] );
1895 1623
1896 - if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) {
1624 + if ( $pages_count->publish <= 50 ) {
1897 1625 self::wp_pages_dropdown( $args );
1898 1626 return;
1899 1627 }
1900 1628
@@ -1918,109 +1646,8 @@
1918 1646 <?php
1919 1647 }
1920 1648
1921 1649 /**
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 1650 * @param array $args
2024 1651 * @param string $page_id Deprecated.
2025 1652 * @param bool $truncate Deprecated.
2026 1653 */
@@ -2028,9 +1655,9 @@
2028 1655 self::prep_page_dropdown_params( $page_id, $truncate, $args );
2029 1656
2030 1657 $pages = self::get_post_ids_and_titles( $args['post_type'] );
2031 1658 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
2032 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1659 +
2033 1660 ?>
2034 1661 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
2035 1662 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
2036 1663 <?php foreach ( $pages as $page ) { ?>
@@ -2039,9 +1666,8 @@
2039 1666 </option>
2040 1667 <?php } ?>
2041 1668 </select>
2042 1669 <?php
2043 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2044 1670 }
2045 1671
2046 1672 /**
2047 1673 * Fill in missing parameters passed to wp_pages_dropdown().
@@ -2047,14 +1673,8 @@
2047 1673 * Fill in missing parameters passed to wp_pages_dropdown().
2048 1674 * This is for reverse compatibility with switching 3 params to 1.
2049 1675 *
2050 1676 * @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 1677 */
2058 1678 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
2059 1679 if ( ! is_array( $args ) ) {
2060 1680 $args = array(
@@ -2071,12 +1691,8 @@
2071 1691 * Filter to format args for page dropdown or autocomplete
2072 1692 *
2073 1693 * @since 4.03.06
2074 1694 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
2075 - *
2076 - * @param array $args
2077 - *
2078 - * @return array
2079 1695 */
2080 1696 private static function preformat_selection_args( $args ) {
2081 1697 $defaults = array(
2082 1698 'truncate' => false,
@@ -2089,18 +1705,13 @@
2089 1705
2090 1706 return array_merge( $defaults, $args );
2091 1707 }
2092 1708
2093 - /**
2094 - * @param int $post_id
2095 - *
2096 - * @return string
2097 - */
2098 1709 public static function post_edit_link( $post_id ) {
2099 1710 $post = get_post( $post_id );
2100 -
2101 1711 if ( $post ) {
2102 1712 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1713 +
2103 1714 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
2104 1715 }
2105 1716
2106 1717 return '';
@@ -2113,9 +1724,11 @@
2113 1724 *
2114 1725 * @return bool
2115 1726 */
2116 1727 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();
1728 + return self::is_form_builder_page() ||
1729 + self::is_style_editor_page() ||
1730 + self::is_full_screen_view_builder_page();
2118 1731 }
2119 1732
2120 1733 /**
2121 1734 * Check if user is on the style editor or its alternative URL.
@@ -2125,9 +1738,8 @@
2125 1738 * @since 5.5.3
2126 1739 * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
2127 1740 *
2128 1741 * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
2129 - *
2130 1742 * @return bool
2131 1743 */
2132 1744 public static function is_style_editor_page( $view = '' ) {
2133 1745 if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
@@ -2164,9 +1776,8 @@
2164 1776 * @param array|string $capability
2165 1777 * @param string $multiple 'single' and 'multiple'.
2166 1778 */
2167 1779 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
2168 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2169 1780 ?>
2170 1781 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
2171 1782 <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?>
2172 1783 class="frm_multiselect">
@@ -2172,14 +1783,12 @@
2172 1783 class="frm_multiselect">
2173 1784 <?php self::roles_options( $capability ); ?>
2174 1785 </select>
2175 1786 <?php
2176 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2177 1787 }
2178 1788
2179 1789 /**
2180 1790 * @since 4.07
2181 - *
2182 1791 * @param array|string $selected
2183 1792 * @param string $current
2184 1793 */
2185 1794 private static function selected( $selected, $current ) {
@@ -2194,9 +1803,8 @@
2194 1803 * @param array|string $capability
2195 1804 */
2196 1805 public static function roles_options( $capability ) {
2197 1806 global $frm_vars;
2198 -
2199 1807 if ( isset( $frm_vars['editable_roles'] ) ) {
2200 1808 $editable_roles = $frm_vars['editable_roles'];
2201 1809 } else {
2202 1810 $editable_roles = get_editable_roles();
@@ -2205,9 +1813,9 @@
2205 1813
2206 1814 foreach ( $editable_roles as $role => $details ) {
2207 1815 $name = translate_user_role( $details['name'] );
2208 1816 ?>
2209 - <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?></option>
1817 + <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?> </option>
2210 1818 <?php
2211 1819 unset( $role, $details );
2212 1820 }
2213 1821 }
@@ -2217,9 +1825,8 @@
2217 1825 *
2218 1826 * @since 5.0 Parameter `$type` supports `pro_only` value.
2219 1827 *
2220 1828 * @param string $type Supports `auto`, `pro`, or `pro_only`.
2221 - *
2222 1829 * @return array
2223 1830 */
2224 1831 public static function frm_capabilities( $type = 'auto' ) {
2225 1832 if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
@@ -2237,8 +1844,14 @@
2237 1844 * @param array<string,string> $pro_cap
2238 1845 */
2239 1846 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
2240 1847
1848 + if ( ! array_key_exists( 'frm_edit_displays', $pro_cap ) && is_callable( 'FrmProAppHelper::views_is_installed' ) && FrmProAppHelper::views_is_installed() ) {
1849 + // For backward compatibility, add the Add/Edit Views permission if Pro is not up to date.
1850 + // This was added in 6.5.4. Remove this in the future.
1851 + $pro_cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
1852 + }
1853 +
2241 1854 if ( 'pro_only' === $type ) {
2242 1855 return $pro_cap;
2243 1856 }
2244 1857
@@ -2284,18 +1897,21 @@
2284 1897 if ( $role === 'loggedin' || ! $role ) {
2285 1898 return is_user_logged_in();
2286 1899 }
2287 1900
2288 - if ( (int) $role === 1 ) {
1901 + if ( $role == 1 ) {
2289 1902 $role = 'administrator';
2290 1903 }
2291 1904
2292 - return is_user_logged_in() ? current_user_can( $role ) : false;
1905 + if ( ! is_user_logged_in() ) {
1906 + return false;
1907 + }
1908 +
1909 + return current_user_can( $role );
2293 1910 }
2294 1911
2295 1912 /**
2296 1913 * @param array|string $needed_role
2297 - *
2298 1914 * @return bool
2299 1915 */
2300 1916 public static function user_has_permission( $needed_role ) {
2301 1917 if ( is_array( $needed_role ) ) {
@@ -2309,20 +1925,18 @@
2309 1925 }
2310 1926
2311 1927 $can = self::current_user_can( $needed_role );
2312 1928
2313 - if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ), true ) ) {
1929 + if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
2314 1930 return $can;
2315 1931 }
2316 1932
2317 1933 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
2318 -
2319 1934 foreach ( $roles as $role ) {
2320 1935 if ( current_user_can( $role ) ) {
2321 1936 return true;
2322 1937 }
2323 -
2324 - if ( $role === $needed_role ) {
1938 + if ( $role == $needed_role ) {
2325 1939 break;
2326 1940 }
2327 1941 }
2328 1942
@@ -2340,11 +1954,11 @@
2340 1954 if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
2341 1955 return;
2342 1956 }
2343 1957
2344 - $user = new WP_User( get_current_user_id() );
1958 + $user_id = get_current_user_id();
1959 + $user = new WP_User( $user_id );
2345 1960 $frm_roles = self::frm_capabilities();
2346 -
2347 1961 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2348 1962 $user->add_cap( $frm_role );
2349 1963 unset( $frm_role, $frm_role_description );
2350 1964 }
@@ -2355,22 +1969,18 @@
2355 1969 *
2356 1970 * @since 2.0.6
2357 1971 *
2358 1972 * @param string $cap
2359 - *
2360 1973 * @return void
2361 1974 */
2362 1975 public static function force_capability( $cap = 'frm_change_settings' ) {
2363 - if ( ! current_user_can( 'administrator' ) || current_user_can( $cap ) ) {
2364 - return;
1976 + if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
1977 + $role = get_role( 'administrator' );
1978 + $frm_roles = self::frm_capabilities();
1979 + foreach ( $frm_roles as $frm_role => $frm_role_description ) {
1980 + $role->add_cap( $frm_role );
1981 + }
2365 1982 }
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 1983 }
2374 1984
2375 1985 /**
2376 1986 * Check if the user has permission for action.
@@ -2378,22 +1988,17 @@
2378 1988 *
2379 1989 * @since 2.0
2380 1990 *
2381 1991 * @param string $permission
2382 - * @param string $show_message
2383 1992 */
2384 1993 public static function permission_check( $permission, $show_message = 'show' ) {
2385 1994 $permission_error = self::permission_nonce_error( $permission );
2386 -
2387 - if ( $permission_error === false ) {
2388 - return;
1995 + if ( $permission_error !== false ) {
1996 + if ( 'hide' == $show_message ) {
1997 + $permission_error = '';
1998 + }
1999 + wp_die( esc_html( $permission_error ) );
2389 2000 }
2390 -
2391 - if ( 'hide' === $show_message ) {
2392 - $permission_error = '';
2393 - }
2394 -
2395 - wp_die( esc_html( $permission_error ) );
2396 2001 }
2397 2002
2398 2003 /**
2399 2004 * Check user permission and nonce
@@ -2400,27 +2005,24 @@
2400 2005 *
2401 2006 * @since 2.0
2402 2007 *
2403 2008 * @param string $permission
2404 - * @param string $nonce_name
2405 - * @param string $nonce
2406 2009 *
2407 2010 * @return false|string The permission message or false if allowed
2408 2011 */
2409 2012 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
2410 - if ( $permission && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2013 + if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2411 2014 $frm_settings = self::get_settings();
2015 +
2412 2016 return $frm_settings->admin_permission;
2413 2017 }
2414 2018
2415 2019 $error = false;
2416 -
2417 - if ( ! $nonce_name ) {
2020 + if ( empty( $nonce_name ) ) {
2418 2021 return $error;
2419 2022 }
2420 2023
2421 2024 $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
2422 -
2423 2025 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
2424 2026 $frm_settings = self::get_settings();
2425 2027 $error = $frm_settings->admin_permission;
2426 2028 }
@@ -2427,14 +2029,8 @@
2427 2029
2428 2030 return $error;
2429 2031 }
2430 2032
2431 - /**
2432 - * @param array|string $values
2433 - * @param string $current
2434 - *
2435 - * @return void
2436 - */
2437 2033 public static function checked( $values, $current ) {
2438 2034 if ( self::check_selected( $values, $current ) ) {
2439 2035 echo ' checked="checked"';
2440 2036 }
@@ -2439,47 +2035,38 @@
2439 2035 echo ' checked="checked"';
2440 2036 }
2441 2037 }
2442 2038
2443 - /**
2444 - * @param array|string $values
2445 - * @param string|null $current
2446 - *
2447 - * @return bool
2448 - */
2449 2039 public static function check_selected( $values, $current ) {
2450 - $values = self::recursive_function_map( $values, 'trim' );
2451 - $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2040 + $values = self::recursive_function_map( $values, 'trim' );
2041 + $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2042 +
2452 2043 $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) );
2453 2044
2454 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons
2455 - return is_array( $values ) ? in_array( $current, $values ) : $values == $current;
2045 + return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
2456 2046 }
2457 2047
2458 - /**
2459 - * @param array|string $value
2460 - * @param callable|string $function
2461 - *
2462 - * @return array|string
2463 - */
2464 2048 public static function recursive_function_map( $value, $function ) {
2465 2049 if ( is_array( $value ) ) {
2466 2050 $original_function = $function;
2467 - $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function );
2468 -
2469 - if ( self::is_assoc( $value ) ) {
2051 + if ( count( $value ) ) {
2052 + $function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
2053 + } else {
2054 + $function = array( $function );
2055 + }
2056 + if ( ! self::is_assoc( $value ) ) {
2057 + $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2058 + } else {
2470 2059 foreach ( $value as $k => $v ) {
2471 2060 if ( ! is_array( $v ) ) {
2472 2061 $value[ $k ] = call_user_func( $original_function, $v );
2473 2062 }
2474 2063 }
2475 - } else {
2476 - $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2477 2064 }
2478 2065 } else {
2479 2066 $value = self::maybe_update_value_if_null( $value, $function );
2480 2067 $value = call_user_func( $function, $value );
2481 - }//end if
2068 + }
2482 2069
2483 2070 return $value;
2484 2071 }
2485 2072
@@ -2486,27 +2073,20 @@
2486 2073 /**
2487 2074 * Updates value to empty string if it is null and being passed to a string function.
2488 2075 *
2489 2076 * @since 6.8.4
2490 - *
2491 2077 * @param mixed $value
2492 2078 * @param string $function
2493 - *
2494 2079 * @return mixed
2495 2080 */
2496 2081 private static function maybe_update_value_if_null( $value, $function ) {
2497 2082 if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) {
2498 - return '';
2083 + $value = '';
2499 2084 }
2500 2085
2501 2086 return $value;
2502 2087 }
2503 2088
2504 - /**
2505 - * @param array $array
2506 - *
2507 - * @return bool
2508 - */
2509 2089 public static function is_assoc( $array ) {
2510 2090 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
2511 2091 }
2512 2092
@@ -2511,22 +2091,16 @@
2511 2091 }
2512 2092
2513 2093 /**
2514 2094 * Flatten a multi-dimensional array
2515 - *
2516 - * @param array $array
2517 - * @param string $keys
2518 - *
2519 - * @return array
2520 2095 */
2521 2096 public static function array_flatten( $array, $keys = 'keep' ) {
2522 2097 $return = array();
2523 -
2524 2098 foreach ( $array as $key => $value ) {
2525 2099 if ( is_array( $value ) ) {
2526 2100 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
2527 2101 } elseif ( $keys === 'keep' ) {
2528 - $return[ $key ] = $value;
2102 + $return[ $key ] = $value;
2529 2103 } else {
2530 2104 $return[] = $value;
2531 2105 }
2532 2106 }
@@ -2540,9 +2114,8 @@
2540 2114 * @since 6.16.1
2541 2115 *
2542 2116 * @param string $sep
2543 2117 * @param array $array
2544 - *
2545 2118 * @return string
2546 2119 */
2547 2120 public static function safe_implode( $sep, $array ) {
2548 2121 $array = self::array_flatten( $array );
@@ -2551,18 +2124,15 @@
2551 2124
2552 2125 /**
2553 2126 * @param string $text
2554 2127 * @param bool $is_rich_text
2555 - *
2556 2128 * @return string
2557 2129 */
2558 2130 public static function esc_textarea( $text, $is_rich_text = false ) {
2559 2131 $safe_text = str_replace( '&quot;', '"', $text );
2560 -
2561 2132 if ( ! $is_rich_text ) {
2562 2133 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
2563 2134 }
2564 -
2565 2135 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
2566 2136
2567 2137 /**
2568 2138 * @param string $safe_text
@@ -2574,59 +2144,44 @@
2574 2144 /**
2575 2145 * Add auto paragraphs to text areas
2576 2146 *
2577 2147 * @since 2.0
2578 - *
2579 - * @param mixed $content
2580 - *
2581 - * @return mixed
2582 2148 */
2583 2149 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 ) );
2150 + if ( apply_filters( 'frm_use_wpautop', true ) && ! is_array( $content ) ) {
2151 + $content = wpautop( str_replace( '<br>', '<br />', $content ) );
2586 2152 }
2587 2153
2588 2154 return $content;
2589 2155 }
2590 2156
2591 - /**
2592 - * Replace quotes with their HTML entities.
2593 - *
2594 - * @param string $val
2595 - *
2596 - * @return string
2597 - */
2598 2157 public static function replace_quotes( $val ) {
2599 2158 // Replace double quotes.
2600 2159 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
2601 2160
2602 2161 // Replace single quotes.
2603 - return str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2162 + $val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2163 +
2164 + return $val;
2604 2165 }
2605 2166
2606 2167 /**
2607 - * @param string $handle
2608 - * @param int|string $default
2609 - *
2610 - * @return int|string
2168 + * @param string $handle
2611 2169 */
2612 2170 public static function script_version( $handle, $default = 0 ) {
2613 2171 global $wp_scripts;
2614 -
2615 2172 if ( ! $wp_scripts ) {
2616 2173 return $default;
2617 2174 }
2618 2175
2619 2176 $ver = $default;
2620 -
2621 2177 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
2622 2178 return $ver;
2623 2179 }
2624 2180
2625 2181 $query = $wp_scripts->registered[ $handle ];
2626 -
2627 2182 if ( is_object( $query ) && ! empty( $query->ver ) ) {
2628 - return $query->ver;
2183 + $ver = $query->ver;
2629 2184 }
2630 2185
2631 2186 return $ver;
2632 2187 }
@@ -2635,9 +2190,8 @@
2635 2190 * @since 5.0.13 added $echo param.
2636 2191 *
2637 2192 * @param string $url
2638 2193 * @param bool $echo
2639 - *
2640 2194 * @return string|null
2641 2195 */
2642 2196 public static function js_redirect( $url, $echo = false ) {
2643 2197 $callback = function () use ( $url ) {
@@ -2645,13 +2199,8 @@
2645 2199 };
2646 2200 return self::clip( $callback, $echo );
2647 2201 }
2648 2202
2649 - /**
2650 - * @param int|string $user_id
2651 - *
2652 - * @return int|string
2653 - */
2654 2203 public static function get_user_id_param( $user_id ) {
2655 2204 if ( ! $user_id || is_numeric( $user_id ) ) {
2656 2205 return $user_id;
2657 2206 }
@@ -2656,13 +2205,16 @@
2656 2205 return $user_id;
2657 2206 }
2658 2207
2659 2208 $user_id = sanitize_text_field( $user_id );
2660 -
2661 2209 if ( $user_id === 'current' ) {
2662 2210 $user_id = get_current_user_id();
2663 2211 } else {
2664 - $user = is_email( $user_id ) ? get_user_by( 'email', $user_id ) : get_user_by( 'login', $user_id );
2212 + if ( is_email( $user_id ) ) {
2213 + $user = get_user_by( 'email', $user_id );
2214 + } else {
2215 + $user = get_user_by( 'login', $user_id );
2216 + }
2665 2217
2666 2218 if ( $user ) {
2667 2219 $user_id = $user->ID;
2668 2220 }
@@ -2674,9 +2226,8 @@
2674 2226
2675 2227 /**
2676 2228 * @param string $filename
2677 2229 * @param array $atts
2678 - *
2679 2230 * @return false|string
2680 2231 */
2681 2232 public static function get_file_contents( $filename, $atts = array() ) {
2682 2233 if ( ! is_file( $filename ) ) {
@@ -2685,9 +2236,12 @@
2685 2236
2686 2237 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
2687 2238 ob_start();
2688 2239 include $filename;
2689 - return ob_get_clean();
2240 + $contents = ob_get_contents();
2241 + ob_end_clean();
2242 +
2243 + return $contents;
2690 2244 }
2691 2245
2692 2246 /**
2693 2247 * @param string $name
@@ -2697,9 +2251,8 @@
2697 2251 * @param int $num_chars
2698 2252 */
2699 2253 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
2700 2254 $key = '';
2701 -
2702 2255 if ( $name ) {
2703 2256 $key = sanitize_key( $name );
2704 2257 $key = self::maybe_clear_long_key( $key, $column );
2705 2258 }
@@ -2719,31 +2272,31 @@
2719 2272 $column
2720 2273 );
2721 2274
2722 2275 // Create a unique field id if it has already been used.
2723 - if ( ! in_array( $key, $similar_keys, true ) ) {
2724 - return $key;
2725 - }
2276 + if ( in_array( $key, $similar_keys, true ) ) {
2277 + $key = self::maybe_truncate_key_before_appending( $column, $key );
2726 2278
2727 - $key = self::maybe_truncate_key_before_appending( $column, $key );
2279 + /**
2280 + * Allow for a custom separator between the attempted key and the generated suffix.
2281 + *
2282 + * @since 5.2.03
2283 + *
2284 + * @param string $separator. Default empty.
2285 + * @param string $key the key without the added suffix.
2286 + */
2287 + $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2728 2288
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 );
2289 + $suffix = 2;
2290 + do {
2291 + $key_check = $key . $separator . $suffix;
2292 + ++$suffix;
2293 + } while ( in_array( $key_check, $similar_keys, true ) );
2738 2294
2739 - $suffix = 2;
2740 - do {
2741 - $key_check = $key . $separator . $suffix;
2742 - ++$suffix;
2743 - } while ( in_array( $key_check, $similar_keys, true ) );
2295 + $key = $key_check;
2296 + }//end if
2744 2297
2745 - return $key_check;
2298 + return $key;
2746 2299 }
2747 2300
2748 2301 /**
2749 2302 * Avoid trying to append to a really long key,
@@ -2750,26 +2303,20 @@
2750 2303 * The database limit is 100 for form and field keys so we want to avoid getting too close.
2751 2304 *
2752 2305 * @param string $column
2753 2306 * @param string $key
2754 - *
2755 2307 * @return string
2756 2308 */
2757 2309 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';
2310 + if ( in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2311 + $max_key_length_before_truncating = 60;
2312 + if ( strlen( $key ) > $max_key_length_before_truncating ) {
2313 + $key = substr( $key, 0, $max_key_length_before_truncating );
2314 + if ( is_numeric( $key ) ) {
2315 + $key .= 'a';
2316 + }
2769 2317 }
2770 2318 }
2771 -
2772 2319 return $key;
2773 2320 }
2774 2321
2775 2322 /**
@@ -2776,36 +2323,31 @@
2776 2323 * Possibly reset a key to avoid conflicts with column size limits.
2777 2324 *
2778 2325 * @param string $key
2779 2326 * @param string $column
2780 - *
2781 2327 * @return string either the original key value, or an empty string if the key was too long.
2782 2328 */
2783 2329 private static function maybe_clear_long_key( $key, $column ) {
2784 2330 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
2785 - return '';
2331 + $key = '';
2786 2332 }
2787 2333 return $key;
2788 2334 }
2789 2335
2790 2336 /**
2791 - * @since 6.21 This is changed from `private` to `public`.
2792 - *
2793 2337 * @param int $num_chars
2794 - *
2795 2338 * @return string
2796 2339 */
2797 - public static function generate_new_key( $num_chars ) {
2798 - $max_slug_value = 36 ** $num_chars;
2340 + private static function generate_new_key( $num_chars ) {
2341 + $max_slug_value = pow( 36, $num_chars );
2799 2342
2800 2343 // We want to have at least 2 characters in the slug.
2801 2344 $min_slug_value = 37;
2802 - return base_convert( random_int( $min_slug_value, $max_slug_value ), 10, 36 );
2345 + return base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
2803 2346 }
2804 2347
2805 2348 /**
2806 2349 * @param string $key
2807 - *
2808 2350 * @return string
2809 2351 */
2810 2352 private static function prevent_numeric_and_reserved_keys( $key ) {
2811 2353 if ( is_numeric( $key ) ) {
@@ -2819,14 +2361,12 @@
2819 2361 'editlink',
2820 2362 'siteurl',
2821 2363 'evenodd',
2822 2364 );
2823 -
2824 2365 if ( in_array( $key, $not_allowed, true ) ) {
2825 2366 $key .= 'a';
2826 2367 }
2827 2368 }
2828 -
2829 2369 return $key;
2830 2370 }
2831 2371
2832 2372 /**
@@ -2845,9 +2385,9 @@
2845 2385 if ( ! $record ) {
2846 2386 return false;
2847 2387 }
2848 2388
2849 - if ( ! $post_values ) {
2389 + if ( empty( $post_values ) ) {
2850 2390 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
2851 2391 }
2852 2392
2853 2393 $values = array(
@@ -2855,9 +2395,9 @@
2855 2395 'fields' => array(),
2856 2396 );
2857 2397
2858 2398 foreach ( array( 'name', 'description' ) as $var ) {
2859 - $default_val = $record->{$var} ?? '';
2399 + $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
2860 2400 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
2861 2401 unset( $var, $default_val );
2862 2402 }
2863 2403
@@ -2875,67 +2415,46 @@
2875 2415
2876 2416 return $values;
2877 2417 }
2878 2418
2879 - /**
2880 - * @param array|string $fields
2881 - * @param object $record
2882 - * @param array $values
2883 - * @param array $args
2884 - *
2885 - * @return void
2886 - */
2887 2419 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 );
2420 + if ( ! empty( $fields ) ) {
2421 + foreach ( (array) $fields as $field ) {
2422 + if ( ! self::is_admin_page() ) {
2423 + // Don't prep default values on the form settings page.
2424 + $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
2425 + }
2426 + $args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
2427 + self::fill_field_defaults( $field, $record, $values, $args );
2896 2428 }
2897 -
2898 - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id;
2899 - self::fill_field_defaults( $field, $record, $values, $args );
2900 2429 }
2901 2430 }
2902 2431
2903 - /**
2904 - * @param object $field
2905 - * @param object $record
2906 - * @param array $values
2907 - * @param array $args
2908 - *
2909 - * @return void
2910 - */
2911 2432 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
2912 2433 $post_values = $args['post_values'];
2913 2434
2914 2435 if ( $args['default'] ) {
2915 2436 $meta_value = $field->default_value;
2916 - } elseif ( $record->post_id && self::pro_is_installed() && ! empty( $field->field_options['post_field'] ) ) {
2437 + } elseif ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) {
2917 2438 if ( ! isset( $field->field_options['custom_field'] ) ) {
2918 2439 $field->field_options['custom_field'] = '';
2919 2440 }
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 - );
2441 + $meta_value = FrmProEntryMetaHelper::get_post_value(
2442 + $record->post_id,
2443 + $field->field_options['post_field'],
2444 + $field->field_options['custom_field'],
2445 + array(
2446 + 'truncate' => false,
2447 + 'type' => $field->type,
2448 + 'form_id' => $field->form_id,
2449 + 'field' => $field,
2450 + )
2451 + );
2932 2452 } else {
2933 2453 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
2934 2454 }//end if
2935 2455
2936 - $field_type = $post_values['field_options'][ 'type_' . $field->id ] ?? $field->type;
2937 -
2456 + $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
2938 2457 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
2939 2458 $new_value = $post_values['item_meta'][ $field->id ];
2940 2459 self::unserialize_or_decode( $new_value );
2941 2460 } else {
@@ -2950,9 +2469,9 @@
2950 2469 $args['field_type'] = $field_type;
2951 2470
2952 2471 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
2953 2472
2954 - if ( empty( $field_array['unique'] ) ) {
2473 + if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
2955 2474 $field_array['unique_msg'] = '';
2956 2475 }
2957 2476
2958 2477 $field_array = array_merge( (array) $field->field_options, $field_array );
@@ -3019,21 +2538,15 @@
3019 2538 }
3020 2539
3021 2540 /**
3022 2541 * Set to POST value or default
3023 - *
3024 - * @param array $post_values
3025 - * @param array $values
3026 - *
3027 - * @return void
3028 2542 */
3029 2543 private static function fill_form_defaults( $post_values, array &$values ) {
3030 2544 $form_defaults = FrmFormsHelper::get_default_opts();
3031 2545
3032 2546 foreach ( $form_defaults as $opt => $default ) {
3033 - // phpcs:ignore Universal.Operators.StrictComparisons
3034 2547 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
3035 - $values[ $opt ] = $post_values['options'][ $opt ] ?? $default;
2548 + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default;
3036 2549 }
3037 2550
3038 2551 unset( $opt, $default );
3039 2552 }
@@ -3043,9 +2556,9 @@
3043 2556 }
3044 2557
3045 2558 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
3046 2559 if ( ! isset( $values[ $h . '_html' ] ) ) {
3047 - $values[ $h . '_html' ] = $post_values['options'][ $h . '_html' ] ?? FrmFormsHelper::get_default_html( $h );
2560 + $values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
3048 2561 }
3049 2562 unset( $h );
3050 2563 }
3051 2564 }
@@ -3057,57 +2570,46 @@
3057 2570 *
3058 2571 * @return bool|int
3059 2572 */
3060 2573 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'] );
2574 + if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
2575 + $custom_style = absint( $post_values['options']['custom_style'] );
2576 + } else {
2577 + $frm_settings = self::get_settings();
2578 + $custom_style = ( $frm_settings->load_style !== 'none' );
3063 2579 }
3064 2580
3065 - $frm_settings = self::get_settings();
3066 - return $frm_settings->load_style !== 'none';
2581 + return $custom_style;
3067 2582 }
3068 2583
3069 2584 /**
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 2585 * @param mixed $original_string
3077 2586 * @param int|string $length
3078 2587 * @param int $minword
3079 2588 * @param string $continue
3080 - * @param bool $force_length_limit Force the final string to never exceed the length limit.
3081 - *
3082 2589 * @return string
3083 2590 */
3084 - public static function truncate( $original_string, $length, $minword = 3, $continue = '...', $force_length_limit = false ) {
2591 + public static function truncate( $original_string, $length, $minword = 3, $continue = '...' ) {
3085 2592 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
3086 2593 return '';
3087 2594 }
3088 2595
3089 - $length = (int) $length;
2596 + $length = (int) $length;
2597 + $str = wp_strip_all_tags( (string) $original_string );
2598 + $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3090 2599
3091 - if ( $length === 0 ) {
2600 + if ( $length == 0 ) {
3092 2601 return '';
3093 2602 }
3094 2603
3095 - $str = wp_strip_all_tags( (string) $original_string );
3096 - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3097 -
3098 2604 if ( $length <= 10 ) {
3099 2605 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
3100 -
3101 - if ( $force_length_limit ) {
3102 - return $sub;
3103 - }
3104 -
3105 2606 return $sub . ( $length < $original_len ? $continue : '' );
3106 2607 }
3107 2608
3108 - $sub = '';
3109 - $len = 0;
2609 + $sub = '';
2610 + $len = 0;
2611 +
3110 2612 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
3111 2613
3112 2614 if ( ! is_array( $words ) ) {
3113 2615 return $original_string;
@@ -3113,11 +2615,10 @@
3113 2615 return $original_string;
3114 2616 }
3115 2617
3116 2618 foreach ( $words as $word ) {
3117 - $part = ( $sub !== '' ? ' ' : '' ) . $word;
2619 + $part = ( $sub != '' ? ' ' : '' ) . $word;
3118 2620 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
3119 -
3120 2621 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
3121 2622 break;
3122 2623 }
3123 2624
@@ -3130,21 +2631,10 @@
3130 2631
3131 2632 unset( $total_len, $word );
3132 2633 }
3133 2634
3134 - $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length, $force_length_limit );
2635 + $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length );
3135 2636
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 2637 return $sub . ( $len < $original_len ? $continue : '' );
3148 2638 }
3149 2639
3150 2640 /**
@@ -3151,51 +2641,30 @@
3151 2641 * If the string is still too long because there may not have been any spaces, force truncate.
3152 2642 *
3153 2643 * @since 6.5.4
3154 2644 *
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 - *
2645 + * @param string $sub Current substring.
2646 + * @param int $length The length limit.
3159 2647 * @return string
3160 2648 */
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 );
2649 + private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) {
2650 + if ( strlen( $sub ) < $length + 50 ) {
2651 + // If the string isn't way over the limit, leave it.
2652 + return $sub;
3176 2653 }
3177 2654
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 ) );
2655 + $first_space = strpos( $sub, ' ', $length );
2656 + if ( false !== $first_space ) {
2657 + // Ignore anything with spaces.
2658 + return $sub;
3183 2659 }
3184 2660
3185 - return $sub;
2661 + return substr( $sub, 0, $length + 10 );
3186 2662 }
3187 2663
3188 - /**
3189 - * @param array $function_names
3190 - * @param array $args
3191 - *
3192 - * @return mixed
3193 - */
3194 2664 public static function mb_function( $function_names, $args ) {
3195 2665 $mb_function_name = $function_names[0];
3196 2666 $function_name = $function_names[1];
3197 -
3198 2667 if ( function_exists( $mb_function_name ) ) {
3199 2668 $function_name = $mb_function_name;
3200 2669 }
3201 2670
@@ -3201,21 +2670,14 @@
3201 2670
3202 2671 return call_user_func_array( $function_name, $args );
3203 2672 }
3204 2673
3205 - /**
3206 - * @param string $date
3207 - * @param string $date_format
3208 - * @param string $time_format
3209 - *
3210 - * @return string
3211 - */
3212 2674 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
3213 - if ( ! $date ) {
2675 + if ( empty( $date ) ) {
3214 2676 return $date;
3215 2677 }
3216 2678
3217 - if ( ! $date_format ) {
2679 + if ( empty( $date_format ) ) {
3218 2680 $date_format = get_option( 'date_format' );
3219 2681 }
3220 2682
3221 2683 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
@@ -3223,10 +2685,10 @@
3223 2685 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
3224 2686 }
3225 2687
3226 2688 $formatted = self::get_localized_date( $date_format, $date );
3227 - $do_time = gmdate( 'H:i:s', strtotime( $date ) ) !== '00:00:00';
3228 2689
2690 + $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
3229 2691 if ( $do_time ) {
3230 2692 $formatted .= self::add_time_to_date( $time_format, $date );
3231 2693 }
3232 2694
@@ -3232,38 +2694,28 @@
3232 2694
3233 2695 return $formatted;
3234 2696 }
3235 2697
3236 - /**
3237 - * @param string $time_format
3238 - * @param string $date
3239 - *
3240 - * @return string
3241 - */
3242 2698 private static function add_time_to_date( $time_format, $date ) {
3243 - if ( ! $time_format ) {
2699 + if ( empty( $time_format ) ) {
3244 2700 $time_format = get_option( 'time_format' );
3245 2701 }
3246 2702
3247 2703 $trimmed_format = trim( $time_format );
3248 -
3249 - if ( $time_format && $trimmed_format ) {
3250 - return ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
2704 + $time = '';
2705 + if ( $time_format && ! empty( $trimmed_format ) ) {
2706 + $time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
3251 2707 }
3252 2708
3253 - return '';
2709 + return $time;
3254 2710 }
3255 2711
3256 2712 /**
3257 2713 * @since 2.0.8
3258 - *
3259 - * @param string $date_format
3260 - * @param string $date
3261 - *
3262 - * @return string
3263 2714 */
3264 2715 public static function get_localized_date( $date_format, $date ) {
3265 2716 $date = get_date_from_gmt( $date );
2717 +
3266 2718 return date_i18n( $date_format, strtotime( $date ) );
3267 2719 }
3268 2720
3269 2721 /**
@@ -3268,16 +2720,19 @@
3268 2720
3269 2721 /**
3270 2722 * Gets the time ago in words.
3271 2723 *
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.
2724 + * @param int $from In seconds.
2725 + * @param int|string $to In seconds.
3275 2726 *
3276 - * @return string Time ago.
2727 + * @return string $time_ago
3277 2728 */
3278 2729 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
3279 - $now = ! $to && 0 !== $to ? new DateTime() : new DateTime( '@' . $to );
2730 + if ( empty( $to ) && 0 !== $to ) {
2731 + $now = new DateTime();
2732 + } else {
2733 + $now = new DateTime( '@' . $to );
2734 + }
3280 2735 $ago = new DateTime( '@' . $from );
3281 2736
3282 2737 // Get the time difference
3283 2738 $diff_object = $now->diff( $ago );
@@ -3291,9 +2746,8 @@
3291 2746
3292 2747 if ( ! is_numeric( $levels ) ) {
3293 2748 // Show time in specified unit.
3294 2749 $levels = self::get_unit( $levels );
3295 -
3296 2750 if ( isset( $time_strings[ $levels ] ) ) {
3297 2751 $diff = array(
3298 2752 $levels => self::time_format( $levels, $diff ),
3299 2753 );
@@ -3300,14 +2754,13 @@
3300 2754 $time_strings = array(
3301 2755 $levels => $time_strings[ $levels ],
3302 2756 );
3303 2757 }
3304 -
3305 2758 $levels = 1;
3306 2759 }
3307 2760
3308 2761 foreach ( $time_strings as $k => $v ) {
3309 - if ( ! empty( $diff[ $k ] ) ) {
2762 + if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
3310 2763 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
3311 2764 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
3312 2765 // Account for 0.
3313 2766 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
@@ -3315,21 +2768,17 @@
3315 2768 unset( $time_strings[ $k ] );
3316 2769 }
3317 2770 }
3318 2771
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 ) );
2772 + $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
2773 + $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2774 + $time_ago_string = implode( ' ', $time_strings );
3321 2775
3322 - return implode( ' ', $time_strings );
2776 + return $time_ago_string;
3323 2777 }
3324 2778
3325 2779 /**
3326 2780 * @since 4.05.01
3327 - *
3328 - * @param string $unit
3329 - * @param array $diff
3330 - *
3331 - * @return int
3332 2781 */
3333 2782 private static function time_format( $unit, $diff ) {
3334 2783 $return = array(
3335 2784 'y' => 'y',
@@ -3334,14 +2783,14 @@
3334 2783 $return = array(
3335 2784 'y' => 'y',
3336 2785 'd' => 'days',
3337 2786 );
3338 -
3339 2787 if ( isset( $return[ $unit ] ) ) {
3340 2788 return $diff[ $return[ $unit ] ];
3341 2789 }
3342 2790
3343 2791 $total = $diff['days'] * self::convert_time( 'd', $unit );
2792 +
3344 2793 $times = array( 'h', 'i', 's' );
3345 2794
3346 2795 foreach ( $times as $time ) {
3347 2796 if ( ! isset( $diff[ $time ] ) ) {
@@ -3355,13 +2804,8 @@
3355 2804 }
3356 2805
3357 2806 /**
3358 2807 * @since 4.05.01
3359 - *
3360 - * @param string $from
3361 - * @param string $to
3362 - *
3363 - * @return int
3364 2808 */
3365 2809 private static function convert_time( $from, $to ) {
3366 2810 $convert = array(
3367 2811 's' => 1,
@@ -3377,26 +2821,20 @@
3377 2821 }
3378 2822
3379 2823 /**
3380 2824 * @since 4.05.01
3381 - *
3382 - * @param string $unit
3383 - *
3384 - * @return int|string
3385 2825 */
3386 2826 private static function get_unit( $unit ) {
3387 2827 $units = self::get_time_strings();
3388 -
3389 2828 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
3390 2829 return $unit;
3391 2830 }
3392 2831
3393 2832 foreach ( $units as $u => $strings ) {
3394 - if ( in_array( $unit, $strings, true ) ) {
2833 + if ( in_array( $unit, $strings ) ) {
3395 2834 return $u;
3396 2835 }
3397 2836 }
3398 -
3399 2837 return 1;
3400 2838 }
3401 2839
3402 2840 /**
@@ -3403,9 +2841,8 @@
3403 2841 * Get the translatable time strings. The untranslated version is a failsafe
3404 2842 * in case languages are changing for the unit set in the shortcode.
3405 2843 *
3406 2844 * @since 2.0.20
3407 - *
3408 2845 * @return array
3409 2846 */
3410 2847 private static function get_time_strings() {
3411 2848 return array(
@@ -3452,13 +2889,12 @@
3452 2889 /**
3453 2890 * @param int $r_count
3454 2891 * @param int $current_p
3455 2892 * @param int $p_size
3456 - *
3457 2893 * @return int
3458 2894 */
3459 2895 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;
2896 + return ( $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size );
3461 2897 }
3462 2898
3463 2899 /**
3464 2900 * @param int $r_count
@@ -3463,13 +2899,11 @@
3463 2899 /**
3464 2900 * @param int $r_count
3465 2901 * @param int $current_p
3466 2902 * @param int $p_size
3467 - *
3468 2903 * @return int
3469 2904 */
3470 2905 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
3471 - // phpcs:ignore Universal.Operators.StrictComparisons
3472 2906 if ( $current_p == 1 ) {
3473 2907 return 1;
3474 2908 }
3475 2909 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
@@ -3475,22 +2909,17 @@
3475 2909 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
3476 2910 }
3477 2911
3478 2912 /**
3479 - * @param array $json_vars
3480 - *
3481 2913 * @return array
3482 2914 */
3483 2915 public static function json_to_array( $json_vars ) {
3484 2916 $vars = array();
3485 -
3486 2917 foreach ( $json_vars as $jv ) {
3487 2918 $jv_name = explode( '[', $jv['name'] );
3488 2919 $last = count( $jv_name ) - 1;
3489 -
3490 2920 foreach ( $jv_name as $p => $n ) {
3491 2921 $name = trim( $n, ']' );
3492 -
3493 2922 if ( ! isset( $l1 ) ) {
3494 2923 $l1 = $name;
3495 2924 }
3496 2925
@@ -3501,9 +2930,9 @@
3501 2930 if ( ! isset( $l3 ) ) {
3502 2931 $l3 = $name;
3503 2932 }
3504 2933
3505 - $this_val = $p === $last ? $jv['value'] : array();
2934 + $this_val = $p == $last ? $jv['value'] : array();
3506 2935
3507 2936 switch ( $p ) {
3508 2937 case 0:
3509 2938 $l1 = $name;
@@ -3536,15 +2965,10 @@
3536 2965
3537 2966 /**
3538 2967 * @param string $name
3539 2968 * @param string $l1
3540 - * @param mixed $val
3541 - * @param array $vars
3542 - *
3543 - * @return void
3544 2969 */
3545 2970 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
3546 - // phpcs:ignore Universal.Operators.StrictComparisons
3547 2971 if ( $name == '' ) {
3548 2972 $vars[] = $val;
3549 2973 } elseif ( ! isset( $vars[ $l1 ] ) ) {
3550 2974 $vars[ $l1 ] = $val;
@@ -3550,26 +2974,19 @@
3550 2974 $vars[ $l1 ] = $val;
3551 2975 }
3552 2976 }
3553 2977
3554 - /**
3555 - * @param string $name
3556 - * @param string $class
3557 - * @param string $form_name
3558 - *
3559 - * @return void
3560 - */
3561 2978 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
3562 2979 $tooltips = array(
3563 2980 '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
2981 + '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 2982 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3566 2983 '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
2984 + '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 2985 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
3569 2986 /* 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
2987 + '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() ) ),
2988 + '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 2989 );
3573 2990
3574 2991 if ( ! isset( $tooltips[ $name ] ) ) {
3575 2992 return;
@@ -3574,9 +2991,9 @@
3574 2991 if ( ! isset( $tooltips[ $name ] ) ) {
3575 2992 return;
3576 2993 }
3577 2994
3578 - if ( 'open' === $class ) {
2995 + if ( 'open' == $class ) {
3579 2996 echo ' frm_help"';
3580 2997 } else {
3581 2998 echo ' class="frm_help"';
3582 2999 }
@@ -3582,9 +2999,9 @@
3582 2999 }
3583 3000
3584 3001 echo ' title="' . esc_attr( $tooltips[ $name ] );
3585 3002
3586 - if ( 'open' !== $class ) {
3003 + if ( 'open' != $class ) {
3587 3004 echo '"';
3588 3005 }
3589 3006 }
3590 3007
@@ -3589,28 +3006,20 @@
3589 3006 }
3590 3007
3591 3008 /**
3592 3009 * 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 3010 */
3600 3011 public static function select_current_page( $page, $current_page, $action = array() ) {
3601 - // phpcs:ignore Universal.Operators.StrictComparisons
3602 3012 if ( $current_page != $page ) {
3603 3013 return;
3604 3014 }
3605 3015
3606 3016 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
3607 -
3608 3017 if ( 'lite-reports' === $frm_action ) {
3609 3018 $frm_action = 'reports';
3610 3019 }
3611 3020
3612 - if ( ! $action || ( $frm_action && in_array( $frm_action, $action, true ) ) ) {
3021 + if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
3613 3022 echo ' class="current_page"';
3614 3023 }
3615 3024 }
3616 3025
@@ -3640,19 +3049,14 @@
3640 3049
3641 3050 // Add extra slashes for \r\n since WP strips them.
3642 3051 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
3643 3052
3644 - // Allow for &quot
3645 - return str_replace( '&quot;', '\\"', $post_content );
3053 + // allow for &quot
3054 + $post_content = str_replace( '&quot;', '\\"', $post_content );
3055 +
3056 + return $post_content;
3646 3057 }
3647 3058
3648 - /**
3649 - * @param array|string $val
3650 - * @param int|string $key
3651 - * @param array $post_content
3652 - *
3653 - * @return void
3654 - */
3655 3059 private static function prepare_action_slashes( $val, $key, &$post_content ) {
3656 3060 if ( ! isset( $post_content[ $key ] ) || is_numeric( $val ) ) {
3657 3061 return;
3658 3062 }
@@ -3661,17 +3065,15 @@
3661 3065 foreach ( $val as $k1 => $v1 ) {
3662 3066 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
3663 3067 unset( $k1, $v1 );
3664 3068 }
3069 + } else {
3070 + // Strip all slashes so everything is the same, no matter where the value is coming from
3071 + $val = stripslashes( $val );
3665 3072
3666 - return;
3073 + // Add backslashes before double quotes and forward slashes only
3074 + $post_content[ $key ] = addcslashes( $val, '"\\/' );
3667 3075 }
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 3076 }
3675 3077
3676 3078 /**
3677 3079 * Check for either json or serialized data. This is temporary while transitioning
@@ -3679,9 +3081,8 @@
3679 3081 *
3680 3082 * @since 4.02.03
3681 3083 *
3682 3084 * @param array|string $value
3683 - *
3684 3085 * @return void
3685 3086 */
3686 3087 public static function unserialize_or_decode( &$value ) {
3687 3088 if ( is_array( $value ) ) {
@@ -3687,9 +3088,13 @@
3687 3088 if ( is_array( $value ) ) {
3688 3089 return;
3689 3090 }
3690 3091
3691 - $value = is_serialized( $value ) ? self::maybe_unserialize_array( $value ) : self::maybe_json_decode( $value, false );
3092 + if ( is_serialized( $value ) ) {
3093 + $value = self::maybe_unserialize_array( $value );
3094 + } else {
3095 + $value = self::maybe_json_decode( $value, false );
3096 + }
3692 3097 }
3693 3098
3694 3099 /**
3695 3100 * Safely unserialize an array if necessary.
@@ -3697,9 +3102,8 @@
3697 3102 *
3698 3103 * @since 6.2
3699 3104 *
3700 3105 * @param mixed $value
3701 - *
3702 3106 * @return mixed
3703 3107 */
3704 3108 public static function maybe_unserialize_array( $value ) {
3705 3109 if ( ! is_string( $value ) ) {
@@ -3706,15 +3110,18 @@
3706 3110 return $value;
3707 3111 }
3708 3112
3709 3113 // Since we only expect an array, skip anything that doesn't start with a:.
3710 - if ( ! is_serialized( $value ) || ! str_starts_with( $value, 'a:' ) ) {
3114 + if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
3711 3115 return $value;
3712 3116 }
3713 3117
3714 3118 $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
3119 + if ( is_array( $parsed ) ) {
3120 + $value = $parsed;
3121 + }
3715 3122
3716 - return is_array( $parsed ) ? $parsed : $value;
3123 + return $value;
3717 3124 }
3718 3125
3719 3126 /**
3720 3127 * Decode a JSON string.
@@ -3719,12 +3126,11 @@
3719 3126 /**
3720 3127 * Decode a JSON string.
3721 3128 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
3722 3129 *
3723 - * @param array|string|null $string
3724 - * @param bool $single_to_array
3725 - *
3726 - * @return array|string|null
3130 + * @param mixed $string
3131 + * @param bool $single_to_array
3132 + * @return mixed
3727 3133 */
3728 3134 public static function maybe_json_decode( $string, $single_to_array = true ) {
3729 3135 if ( is_array( $string ) || is_null( $string ) ) {
3730 3136 return $string;
@@ -3729,19 +3135,20 @@
3729 3135 if ( is_array( $string ) || is_null( $string ) ) {
3730 3136 return $string;
3731 3137 }
3732 3138
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] );
3139 + $new_string = json_decode( $string, true );
3140 + if ( function_exists( 'json_last_error' ) ) {
3141 + // php 5.3+
3142 + $single_value = false;
3143 + if ( ! $single_to_array ) {
3144 + $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
3145 + }
3146 + if ( json_last_error() == JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3147 + $string = $new_string;
3148 + }
3738 3149 }
3739 3150
3740 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3741 - return $new_string;
3742 - }
3743 -
3744 3151 return $string;
3745 3152 }
3746 3153
3747 3154 /**
@@ -3747,9 +3154,8 @@
3747 3154 /**
3748 3155 * @since 6.2.3
3749 3156 *
3750 3157 * @param string $value
3751 - *
3752 3158 * @return string
3753 3159 */
3754 3160 public static function maybe_utf8_encode( $value ) {
3755 3161 $from_format = 'ISO-8859-1';
@@ -3758,15 +3164,13 @@
3758 3164 if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
3759 3165 if ( mb_check_encoding( $value, $from_format ) ) {
3760 3166 return mb_convert_encoding( $value, $to_format, $from_format );
3761 3167 }
3762 -
3763 3168 return $value;
3764 3169 }
3765 3170
3766 3171 if ( function_exists( 'iconv' ) ) {
3767 3172 $converted = iconv( $from_format, $to_format, $value );
3768 -
3769 3173 // Value is false if $value is not ISO-8859-1.
3770 3174 if ( false !== $converted ) {
3771 3175 return $converted;
3772 3176 }
@@ -3778,12 +3182,8 @@
3778 3182 /**
3779 3183 * Reformat the json serialized array in name => value array.
3780 3184 *
3781 3185 * @since 4.02.03
3782 - *
3783 - * @param array $form
3784 - *
3785 - * @return void
3786 3186 */
3787 3187 public static function format_form_data( &$form ) {
3788 3188 $formatted = array();
3789 3189
@@ -3790,21 +3190,18 @@
3790 3190 foreach ( $form as $input ) {
3791 3191 if ( ! isset( $input['name'] ) ) {
3792 3192 continue;
3793 3193 }
3794 -
3795 3194 $key = $input['name'];
3796 -
3797 - if ( ! isset( $formatted[ $key ] ) ) {
3195 + if ( isset( $formatted[ $key ] ) ) {
3196 + if ( is_array( $formatted[ $key ] ) ) {
3197 + $formatted[ $key ][] = $input['value'];
3198 + } else {
3199 + $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3200 + }
3201 + } else {
3798 3202 $formatted[ $key ] = $input['value'];
3799 - continue;
3800 3203 }
3801 -
3802 - if ( is_array( $formatted[ $key ] ) ) {
3803 - $formatted[ $key ][] = $input['value'];
3804 - } else {
3805 - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3806 - }
3807 3204 }
3808 3205
3809 3206 parse_str( http_build_query( $formatted ), $form );
3810 3207 }
@@ -3812,13 +3209,15 @@
3812 3209 /**
3813 3210 * @since 4.02.03
3814 3211 *
3815 3212 * @param array|string $value
3816 - *
3817 3213 * @return string
3818 3214 */
3819 3215 public static function maybe_json_encode( $value ) {
3820 - return is_array( $value ) ? wp_json_encode( $value ) : $value;
3216 + if ( is_array( $value ) ) {
3217 + $value = wp_json_encode( $value );
3218 + }
3219 + return $value;
3821 3220 }
3822 3221
3823 3222 /**
3824 3223 * Echo The javascript to open and highlight the Formidable menu
@@ -3825,19 +3224,18 @@
3825 3224 *
3826 3225 * @since 1.07.10
3827 3226 *
3828 3227 * @param string $post_type The name of the post type that may need to be highlighted.
3829 - *
3830 3228 * @return void
3831 3229 */
3832 3230 public static function maybe_highlight_menu( $post_type ) {
3833 3231 global $post;
3834 3232
3835 - if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] !== $post_type ) {
3233 + if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
3836 3234 return;
3837 3235 }
3838 3236
3839 - if ( is_object( $post ) && $post->post_type !== $post_type ) {
3237 + if ( is_object( $post ) && $post->post_type != $post_type ) {
3840 3238 return;
3841 3239 }
3842 3240
3843 3241 self::load_admin_wide_js();
@@ -3849,13 +3247,13 @@
3849 3247 *
3850 3248 * @since 2.0
3851 3249 *
3852 3250 * @param bool $load
3853 - *
3854 3251 * @return void
3855 3252 */
3856 3253 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() );
3254 + $version = self::plugin_version();
3255 + wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
3858 3256
3859 3257 $global_strings = array(
3860 3258 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
3861 3259 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
@@ -3861,9 +3259,9 @@
3861 3259 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
3862 3260 'url' => self::plugin_url(),
3863 3261 'app_url' => 'https://formidableforms.com/',
3864 3262 '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
3263 + 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ),
3866 3264 'loading' => __( 'Loading&hellip;', 'formidable' ),
3867 3265 'nonce' => wp_create_nonce( 'frm_ajax' ),
3868 3266 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
3869 3267 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(),
@@ -3876,9 +3274,8 @@
3876 3274 }
3877 3275
3878 3276 /**
3879 3277 * @since 2.0.9
3880 - *
3881 3278 * @return void
3882 3279 */
3883 3280 public static function load_font_style() {
3884 3281 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
@@ -3885,9 +3282,8 @@
3885 3282 }
3886 3283
3887 3284 /**
3888 3285 * @param string $location
3889 - *
3890 3286 * @return void
3891 3287 */
3892 3288 public static function localize_script( $location ) {
3893 3289 global $wp_scripts, $wp_version;
@@ -3910,9 +3306,8 @@
3910 3306 'include_resend_email' => false,
3911 3307 );
3912 3308
3913 3309 $data = $wp_scripts->get_data( 'formidable', 'data' );
3914 -
3915 3310 if ( ! $data ) {
3916 3311 wp_localize_script( 'formidable', 'frm_js', $script_strings );
3917 3312 }
3918 3313
@@ -3919,9 +3314,9 @@
3919 3314 if ( $location === 'admin' ) {
3920 3315 $admin_script_strings = array(
3921 3316 'desc' => __( '(Click to add description)', 'formidable' ),
3922 3317 'blank' => __( '(Blank)', 'formidable' ),
3923 - 'no_label' => self::get_no_label_text(),
3318 + 'no_label' => __( '(no label)', 'formidable' ),
3924 3319 'ok' => __( 'OK', 'formidable' ),
3925 3320 'cancel' => __( 'Cancel', 'formidable' ),
3926 3321 'default_label' => __( 'Default', 'formidable' ),
3927 3322 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3929,9 +3324,9 @@
3929 3324 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3930 3325 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3931 3326 'confirm' => __( 'Are you sure?', 'formidable' ),
3932 3327 '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
3328 + 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ),
3934 3329 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3935 3330 'default_unique' => FrmFieldsHelper::default_unique_msg(),
3936 3331 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3937 3332 'enter_email' => __( 'Enter Email', 'formidable' ),
@@ -3937,9 +3332,9 @@
3937 3332 'enter_email' => __( 'Enter Email', 'formidable' ),
3938 3333 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3939 3334 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3940 3335 '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
3336 + 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ),
3942 3337 'enter_password' => __( 'Enter Password', 'formidable' ),
3943 3338 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3944 3339 'import_complete' => __( 'Import Complete', 'formidable' ),
3945 3340 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
@@ -3953,15 +3348,13 @@
3953 3348 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
3954 3349 /* translators: %d is the number of allowed actions per form */
3955 3350 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ),
3956 3351 '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 3352 'unsafe_params' => FrmFormsHelper::reserved_words(),
3960 3353 /* 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
3354 + 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
3962 3355 /* 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
3356 + 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
3964 3357 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3965 3358 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3966 3359 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3967 3360 'install' => __( 'Install', 'formidable' ),
@@ -3982,14 +3375,11 @@
3982 3375 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
3983 3376 'noTitleText' => FrmFormsHelper::get_no_title_text(),
3984 3377
3985 3378 // 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+.
3379 + // when the h3 element is clicked. It's only required in WP 6.7+.
3987 3380 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ),
3988 3381 );
3989 -
3990 - self::add_form_builder_modal_data( $admin_script_strings );
3991 -
3992 3382 /**
3993 3383 * @param array $admin_script_strings
3994 3384 */
3995 3385 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
@@ -3994,9 +3384,8 @@
3994 3384 */
3995 3385 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3996 3386
3997 3387 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
3998 -
3999 3388 if ( ! $data ) {
4000 3389 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
4001 3390 }
4002 3391 }//end if
@@ -4002,91 +3391,8 @@
4002 3391 }//end if
4003 3392 }
4004 3393
4005 3394 /**
4006 - * @param array $admin_script_strings
4007 - *
4008 - * @return void
4009 - */
4010 - private static function add_form_builder_modal_data( &$admin_script_strings ) {
4011 - if ( ! self::is_form_builder_page() || self::pro_is_installed() ) {
4012 - return;
4013 - }
4014 -
4015 - $stripe_connected = FrmStrpLiteConnectHelper::at_least_one_mode_is_setup();
4016 - $square_connected = FrmSquareLiteConnectHelper::at_least_one_mode_is_setup();
4017 - $paypal_connected = FrmPayPalLiteConnectHelper::at_least_one_mode_is_setup();
4018 - $gateway_connected = $stripe_connected || $square_connected || $paypal_connected;
4019 - $payments_settings_url = FrmStrpLiteAppController::get_payments_settings_url();
4020 -
4021 - if ( ! $gateway_connected ) {
4022 - // This modal shows when user clicks on one of the pricing fields and no payment gateways configured.
4023 - $admin_script_strings['paymentsSettingsModal'] = array(
4024 - 'title' => __( 'Setup a Payment Gateway first', 'formidable' ),
4025 - 'msg' => __( 'To use the payment fields, please install and configure a payment gateway in your account settings.', 'formidable' ),
4026 - 'closeText' => __( 'Close', 'formidable' ),
4027 - 'actionUrl' => $payments_settings_url,
4028 - 'actionText' => __( 'Go to Payment Settings', 'formidable' ),
4029 - 'noCenter' => true,
4030 - );
4031 - }
4032 -
4033 - // This modal shows on load once after upgrading the plugin.
4034 - $show_pricing_fields_modal = get_option( 'frm_show_pricing_fields_modal' );
4035 -
4036 - if ( ! $show_pricing_fields_modal ) {
4037 - return;
4038 - }
4039 -
4040 - $admin_script_strings['pricingFieldsModal'] = array(
4041 - 'title' => esc_html__( 'Start Accepting Payments Today!', 'formidable' ),
4042 - 'img' => esc_url( self::plugin_url() . '/images/upsell/pricing-fields.png' ),
4043 - 'noCenter' => true,
4044 - );
4045 -
4046 - if ( $gateway_connected ) {
4047 - $gateway_texts = array();
4048 -
4049 - if ( $stripe_connected ) {
4050 - $gateway_texts['stripe'] = esc_html__( 'Stripe', 'formidable' );
4051 - }
4052 -
4053 - if ( $square_connected ) {
4054 - $gateway_texts['square'] = esc_html__( 'Square', 'formidable' );
4055 - }
4056 -
4057 - if ( $paypal_connected ) {
4058 - $gateway_texts['paypal'] = esc_html__( 'PayPal', 'formidable' );
4059 - }
4060 -
4061 - $admin_script_strings['pricingFieldsModal']['msg'] = sprintf(
4062 - // translators: %s: Stripe, Square, or PayPal.
4063 - esc_html__( 'You already have %s connected, so these have already been unlocked.', 'formidable' ),
4064 - esc_html( implode( ' ' . esc_html__( 'and', 'formidable' ) . ' ', $gateway_texts ) )
4065 - );
4066 - } else {
4067 - $admin_script_strings['pricingFieldsModal']['closeText'] = __( 'I\'ll do it later!', 'formidable' );
4068 - $admin_script_strings['pricingFieldsModal']['actionText'] = __( 'Setup Payments Now', 'formidable' );
4069 - $admin_script_strings['pricingFieldsModal']['actionUrl'] = $payments_settings_url;
4070 - // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4071 - $admin_script_strings['pricingFieldsModal']['msg'] = __( 'We\'ve unlocked Product, Quantity, and Total fields for Lite users! You can now transform your forms into checkout pages. To start collecting revenue, simply connect your preferred payment gateway (Stripe, Square, or PayPal) in your settings.', 'formidable' );
4072 - }//end if
4073 -
4074 - delete_option( 'frm_show_pricing_fields_modal' );
4075 - }
4076 -
4077 - /**
4078 - * Get the no label text.
4079 - *
4080 - * @since 6.25.1
4081 - *
4082 - * @return string
4083 - */
4084 - public static function get_no_label_text() {
4085 - return __( '(no label)', 'formidable' );
4086 - }
4087 -
4088 - /**
4089 3395 * @since 6.5
4090 3396 *
4091 3397 * @return string
4092 3398 */
@@ -4128,9 +3434,8 @@
4128 3434 *
4129 3435 * @since 1.07.10
4130 3436 *
4131 3437 * @param float $min_version The version the add-on requires.
4132 - *
4133 3438 * @return void
4134 3439 */
4135 3440 public static function min_version_notice( $min_version ) {
4136 3441 $frm_version = self::plugin_version();
@@ -4140,11 +3445,11 @@
4140 3445 return;
4141 3446 }
4142 3447
4143 3448 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
4144 - echo '<tr class="plugin-update-tr active"><th colspan="' . absint( $wp_list_table->get_column_count() ) . '" class="check-column plugin-update colspanchange"><div class="update-message">' . // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
4145 - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
4146 - '</div></td></tr>';
3449 + 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">' .
3450 + esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
3451 + '</div></td></tr>';
4147 3452 }
4148 3453
4149 3454 /**
4150 3455 * If Pro is far outdated, show a message.
@@ -4150,10 +3455,8 @@
4150 3455 * If Pro is far outdated, show a message.
4151 3456 *
4152 3457 * @since 4.0.01
4153 3458 *
4154 - * @param string $min_version
4155 - *
4156 3459 * @return void
4157 3460 */
4158 3461 public static function min_pro_version_notice( $min_version ) {
4159 3462 if ( ! self::is_formidable_admin() ) {
@@ -4163,14 +3466,25 @@
4163 3466
4164 3467 self::php_version_notice();
4165 3468
4166 3469 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
4167 -
4168 3470 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
4169 3471 return;
4170 3472 }
4171 3473
4172 - include self::plugin_path() . '/classes/views/addons/min-version-notice.php';
3474 + $expired = FrmAddonsController::is_license_expired();
3475 + ?>
3476 + <div class="frm-banner-alert frm_error_style frm_previous_install">
3477 + <?php
3478 + esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
3479 + if ( empty( $expired ) ) {
3480 + echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
3481 + } else {
3482 + echo '<br/>Please <a href="https://formidableforms.com/account/downloads/?utm_source=WordPress&utm_medium=outdated">renew now</a> to get the latest version.';
3483 + }
3484 + ?>
3485 + </div>
3486 + <?php
4173 3487 }
4174 3488
4175 3489 /**
4176 3490 * If Pro is installed, check the version number.
@@ -4177,9 +3491,8 @@
4177 3491 *
4178 3492 * @since 4.0.01
4179 3493 *
4180 3494 * @param string $min_version
4181 - *
4182 3495 * @return bool
4183 3496 */
4184 3497 public static function meets_min_pro_version( $min_version ) {
4185 3498 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
@@ -4188,19 +3501,16 @@
4188 3501 /**
4189 3502 * Show a message if the PHP version is below the recommendations.
4190 3503 *
4191 3504 * @since 4.0.02
4192 - *
4193 3505 * @return void
4194 3506 */
4195 3507 private static function php_version_notice() {
4196 3508 $message = array();
4197 -
4198 3509 if ( version_compare( phpversion(), '7.0', '<' ) ) {
4199 - $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3510 + $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' );
4200 3511 }
4201 3512
4202 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4203 3513 foreach ( $message as $m ) {
4204 3514 ?>
4205 3515 <div class="frm-banner-alert frm_error_style frm_previous_install">
4206 3516 <?php echo esc_html( $m ); ?>
@@ -4206,14 +3516,12 @@
4206 3516 <?php echo esc_html( $m ); ?>
4207 3517 </div>
4208 3518 <?php
4209 3519 }
4210 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4211 3520 }
4212 3521
4213 3522 /**
4214 3523 * @param string $type
4215 - *
4216 3524 * @return array<string,string>
4217 3525 */
4218 3526 public static function locales( $type = 'date' ) {
4219 3527 $locales = array(
@@ -4307,12 +3615,12 @@
4307 3615 'zu' => __( 'Zulu', 'formidable' ),
4308 3616 );
4309 3617
4310 3618 if ( $type === 'captcha' ) {
4311 - // Remove the languages unavailable for the captcha
3619 + // remove the languages unavailable for the captcha
4312 3620 $unset = array( 'sq', 'bs', 'eo', 'fo', 'fr-CH', 'sr-SR', 'ar-DZ', 'be', 'cy-GB', 'kk', 'km', 'ky', 'lb', 'mk', 'nb', 'nn', 'rm', 'tj' );
4313 3621 } else {
4314 - // Remove the languages unavailable for the datepicker
3622 + // remove the languages unavailable for the datepicker
4315 3623 $unset = array( 'fil', 'fr-CA', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419', 'mr', 'lo', 'kn', 'si', 'gu', 'bn', 'zu', 'ur', 'te', 'sw', 'am' );
4316 3624 }
4317 3625
4318 3626 $locales = array_diff_key( $locales, array_flip( $unset ) );
@@ -4323,13 +3631,14 @@
4323 3631 * @since 5.4.5 Added $args parameter with type.
4324 3632 *
4325 3633 * @param array<string,string> $locales
4326 3634 * @param array $args {
4327 - *
4328 3635 * @type string $type
4329 3636 * }
4330 3637 */
4331 - return apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3638 + $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3639 +
3640 + return $locales;
4332 3641 }
4333 3642
4334 3643 /**
4335 3644 * @return string
@@ -4336,14 +3645,12 @@
4336 3645 */
4337 3646 public static function get_menu_icon_class() {
4338 3647 if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
4339 3648 $settings = FrmProAppHelper::get_settings();
4340 -
4341 3649 if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
4342 3650 return $settings->menu_icon;
4343 3651 }
4344 3652 }
4345 -
4346 3653 return 'frmfont frm_logo_icon';
4347 3654 }
4348 3655
4349 3656 /**
@@ -4361,9 +3668,10 @@
4361 3668 * @type array $input_attrs Attributes of value input.
4362 3669 * }
4363 3670 */
4364 3671 public static function images_dropdown( $args ) {
4365 - $args = self::fill_default_images_dropdown_args( $args );
3672 + $args = self::fill_default_images_dropdown_args( $args );
3673 +
4366 3674 $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
4367 3675 ob_start();
4368 3676 include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
4369 3677 $output = ob_get_clean();
@@ -4384,9 +3692,8 @@
4384 3692 *
4385 3693 * @since 5.0.04
4386 3694 *
4387 3695 * @param array $args The arguments.
4388 - *
4389 3696 * @return array
4390 3697 */
4391 3698 private static function fill_default_images_dropdown_args( $args ) {
4392 3699 $defaults = array(
@@ -4399,8 +3706,14 @@
4399 3706
4400 3707 $new_args['options'] = (array) $new_args['options'];
4401 3708 $new_args['input_attrs'] = (array) $new_args['input_attrs'];
4402 3709
3710 + // Set the number of columns.
3711 + $new_args['col_class'] = ceil( 12 / count( $new_args['options'] ) );
3712 + if ( $new_args['col_class'] > 6 ) {
3713 + $new_args['col_class'] = ceil( $new_args['col_class'] / 2 );
3714 + }
3715 +
4403 3716 /**
4404 3717 * Allows modifying the arguments of images_dropdown() method.
4405 3718 *
4406 3719 * @since 5.0.04
@@ -4416,9 +3729,8 @@
4416 3729 *
4417 3730 * @since 5.0.04
4418 3731 *
4419 3732 * @param array $args The arguments.
4420 - *
4421 3733 * @return string
4422 3734 */
4423 3735 private static function get_images_dropdown_input_attrs( $args ) {
4424 3736 $input_attrs = $args['input_attrs'];
@@ -4425,9 +3737,8 @@
4425 3737 $input_attrs['type'] = 'radio';
4426 3738 $input_attrs['name'] = $args['name'];
4427 3739
4428 3740 $input_attrs_str = '';
4429 -
4430 3741 foreach ( $input_attrs as $key => $input_attr ) {
4431 3742 $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
4432 3743 }
4433 3744
@@ -4443,13 +3754,8 @@
4443 3754 }
4444 3755
4445 3756 /**
4446 3757 * @since 6.7.1
4447 - *
4448 - * @param array $option Option data.
4449 - * @param array $args The arguments of images_dropdown() method.
4450 - *
4451 - * @return array
4452 3758 */
4453 3759 public static function get_images_dropdown_atts( $option, $args ) {
4454 3760 $image = self::get_images_dropdown_option_image( $option, $args );
4455 3761 $classes = self::get_images_dropdown_option_classes( $option, $args );
@@ -4463,9 +3769,8 @@
4463 3769 * @since 5.0.04
4464 3770 *
4465 3771 * @param array $option Option data.
4466 3772 * @param array $args The arguments of images_dropdown() method.
4467 - *
4468 3773 * @return string
4469 3774 */
4470 3775 private static function get_images_dropdown_option_image( $option, $args ) {
4471 3776 $image = self::icon_by_class(
@@ -4494,9 +3799,8 @@
4494 3799 * @since 5.0.04
4495 3800 *
4496 3801 * @param array $option Option data.
4497 3802 * @param array $args The arguments of images_dropdown() method.
4498 - *
4499 3803 * @return string
4500 3804 */
4501 3805 private static function get_images_dropdown_option_classes( $option, $args ) {
4502 3806 $classes = '';
@@ -4524,19 +3828,17 @@
4524 3828 * @since 5.0.04
4525 3829 *
4526 3830 * @param array $option Option data.
4527 3831 * @param array $args The arguments of images_dropdown() method.
4528 - *
4529 3832 * @return string
4530 3833 */
4531 3834 private static function get_images_dropdown_option_html_attrs( $option, $args ) {
4532 3835 $html_attrs = '';
4533 -
4534 3836 if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
4535 3837 $html_attrs_arr = array();
4536 3838
4537 3839 foreach ( $option['custom_attrs'] as $key => $value ) {
4538 - if ( in_array( $key, array( 'type', 'class', 'data-value' ), true ) ) {
3840 + if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
4539 3841 continue;
4540 3842 }
4541 3843
4542 3844 $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
@@ -4594,13 +3896,14 @@
4594 3896 * @since 5.0.07
4595 3897 *
4596 3898 * @param array $values
4597 3899 * @param array $keys
4598 - *
4599 3900 * @return array
4600 3901 */
4601 3902 public static function maybe_filter_array( $values, $keys ) {
4602 - if ( self::allow_unfiltered_html() ) {
3903 + $allow_unfiltered_html = self::allow_unfiltered_html();
3904 +
3905 + if ( $allow_unfiltered_html ) {
4603 3906 return $values;
4604 3907 }
4605 3908
4606 3909 foreach ( $keys as $key ) {
@@ -4619,14 +3922,13 @@
4619 3922 * @since 5.0.13
4620 3923 *
4621 3924 * @param string $value
4622 3925 * @param array|string $allowed 'all' for everything included as defaults.
4623 - *
4624 3926 * @return string
4625 3927 */
4626 3928 public static function maybe_kses( $value, $allowed = 'all' ) {
4627 3929 if ( self::should_never_allow_unfiltered_html() ) {
4628 - return self::kses( $value, $allowed );
3930 + $value = self::kses( $value, $allowed );
4629 3931 }
4630 3932 return $value;
4631 3933 }
4632 3934
@@ -4636,18 +3938,17 @@
4636 3938 * @since 6.11.2
4637 3939 *
4638 3940 * @param string $key
4639 3941 * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed.
4640 - *
4641 3942 * @return bool
4642 3943 */
4643 3944 public static function input_key_is_safe( $key, $context = 'display' ) {
4644 3945 if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) {
4645 3946 $safe = true;
4646 - } elseif ( str_starts_with( $key, 'data-' ) ) {
3947 + } elseif ( 0 === strpos( $key, 'data-' ) ) {
4647 3948 // Allow all data attributes.
4648 3949 $safe = true;
4649 - } elseif ( str_starts_with( $key, 'aria-' ) ) {
3950 + } elseif ( 0 === strpos( $key, 'aria-' ) ) {
4650 3951 // Allow all aria attributes.
4651 3952 $safe = true;
4652 3953 } else {
4653 3954 $safe_keys = array(
@@ -4689,9 +3990,16 @@
4689 3990
4690 3991 /**
4691 3992 * @since 5.0.16
4692 3993 *
4693 - * @param string $medium
3994 + * @return bool
3995 + */
3996 + public static function show_landing_pages() {
3997 + return self::show_new_feature( 'landing' );
3998 + }
3999 +
4000 + /**
4001 + * @since 5.0.16
4694 4002 *
4695 4003 * @return array
4696 4004 */
4697 4005 public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
@@ -4699,9 +4007,8 @@
4699 4007 'medium' => $medium,
4700 4008 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
4701 4009 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
4702 4010 'screenshot' => 'landing.png',
4703 - 'learn-more' => self::get_doc_url( 'landing-page-forms', 'form-landing-page-settings', false ),
4704 4011 );
4705 4012 return self::get_upgrade_data_params( 'landing', $params );
4706 4013 }
4707 4014
@@ -4708,9 +4015,8 @@
4708 4015 /**
4709 4016 * @since 5.0.17
4710 4017 *
4711 4018 * @param string $feature
4712 - *
4713 4019 * @return bool
4714 4020 */
4715 4021 public static function show_new_feature( $feature ) {
4716 4022 $link = FrmAddonsController::install_link( $feature );
@@ -4717,21 +4023,16 @@
4717 4023 return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
4718 4024 }
4719 4025
4720 4026 /**
4721 - * Enhances upgrade data parameters with installation link and plan requirement information.
4722 - *
4723 4027 * @since 5.0.17
4724 4028 *
4725 - * @param string $plugin The plugin slug to get installation data for.
4726 - * @param array $params Initial parameters for the upgrade data.
4727 - * @param bool $detailed Whether to include detailed information.
4728 - *
4729 - * @return array Modified parameters with installation data.
4029 + * @param string $plugin
4030 + * @param array $params
4031 + * @return array
4730 4032 */
4731 - public static function get_upgrade_data_params( $plugin, $params, $detailed = false ) {
4033 + public static function get_upgrade_data_params( $plugin, $params ) {
4732 4034 $link = FrmAddonsController::install_link( $plugin );
4733 -
4734 4035 if ( ! $link ) {
4735 4036 return $params;
4736 4037 }
4737 4038
@@ -4737,20 +4038,15 @@
4737 4038
4738 4039 if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
4739 4040 $params['oneclick'] = json_encode( $link );
4740 4041 unset( $params['message'] );
4741 -
4742 4042 if ( ! isset( $params['medium'] ) ) {
4743 4043 $params['medium'] = $plugin;
4744 4044 }
4745 4045 } else {
4746 - $params['requires'] = $params['requires'] ?? FrmFormsHelper::get_plan_required( $link );
4046 + $params['requires'] = FrmFormsHelper::get_plan_required( $link );
4747 4047 }
4748 4048
4749 - if ( $detailed ) {
4750 - $params['plugin-status'] = $link['status'] ?? '';
4751 - }
4752 -
4753 4049 return $params;
4754 4050 }
4755 4051
4756 4052 /**
@@ -4759,9 +4055,8 @@
4759 4055 *
4760 4056 * @since 5.0.17
4761 4057 *
4762 4058 * @param string $text
4763 - *
4764 4059 * @return bool
4765 4060 */
4766 4061 public static function ctype_xdigit( $text ) {
4767 4062 if ( function_exists( 'ctype_xdigit' ) ) {
@@ -4776,14 +4071,12 @@
4776 4071 * @since 5.2.01
4777 4072 */
4778 4073 public static function set_current_screen_and_hook_suffix() {
4779 4074 global $hook_suffix;
4780 -
4781 4075 if ( is_null( $hook_suffix ) ) {
4782 4076 // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
4783 4077 $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
4784 4078 }
4785 -
4786 4079 set_current_screen();
4787 4080 }
4788 4081
4789 4082 /**
@@ -4790,9 +4083,9 @@
4790 4083 * Shows pill text.
4791 4084 *
4792 4085 * @since 5.2.02
4793 4086 *
4794 - * @param string|null $text Text in the pill. Default is NEW.
4087 + * @param string $text Text in the pill. Default is NEW.
4795 4088 */
4796 4089 public static function show_pill_text( $text = null ) {
4797 4090 if ( null === $text ) {
4798 4091 $text = __( 'NEW', 'formidable' );
@@ -4805,9 +4098,8 @@
4805 4098 *
4806 4099 * @since 5.2.07
4807 4100 *
4808 4101 * @param mixed $num Number.
4809 - *
4810 4102 * @return false|int Returns `false` if the passed parameter is not number.
4811 4103 */
4812 4104 public static function count_decimals( $num ) {
4813 4105 if ( ! is_numeric( $num ) ) {
@@ -4815,9 +4107,8 @@
4815 4107 }
4816 4108
4817 4109 $num = (string) $num;
4818 4110 $parts = explode( '.', $num );
4819 -
4820 4111 if ( 1 === count( $parts ) ) {
4821 4112 return 0;
4822 4113 }
4823 4114
@@ -4899,20 +4190,17 @@
4899 4190 * @since 5.5.5
4900 4191 *
4901 4192 * @param string $url
4902 4193 * @param string $expected_extension
4903 - *
4904 4194 * @return bool
4905 4195 */
4906 4196 public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
4907 - $file_is_in_expected_s3_bucket = str_starts_with( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4908 -
4197 + $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4909 4198 if ( ! $file_is_in_expected_s3_bucket ) {
4910 4199 return false;
4911 4200 }
4912 4201
4913 4202 $parsed = parse_url( $url );
4914 -
4915 4203 if ( ! is_array( $parsed ) ) {
4916 4204 // URL is malformed.
4917 4205 return false;
4918 4206 }
@@ -4918,10 +4206,14 @@
4918 4206 }
4919 4207
4920 4208 $path = $parsed['path'];
4921 4209 $ext = pathinfo( $path, PATHINFO_EXTENSION );
4922 - // The URL isn't to an XML file.
4923 - return $expected_extension === $ext;
4210 + if ( $expected_extension !== $ext ) {
4211 + // The URL isn't to an XML file.
4212 + return false;
4213 + }
4214 +
4215 + return true;
4924 4216 }
4925 4217
4926 4218 /**
4927 4219 * Display a dismissable warning message and save its dismissal state.
@@ -4929,9 +4221,8 @@
4929 4221 * @since 6.3
4930 4222 *
4931 4223 * @param string $message The warning message to display.
4932 4224 * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
4933 - *
4934 4225 * @return void
4935 4226 */
4936 4227 public static function add_dismissable_warning_message( $message = '', $option = '' ) {
4937 4228 if ( ! $message || ! $option ) {
@@ -4974,9 +4265,8 @@
4974 4265 *
4975 4266 * @since 6.3
4976 4267 *
4977 4268 * @param string $option The unique identifier for the dismissal state of the message.
4978 - *
4979 4269 * @return void
4980 4270 */
4981 4271 public static function dismiss_warning_message( $option = '' ) {
4982 4272 self::permission_check( 'frm_change_settings' );
@@ -4982,9 +4272,9 @@
4982 4272 self::permission_check( 'frm_change_settings' );
4983 4273 check_ajax_referer( 'frm_ajax', 'nonce' );
4984 4274
4985 4275 if ( $option ) {
4986 - update_option( $option, true, false );
4276 + update_option( $option, true, 'no' );
4987 4277 }
4988 4278
4989 4279 wp_send_json_success();
4990 4280 }
@@ -4998,8 +4288,17 @@
4998 4288 * @return string
4999 4289 */
5000 4290 public static function copy_for_lite_license() {
5001 4291 $message = __( 'You\'re using Formidable Forms Lite - no license needed. Enjoy!', 'formidable' ) . ' 🙂';
4292 +
4293 + if ( is_callable( 'FrmProAddonsController::get_readable_license_type' ) && ! class_exists( 'FrmProDashboardController' ) ) {
4294 + // Manage PRO versions without PRO dashboard functionality.
4295 + $license_type = FrmProAddonsController::get_readable_license_type();
4296 + if ( 'lite' !== strtolower( $license_type ) ) {
4297 + $message = 'Formidable Pro ' . $license_type;
4298 + }
4299 + }
4300 +
5002 4301 return apply_filters( 'frm_license_type_text', $message );
5003 4302 }
5004 4303
5005 4304 /**
@@ -5005,9 +4304,8 @@
5005 4304 /**
5006 4305 * Removes scripts that are unnecessarily loaded across the pages!
5007 4306 *
5008 4307 * @since 6.9
5009 - *
5010 4308 * @return void
5011 4309 */
5012 4310 public static function dequeue_extra_global_scripts() {
5013 4311 wp_dequeue_script( 'frm-surveys-admin' );
@@ -5025,21 +4323,18 @@
5025 4323 * @return void
5026 4324 */
5027 4325 public static function tooltip_icon( $tooltip_text, $atts = array() ) {
5028 4326 $atts['title'] = $tooltip_text;
5029 -
5030 4327 if ( isset( $atts['class'] ) ) {
5031 4328 $atts['class'] .= ' frm_help';
5032 4329 } else {
5033 4330 $atts['class'] = 'frm_help';
5034 4331 }
5035 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5036 4332 ?>
5037 4333 <span <?php self::array_to_html_params( $atts, true ); ?>>
5038 4334 <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?>
5039 4335 </span>
5040 4336 <?php
5041 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5042 4337 }
5043 4338
5044 4339 /**
5045 4340 * Prints errors for settings in onboarding wizard or template settings.
@@ -5060,10 +4355,8 @@
5060 4355 )
5061 4356 );
5062 4357
5063 4358 $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden';
5064 -
5065 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
5066 4359 ?>
5067 4360 <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>">
5068 4361 <?php
5069 4362 if ( is_array( $args['errors'] ) ) {
@@ -5077,87 +4370,6 @@
5077 4370 }
5078 4371 ?>
5079 4372 </span>
5080 4373 <?php
5081 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
5082 - }
5083 -
5084 - /**
5085 - * Check if GDPR is enabled.
5086 - *
5087 - * @since 6.19
5088 - *
5089 - * @return bool
5090 - */
5091 - public static function is_gdpr_enabled() {
5092 - $frm_settings = self::get_settings();
5093 - return $frm_settings->enable_gdpr || $frm_settings->no_ips || $frm_settings->custom_header_ip || $frm_settings->no_gdpr_cookies;
5094 - }
5095 -
5096 - /**
5097 - * Check if GDPR cookies are disabled.
5098 - *
5099 - * @since 6.19
5100 - *
5101 - * @return bool
5102 - */
5103 - public static function no_gdpr_cookies() {
5104 - $frm_settings = self::get_settings();
5105 - return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies;
5106 - }
5107 -
5108 - /**
5109 - * Check if a string is valid UTF-8.
5110 - *
5111 - * @since 6.24
5112 - *
5113 - * @param string|null $string The string to check.
5114 - *
5115 - * @return bool
5116 - */
5117 - public static function is_valid_utf8( $string ) {
5118 - if ( is_null( $string ) ) {
5119 - // Return true so we do not attempt to change encoding on a null value.
5120 - return true;
5121 - }
5122 -
5123 - // wp_is_valid_utf8 is added in WP 6.9.
5124 - if ( function_exists( 'wp_is_valid_utf8' ) ) {
5125 - return wp_is_valid_utf8( $string );
5126 - }
5127 -
5128 - // As of WP 6.9, seems_utf8 is deprecated.
5129 - return function_exists( 'seems_utf8' ) ? seems_utf8( $string ) : false;
5130 - }
5131 -
5132 - /**
5133 - * Get a documentation URL with UTM parameters and affiliate tracking.
5134 - *
5135 - * @since 6.26
5136 - *
5137 - * @param string $path The relative path to append to the base URL.
5138 - * @param string $campaign The campaign to use for UTM parameters.
5139 - * @param bool $add_kb_base Whether to prepend 'knowledgebase/' to the path. Default true.
5140 - *
5141 - * @return string The processed URL with UTM parameters and affiliate tracking.
5142 - */
5143 - public static function get_doc_url( $path, $campaign, $add_kb_base = true ) {
5144 - $path = trim( $path, '/' );
5145 -
5146 - if ( $add_kb_base ) {
5147 - $path = 'knowledgebase/' . $path;
5148 - }
5149 -
5150 - return self::maybe_add_missing_utm( 'https://formidableforms.com/' . $path, array( 'campaign' => $campaign ) );
5151 - }
5152 -
5153 - /**
5154 - * @since 5.0.16
5155 - * @deprecated 6.26
5156 - *
5157 - * @return bool
5158 - */
5159 - public static function show_landing_pages() {
5160 - _deprecated_function( __METHOD__, '6.26' );
5161 - return true;
5162 4374 }
5163 4375 }