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