PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.21
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.21
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 +433 -888 6.296.21 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 = 104;
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.29';
32 + public static $plug_version = '6.21';
33 33
34 34 /**
35 35 * @var bool
36 36 */
@@ -55,9 +55,9 @@
55 55 /**
56 56 * @return string
57 57 */
58 58 public static function plugin_path() {
59 - return dirname( __DIR__, 2 );
59 + return dirname( dirname( __DIR__ ) );
60 60 }
61 61
62 62 /**
63 63 * @return string
@@ -85,9 +85,8 @@
85 85 * Get the name of this site
86 86 * Used for [sitename] shortcode
87 87 *
88 88 * @since 2.0
89 - *
90 89 * @return string
91 90 */
92 91 public static function site_name() {
93 92 return get_option( 'blogname' );
@@ -94,15 +93,13 @@
94 93 }
95 94
96 95 /**
97 96 * @param string $url
98 - *
99 97 * @return string
100 98 */
101 99 public static function make_affiliate_url( $url ) {
102 100 $affiliate_id = self::get_affiliate();
103 -
104 - if ( $affiliate_id ) {
101 + if ( ! empty( $affiliate_id ) ) {
105 102 $url = str_replace( array( 'http://', 'https://' ), '', $url );
106 103 $url = 'http://www.shareasale.com/r.cfm?u=' . absint( $affiliate_id ) . '&b=841990&m=64739&afftrack=plugin&urllink=' . urlencode( $url );
107 104 }
108 105
@@ -117,124 +114,55 @@
117 114 }
118 115
119 116 /**
120 117 * @since 3.04.02
121 - *
122 - * @param array|string $args If a string is passed, it is used for the utm_campaign attribute.
118 + * @param array|string $args
123 119 * @param string $page
124 120 */
125 121 public static function admin_upgrade_link( $args, $page = '' ) {
126 - if ( $page ) {
122 + if ( empty( $page ) ) {
123 + $page = 'https://formidableforms.com/lite-upgrade/';
124 + } else {
127 125 $page = str_replace( 'https://formidableforms.com/', '', $page );
128 126 $page = 'https://formidableforms.com/' . $page;
127 + }
128 +
129 + $anchor = '';
130 + if ( is_array( $args ) ) {
131 + $medium = isset( $args['medium'] ) ? $args['medium'] : '';
132 + if ( isset( $args['content'] ) ) {
133 + $content = $args['content'];
134 + }
135 + if ( isset( $args['anchor'] ) ) {
136 + $anchor = '#' . $args['anchor'];
137 + }
129 138 } else {
130 - $page = 'https://formidableforms.com/lite-upgrade/';
139 + $medium = $args;
131 140 }
132 141
133 - $args = is_array( $args ) ? self::adjust_legacy_utm_args( $args ) : array( 'campaign' => $args );
134 -
135 142 $query_args = array(
136 - 'utm_source' => 'plugin',
137 - 'utm_medium' => self::get_utm_medium(),
143 + 'utm_source' => 'WordPress',
144 + 'utm_medium' => $medium,
145 + 'utm_campaign' => 'liteplugin',
138 146 );
139 - $query_args = self::maybe_add_utm_license( $query_args );
140 147
141 - if ( isset( $args['campaign'] ) ) {
142 - $query_args['utm_campaign'] = $args['campaign'];
148 + if ( isset( $content ) ) {
149 + $query_args['utm_content'] = $content;
143 150 }
144 151
145 - if ( isset( $args['content'] ) ) {
146 - $query_args['utm_content'] = $args['content'];
147 - }
148 -
149 - if ( isset( $args['param'] ) ) {
152 + if ( is_array( $args ) && isset( $args['param'] ) ) {
150 153 $query_args['f'] = $args['param'];
151 154 }
152 155
153 - if ( ! empty( $args['plan'] ) ) {
156 + if ( is_array( $args ) && ! empty( $args['plan'] ) ) {
154 157 $query_args['plan'] = $args['plan'];
155 158 }
156 159
157 - $link = add_query_arg( $query_args, $page );
158 -
159 - if ( isset( $args['anchor'] ) ) {
160 - $link .= '#' . $args['anchor'];
161 - }
162 -
160 + $link = add_query_arg( $query_args, $page ) . $anchor;
163 161 return self::make_affiliate_url( $link );
164 162 }
165 163
166 164 /**
167 - * If medium is "pro", add an additional utm_license param with their active license type.
168 - *
169 - * @since 6.25.1
170 - *
171 - * @param array $query_args
172 - * @param string $link
173 - *
174 - * @return array
175 - */
176 - private static function maybe_add_utm_license( $query_args, $link = '' ) {
177 - $medium = $query_args['utm_medium'] ?? self::pull_medium_from_link( $link );
178 -
179 - if ( 'pro' === $medium && is_callable( 'FrmProAddonsController::get_readable_license_type' ) ) {
180 - $query_args['utm_license'] = strtolower( FrmProAddonsController::get_readable_license_type() );
181 - }
182 -
183 - return $query_args;
184 - }
185 -
186 - /**
187 - * @since 6.26
188 - *
189 - * @param string $link
190 - *
191 - * @return string
192 - */
193 - private static function pull_medium_from_link( $link ) {
194 - if ( ! $link ) {
195 - return '';
196 - }
197 -
198 - $parsed = parse_url( $link );
199 -
200 - if ( ! is_array( $parsed ) || ! isset( $parsed['query'] ) ) {
201 - return '';
202 - }
203 -
204 - $query_args = wp_parse_args( $parsed['query'] );
205 -
206 - return ! empty( $query_args['utm_medium'] ) ? $query_args['utm_medium'] : '';
207 - }
208 -
209 - /**
210 - * @since 6.25.1
211 - *
212 - * @return string
213 - */
214 - private static function get_utm_medium() {
215 - return self::pro_is_connected() ? 'pro' : 'lite';
216 - }
217 -
218 - /**
219 - * Change campaign from "liteplugin" to what we're currently using for medium.
220 - *
221 - * @since 6.25.1
222 - *
223 - * @param array $args
224 - *
225 - * @return array
226 - */
227 - private static function adjust_legacy_utm_args( $args ) {
228 - if ( isset( $args['medium'] ) ) {
229 - $args['campaign'] = $args['medium'];
230 - unset( $args['medium'] );
231 - }
232 -
233 - return $args;
234 - }
235 -
236 - /**
237 165 * @since 6.21
238 166 *
239 167 * @param string $cta_link
240 168 * @param array $utm
@@ -239,29 +167,26 @@
239 167 * @param string $cta_link
240 168 * @param array $utm
241 169 */
242 170 public static function maybe_add_missing_utm( $cta_link, $utm ) {
243 - $utm = self::adjust_legacy_utm_args( $utm );
244 171 $query_args = array();
245 172
246 - if ( ! str_contains( $cta_link, 'utm_source' ) ) {
247 - $query_args['utm_source'] = 'plugin';
173 + if ( false === strpos( $cta_link, 'utm_source' ) ) {
174 + $query_args['utm_source'] = 'WordPress';
248 175 }
249 176
250 - if ( ! str_contains( $cta_link, 'utm_medium' ) ) {
251 - $query_args['utm_medium'] = self::get_utm_medium();
177 + if ( false === strpos( $cta_link, 'utm_campaign' ) ) {
178 + $query_args['utm_campaign'] = 'liteplugin';
252 179 }
253 180
254 - if ( ! str_contains( $cta_link, 'utm_campaign' ) && isset( $utm['campaign'] ) ) {
255 - $query_args['utm_campaign'] = $utm['campaign'];
181 + if ( false === strpos( $cta_link, 'utm_medium' ) && isset( $utm['medium'] ) ) {
182 + $query_args['utm_medium'] = $utm['medium'];
256 183 }
257 184
258 - if ( ! str_contains( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) {
185 + if ( false === strpos( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) {
259 186 $query_args['utm_content'] = $utm['content'];
260 187 }
261 188
262 - $query_args = self::maybe_add_utm_license( $query_args, $cta_link );
263 -
264 189 return $query_args ? add_query_arg( $query_args, $cta_link ) : $cta_link;
265 190 }
266 191
267 192 /**
@@ -269,15 +194,13 @@
269 194 *
270 195 * @since 2.0
271 196 *
272 197 * @param array $args - May include the form id when values need translation.
273 - *
274 - * @return FrmSettings
198 + * @return FrmSettings $frm_settings
275 199 */
276 200 public static function get_settings( $args = array() ) {
277 201 global $frm_settings;
278 -
279 - if ( ! $frm_settings ) {
202 + if ( empty( $frm_settings ) ) {
280 203 $frm_settings = new FrmSettings( $args );
281 204 } elseif ( isset( $args['current_form'] ) ) {
282 205 // If the global has already been set, allow strings to be filtered.
283 206 $frm_settings->maybe_filter_for_form( $args );
@@ -289,13 +212,11 @@
289 212 /**
290 213 * @return string
291 214 */
292 215 public static function get_menu_name() {
293 - if ( ! self::pro_is_installed() || FrmAddonsController::is_license_expired() ) {
294 - return 'Formidable';
295 - }
216 + $frm_settings = self::get_settings();
296 217
297 - return self::get_settings()->menu;
218 + return FrmAddonsController::is_license_expired() ? 'Formidable' : $frm_settings->menu;
298 219 }
299 220
300 221 /**
301 222 * Determine if the current branding is set to 'formidable'.
@@ -310,9 +231,9 @@
310 231 return true;
311 232 }
312 233
313 234 $menu_icon = self::get_menu_icon_class();
314 - return str_contains( $menu_icon, 'frm_logo_icon' );
235 + return strpos( $menu_icon, 'frm_logo_icon' ) !== false;
315 236 }
316 237
317 238 /**
318 239 * @since 3.05
@@ -317,9 +238,8 @@
317 238 /**
318 239 * @since 3.05
319 240 *
320 241 * @param array $atts
321 - *
322 242 * @return string
323 243 */
324 244 public static function svg_logo( $atts = array() ) {
325 245 $defaults = array(
@@ -329,14 +249,12 @@
329 249 'orange' => '#f05a24',
330 250 );
331 251 $atts = array_merge( $defaults, $atts );
332 252
333 - // phpcs:disable SlevomatCodingStandard.Files.LineLength.LineTooLong
334 253 return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 599.68 601.37" width="' . esc_attr( $atts['width'] ) . '" height="' . esc_attr( $atts['height'] ) . '">
335 254 <path fill="' . esc_attr( $atts['orange'] ) . '" d="M289.6 384h140v76h-140z"/>
336 255 <path fill="' . esc_attr( $atts['fill'] ) . '" d="M400.2 147h-200c-17 0-30.6 12.2-30.6 29.3V218h260v-71zM397.9 264H169.6v196h75V340H398a32.2 32.2 0 0 0 30.1-21.4 24.3 24.3 0 0 0 1.7-8.7V264zM299.8 601.4A300.3 300.3 0 0 1 0 300.7a299.8 299.8 0 1 1 511.9 212.6 297.4 297.4 0 0 1-212 88zm0-563A262 262 0 0 0 38.3 300.7a261.6 261.6 0 1 0 446.5-185.5 259.5 259.5 0 0 0-185-76.8z"/>
337 256 </svg>';
338 - // phpcs:enable SlevomatCodingStandard.Files.LineLength.LineTooLong
339 257 }
340 258
341 259 /**
342 260 * @since 4.0
@@ -341,13 +259,12 @@
341 259 /**
342 260 * @since 4.0
343 261 *
344 262 * @param array $atts
345 - *
346 263 * @return void
347 264 */
348 265 public static function show_logo( $atts = array() ) {
349 - self::kses_echo( self::svg_logo( $atts ), 'all' );
266 + echo self::kses( self::svg_logo( $atts ), 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
350 267 }
351 268
352 269 /**
353 270 * @since 4.03.02
@@ -362,11 +279,10 @@
362 279 )
363 280 );
364 281
365 282 $new_icon = apply_filters( 'frm_icon', $icon, true );
366 -
367 283 if ( $new_icon !== $icon ) {
368 - if ( str_starts_with( $new_icon, '<svg' ) ) {
284 + if ( strpos( $new_icon, '<svg' ) === 0 ) {
369 285 $icon = str_replace( 'viewBox="0 0 20', 'width="30" height="35" style="color:#929699" viewBox="0 0 20', $new_icon );
370 286 } else {
371 287 // Show nothing if it isn't an SVG.
372 288 $icon = '<div style="height:39px"></div>';
@@ -371,9 +287,9 @@
371 287 // Show nothing if it isn't an SVG.
372 288 $icon = '<div style="height:39px"></div>';
373 289 }
374 290 }
375 - self::kses_echo( $icon, 'all' );
291 + echo self::kses( $icon, 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
376 292 }
377 293
378 294 /**
379 295 * @since 2.02.04
@@ -423,13 +339,11 @@
423 339 */
424 340 public static function is_form_builder_page( $check_for_settings = true ) {
425 341 $action = self::simple_get( 'frm_action', 'sanitize_title' );
426 342 $check_actions = array( 'edit', 'duplicate' );
427 -
428 343 if ( $check_for_settings ) {
429 344 $check_actions[] = 'settings';
430 345 }
431 -
432 346 return self::is_admin_page( 'formidable' ) && in_array( $action, $check_actions, true );
433 347 }
434 348
435 349 /**
@@ -435,15 +349,15 @@
435 349 /**
436 350 * @return bool
437 351 */
438 352 public static function is_formidable_admin() {
439 - $page = self::simple_get( 'page', 'sanitize_title' );
440 -
441 - if ( ! $page ) {
442 - return self::is_view_builder_page();
353 + $page = self::simple_get( 'page', 'sanitize_title' );
354 + $is_formidable = strpos( $page, 'formidable' ) !== false;
355 + if ( empty( $page ) ) {
356 + $is_formidable = self::is_view_builder_page();
443 357 }
444 358
445 - return str_contains( $page, 'formidable' );
359 + return $is_formidable;
446 360 }
447 361
448 362 /**
449 363 * Checks if is a list page.
@@ -450,9 +364,8 @@
450 364 *
451 365 * @since 6.19
452 366 *
453 367 * @param string $page The name of the page to check.
454 - *
455 368 * @return bool
456 369 */
457 370 public static function is_admin_list_page( $page = 'formidable' ) {
458 371 if ( 'formidable' === $page ) {
@@ -464,9 +377,8 @@
464 377 }
465 378
466 379 if ( 'formidable-entries' === $page ) {
467 380 $action = self::simple_get( 'frm_action' );
468 -
469 381 if ( ! $action || in_array( $action, self::get_entries_listing_page_form_actions(), true ) ) {
470 382 return true;
471 383 }
472 384 }
@@ -495,13 +407,11 @@
495 407 */
496 408 public static function is_admin_page( $page = 'formidable' ) {
497 409 global $pagenow;
498 410 $get_page = self::simple_get( 'page', 'sanitize_title' );
499 -
500 411 if ( $pagenow ) {
501 - // Allow this to be true during ajax load i.e. ajax form builder loading
412 + // allow this to be true during ajax load i.e. ajax form builder loading
502 413 $is_page = ( $pagenow === 'admin.php' || $pagenow === 'admin-ajax.php' ) && $get_page === $page;
503 -
504 414 if ( $is_page ) {
505 415 return true;
506 416 }
507 417 }
@@ -519,15 +429,15 @@
519 429 */
520 430 public static function is_view_builder_page() {
521 431 global $pagenow;
522 432
523 - if ( ! in_array( $pagenow, array( 'post.php', 'post-new.php', 'edit.php' ), true ) ) {
433 + if ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' && $pagenow !== 'edit.php' ) {
524 434 return false;
525 435 }
526 436
527 437 $post_type = self::simple_get( 'post_type', 'sanitize_title' );
528 438
529 - if ( ! $post_type ) {
439 + if ( empty( $post_type ) ) {
530 440 $post_id = self::simple_get( 'post', 'absint' );
531 441 $post = get_post( $post_id );
532 442 $post_type = $post ? $post->post_type : '';
533 443 }
@@ -545,9 +455,9 @@
545 455 public static function is_preview_page() {
546 456 global $pagenow;
547 457 $action = self::simple_get( 'action', 'sanitize_title' );
548 458
549 - return $pagenow === 'admin-ajax.php' && $action === 'frm_forms_preview';
459 + return $pagenow && $pagenow === 'admin-ajax.php' && $action === 'frm_forms_preview';
550 460 }
551 461
552 462 /**
553 463 * Check for ajax except the form preview page
@@ -568,9 +478,8 @@
568 478 }
569 479
570 480 /**
571 481 * @since 2.0.8
572 - *
573 482 * @return bool
574 483 */
575 484 public static function prevent_caching() {
576 485 global $frm_vars;
@@ -588,9 +497,8 @@
588 497 $is_admin = is_admin() && ! wp_doing_ajax();
589 498
590 499 /**
591 500 * @since 6.0
592 - *
593 501 * @param bool $is_admin
594 502 */
595 503 return apply_filters( 'frm_is_admin', $is_admin );
596 504 }
@@ -605,15 +513,14 @@
605 513 *
606 514 * @return bool
607 515 */
608 516 public static function is_empty_value( $value, $empty = '' ) {
609 - return $value === array() || $value === $empty;
517 + return ( is_array( $value ) && empty( $value ) ) || $value === $empty;
610 518 }
611 519
612 520 /**
613 521 * @param mixed $value
614 522 * @param string $empty
615 - *
616 523 * @return bool
617 524 */
618 525 public static function is_not_empty_value( $value, $empty = '' ) {
619 526 return ! self::is_empty_value( $value, $empty );
@@ -667,9 +574,8 @@
667 574 continue;
668 575 }
669 576
670 577 $key = self::get_server_value( $key );
671 -
672 578 foreach ( explode( ',', $key ) as $ip ) {
673 579 // Just to be safe.
674 580 $ip = trim( $ip );
675 581
@@ -725,26 +631,16 @@
725 631 */
726 632 return apply_filters( 'frm_use_custom_header_ip', $should_use_custom_header_ip );
727 633 }
728 634
729 - /**
730 - * @param string $param
731 - * @param mixed $default
732 - * @param string $src
733 - * @param callable|string $sanitize
734 - *
735 - * @return mixed
736 - */
737 635 public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
738 - if ( str_contains( $param, '[' ) ) {
636 + if ( strpos( $param, '[' ) ) {
739 637 $params = explode( '[', $param );
740 638 $param = $params[0];
741 639 }
742 640
743 641 if ( $src === 'get' ) {
744 - // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
745 - $value = isset( $_POST[ $param ] ) ? wp_unslash( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? wp_unslash( $_GET[ $param ] ) : $default );
746 -
642 + $value = isset( $_POST[ $param ] ) ? wp_unslash( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? wp_unslash( $_GET[ $param ] ) : $default ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
747 643 if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
748 644 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
749 645 $value = htmlspecialchars_decode( wp_unslash( $_GET[ $param ] ) );
750 646 }
@@ -759,19 +655,17 @@
759 655 )
760 656 );
761 657 }
762 658
763 - if ( ! isset( $params ) || ! is_array( $value ) || ! $value ) {
764 - return $value;
765 - }
659 + if ( isset( $params ) && is_array( $value ) && ! empty( $value ) ) {
660 + foreach ( $params as $k => $p ) {
661 + if ( ! $k || ! is_array( $value ) ) {
662 + continue;
663 + }
766 664
767 - foreach ( $params as $k => $p ) {
768 - if ( ! $k || ! is_array( $value ) ) {
769 - continue;
665 + $p = trim( $p, ']' );
666 + $value = isset( $value[ $p ] ) ? $value[ $p ] : $default;
770 667 }
771 -
772 - $p = trim( $p, ']' );
773 - $value = $value[ $p ] ?? $default;
774 668 }
775 669
776 670 return $value;
777 671 }
@@ -782,9 +676,8 @@
782 676 * @param string $param The key we are trying to access data from in $_POST.
783 677 * @param mixed $default The default if nothing is being sent.
784 678 * @param callable|string $sanitize Make sure to pass a sanitize method here. This function will NOT sanitize by default.
785 679 * @param bool $serialized
786 - *
787 680 * @return mixed
788 681 */
789 682 public static function get_post_param( $param, $default = '', $sanitize = '', $serialized = false ) {
790 683 return self::get_simple_request(
@@ -804,9 +697,9 @@
804 697 * @param string $param
805 698 * @param string $sanitize
806 699 * @param string $default
807 700 *
808 - * @return array|int|string
701 + * @return array|string
809 702 */
810 703 public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) {
811 704 return self::get_simple_request(
812 705 array(
@@ -835,10 +728,10 @@
835 728 'sanitize' => 'sanitize_text_field',
836 729 'serialized' => false,
837 730 );
838 731 $args = wp_parse_args( $args, $defaults );
839 - $value = $args['default'];
840 732
733 + $value = $args['default'];
841 734 if ( $args['type'] === 'get' ) {
842 735 if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
843 736 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
844 737 $value = wp_unslash( $_GET[ $args['param'] ] );
@@ -846,16 +739,16 @@
846 739 } elseif ( $args['type'] === 'post' ) {
847 740 if ( isset( $_POST[ $args['param'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
848 741 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
849 742 $value = wp_unslash( $_POST[ $args['param'] ] );
850 -
851 743 if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) {
852 744 self::unserialize_or_decode( $value );
853 745 }
854 746 }
855 747 } elseif ( isset( $_REQUEST[ $args['param'] ] ) ) {
856 - // phpcs:ignore phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
857 - $value = wp_unslash( $_REQUEST[ $args['param'] ] );
748 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
749 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
750 + $value = wp_unslash( $_REQUEST[ $args['param'] ] );
858 751 }
859 752
860 753 self::sanitize_value( $args['sanitize'], $value );
861 754
@@ -868,13 +761,17 @@
868 761 * @since 2.0.8
869 762 *
870 763 * @param string $value
871 764 *
872 - * @return string Value.
765 + * @return string $value
873 766 */
874 767 public static function preserve_backslashes( $value ) {
875 768 // If backslashes have already been added, don't add them again
876 - return str_contains( $value, '\\\\' ) ? $value : addslashes( $value );
769 + if ( strpos( $value, '\\\\' ) === false ) {
770 + $value = addslashes( $value );
771 + }
772 +
773 + return $value;
877 774 }
878 775
879 776 /**
880 777 * Sanitize a value in-place.
@@ -881,9 +778,8 @@
881 778 * If $value is an array, the sanitize function will get called for each item.
882 779 *
883 780 * @param callable $sanitize
884 781 * @param mixed $value
885 - *
886 782 * @return void
887 783 */
888 784 public static function sanitize_value( $sanitize, &$value ) {
889 785 if ( ! $sanitize ) {
@@ -896,13 +792,11 @@
896 792 }
897 793
898 794 if ( is_array( $value ) ) {
899 795 $temp_values = $value;
900 -
901 796 foreach ( $temp_values as $k => $v ) {
902 797 self::sanitize_value( $sanitize, $value[ $k ] );
903 798 }
904 -
905 799 return;
906 800 }
907 801
908 802 $value = call_user_func( $sanitize, $value );
@@ -907,17 +801,10 @@
907 801
908 802 $value = call_user_func( $sanitize, $value );
909 803 }
910 804
911 - /**
912 - * @param array $sanitize_method
913 - * @param array $values
914 - *
915 - * @return void
916 - */
917 805 public static function sanitize_request( $sanitize_method, &$values ) {
918 806 $temp_values = $values;
919 -
920 807 foreach ( $temp_values as $k => $val ) {
921 808 if ( isset( $sanitize_method[ $k ] ) ) {
922 809 $values[ $k ] = call_user_func( $sanitize_method[ $k ], $val );
923 810 }
@@ -927,9 +814,8 @@
927 814 /**
928 815 * @since 4.0.04
929 816 *
930 817 * @param mixed $value
931 - *
932 818 * @return void
933 819 */
934 820 public static function sanitize_with_html( &$value ) {
935 821 if ( current_user_can( 'frm_edit_entries' ) || current_user_can( 'administrator' ) ) {
@@ -948,12 +834,8 @@
948 834 *
949 835 * @param string $value
950 836 */
951 837 public static function strip_most_html( $value ) {
952 - if ( '' === $value ) {
953 - return $value;
954 - }
955 -
956 838 $allowed_html = array(
957 839 'b' => array(),
958 840 'br' => array(),
959 841 'strong' => array(),
@@ -978,15 +860,12 @@
978 860 * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&amp;'
979 861 * this MUST be done, else we'll be back to the '& entity' problem.
980 862 *
981 863 * @since 4.0.04
982 - *
983 - * @param mixed $value Value to decode, passed by reference.
984 864 */
985 865 public static function decode_specialchars( &$value ) {
986 866 if ( is_array( $value ) ) {
987 867 $temp_values = $value;
988 -
989 868 foreach ( $temp_values as $k => $v ) {
990 869 self::decode_specialchars( $value[ $k ] );
991 870 }
992 871 } else {
@@ -1000,13 +879,13 @@
1000 879 * Adapted from wp_specialchars_decode().
1001 880 *
1002 881 * @since 4.03.01
1003 882 *
1004 - * @param string $string The string to prep, passed by reference.
883 + * @param string $string The string to prep.
1005 884 */
1006 885 private static function decode_amp( &$string ) {
1007 886 // Don't bother if there are no entities - saves a lot of processing
1008 - if ( ! $string || ! str_contains( $string, '&' ) ) {
887 + if ( empty( $string ) || strpos( $string, '&' ) === false ) {
1009 888 return;
1010 889 }
1011 890
1012 891 $translation = array(
@@ -1044,15 +923,16 @@
1044 923 * Sanitize the value, and allow some HTML
1045 924 *
1046 925 * @since 2.0
1047 926 *
1048 - * @param string $value The value to sanitize.
1049 - * @param array|string $allowed Allowed HTML tags and attributes, or 'all' for defaults.
927 + * @param string $value
928 + * @param array|string $allowed 'all' for everything included as defaults.
1050 929 *
1051 930 * @return string
1052 931 */
1053 932 public static function kses( $value, $allowed = array() ) {
1054 933 $allowed_html = self::allowed_html( $allowed );
934 +
1055 935 return wp_kses( $value, $allowed_html );
1056 936 }
1057 937
1058 938 /**
@@ -1061,9 +941,8 @@
1061 941 * @since 6.18
1062 942 *
1063 943 * @param string $value The value to sanitize and output.
1064 944 * @param array|string $allowed Allowed HTML tags and attributes.
1065 - *
1066 945 * @return void
1067 946 */
1068 947 public static function kses_echo( $value, $allowed = array() ) {
1069 948 echo self::kses( $value, $allowed ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -1074,23 +953,21 @@
1074 953 *
1075 954 * @since 5.0.13
1076 955 *
1077 956 * @param string $html
1078 - *
1079 957 * @return string
1080 958 */
1081 959 public static function kses_submit_button( $html ) {
1082 - $included_button_action = str_contains( $html, '[button_action]' );
1083 - $included_back_hook = str_contains( $html, '[back_hook]' );
1084 - $included_draft_hook = str_contains( $html, '[draft_hook]' );
960 + $included_button_action = false !== strpos( $html, '[button_action]' );
961 + $included_back_hook = false !== strpos( $html, '[back_hook]' );
962 + $included_draft_hook = false !== strpos( $html, '[draft_hook]' );
1085 963 add_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1086 964 add_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1087 965 $html = self::kses( $html, 'all' );
1088 966 remove_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1089 967 remove_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1090 -
1091 968 if ( $included_button_action ) {
1092 - if ( str_contains( $html, '<input type="submit"' ) ) {
969 + if ( false !== strpos( $html, '<input type="submit"' ) ) {
1093 970 $pattern = '/(<input type="submit")([^>]*)(\/>)/';
1094 971 $html = preg_replace( $pattern, '$1$2[button_action] $3', $html, 1 );
1095 972 } else {
1096 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
@@ -1096,17 +973,14 @@
1096 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
1097 974 $html = preg_replace( $pattern, '$1$2$3$4$5$6$7 [button_action]$8$9$10', $html, 1 );
1098 975 }
1099 976 }
1100 -
1101 977 if ( $included_back_hook ) {
1102 978 $html = str_replace( 'class="frm_prev_page"', 'class="frm_prev_page" [back_hook]', $html );
1103 979 }
1104 -
1105 980 if ( $included_draft_hook ) {
1106 - return str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html );
981 + $html = str_replace( 'class="frm_save_draft"', 'class="frm_save_draft" [draft_hook]', $html );
1107 982 }
1108 -
1109 983 return $html;
1110 984 }
1111 985
1112 986 /**
@@ -1112,9 +986,8 @@
1112 986 /**
1113 987 * @since 5.0.13
1114 988 *
1115 989 * @param array $allowed_attr
1116 - *
1117 990 * @return array
1118 991 */
1119 992 public static function allow_visibility_style( $allowed_attr ) {
1120 993 $allowed_attr[] = 'visibility';
@@ -1124,9 +997,8 @@
1124 997 /**
1125 998 * @since 5.0.13
1126 999 *
1127 1000 * @param array $allowed_html
1128 - *
1129 1001 * @return array
1130 1002 */
1131 1003 public static function add_allowed_submit_button_tags( $allowed_html ) {
1132 1004 $allowed_html['input'] = array(
@@ -1143,22 +1015,17 @@
1143 1015 }
1144 1016
1145 1017 /**
1146 1018 * @since 2.05.03
1147 - *
1148 - * @param array|string $allowed
1149 - *
1150 - * @return array
1151 1019 */
1152 1020 private static function allowed_html( $allowed ) {
1153 1021 $html = self::safe_html();
1154 1022 $allowed_html = array();
1155 -
1156 1023 if ( $allowed === 'all' ) {
1157 1024 $allowed_html = $html;
1158 - } elseif ( $allowed ) {
1025 + } elseif ( ! empty( $allowed ) ) {
1159 1026 foreach ( (array) $allowed as $a ) {
1160 - $allowed_html[ $a ] = $html[ $a ] ?? array();
1027 + $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
1161 1028 }
1162 1029 }
1163 1030
1164 1031 return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
@@ -1165,10 +1032,8 @@
1165 1032 }
1166 1033
1167 1034 /**
1168 1035 * @since 2.05.03
1169 - *
1170 - * @return array
1171 1036 */
1172 1037 private static function safe_html() {
1173 1038 $allow_class = array(
1174 1039 'class' => true,
@@ -1320,16 +1185,14 @@
1320 1185 return;
1321 1186 }
1322 1187
1323 1188 $action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' );
1324 -
1325 - if ( ! $action_name ) {
1189 + if ( empty( $action_name ) ) {
1326 1190 return;
1327 1191 }
1328 1192
1329 1193 $new_action = self::get_param( $action_name, '', 'get', 'sanitize_text_field' );
1330 -
1331 - if ( $new_action ) {
1194 + if ( ! empty( $new_action ) ) {
1332 1195 $_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', self::get_server_value( 'REQUEST_URI' ) );
1333 1196 }
1334 1197 }
1335 1198
@@ -1336,23 +1199,21 @@
1336 1199 /**
1337 1200 * Check the WP query for a parameter
1338 1201 *
1339 1202 * @since 2.0
1340 - *
1341 - * @param array|string $value
1342 - * @param string $param
1343 - *
1344 1203 * @return array|string
1345 1204 */
1346 1205 public static function get_query_var( $value, $param ) {
1347 - // phpcs:ignore Universal.Operators.StrictComparisons
1348 1206 if ( $value != '' ) {
1349 1207 return $value;
1350 1208 }
1351 1209
1352 1210 global $wp_query;
1211 + if ( isset( $wp_query->query_vars[ $param ] ) ) {
1212 + $value = $wp_query->query_vars[ $param ];
1213 + }
1353 1214
1354 - return $wp_query->query_vars[ $param ] ?? $value;
1215 + return $value;
1355 1216 }
1356 1217
1357 1218 /**
1358 1219 * Try to show the SVG if possible. Otherwise, use the font icon.
@@ -1360,21 +1221,20 @@
1360 1221 * @since 4.0.02
1361 1222 *
1362 1223 * @param string $class
1363 1224 * @param array $atts
1364 - *
1365 1225 * @return string|null
1366 1226 */
1367 1227 public static function icon_by_class( $class, $atts = array() ) {
1368 1228 $echo = ! isset( $atts['echo'] ) || $atts['echo'];
1369 -
1370 1229 if ( isset( $atts['echo'] ) ) {
1371 1230 unset( $atts['echo'] );
1372 1231 }
1373 1232
1374 1233 $html_atts = self::array_to_html_params( $atts );
1375 - $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1376 1234
1235 + $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1236 +
1377 1237 // Replace icons that have been removed or renamed.
1378 1238 $deprecated = array(
1379 1239 'frm_clone_solid_icon' => 'frm_clone_icon',
1380 1240 'frm_keyalt_icon' => 'frm_key_icon',
@@ -1379,9 +1239,8 @@
1379 1239 'frm_clone_solid_icon' => 'frm_clone_icon',
1380 1240 'frm_keyalt_icon' => 'frm_key_icon',
1381 1241 'frm_keyalt_solid_icon' => 'frm_key_solid_icon',
1382 1242 );
1383 -
1384 1243 if ( isset( $deprecated[ $icon ] ) ) {
1385 1244 $icon = $deprecated[ $icon ];
1386 1245 $class = str_replace( $icon, $deprecated[ $icon ], $class );
1387 1246 }
@@ -1388,24 +1247,21 @@
1388 1247
1389 1248 if ( $icon === $class ) {
1390 1249 $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
1391 1250 } else {
1392 - $class = str_contains( $icon, ' ' ) ? ' ' . $icon : '';
1393 -
1394 - if ( str_contains( $icon, ' ' ) ) {
1251 + $class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
1252 + if ( strpos( $icon, ' ' ) ) {
1395 1253 $icon = explode( ' ', $icon );
1396 1254 $icon = reset( $icon );
1397 1255 }
1398 -
1399 - $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use href="#' . esc_attr( $icon ) . '" /></svg>';
1256 + $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use xlink:href="#' . esc_attr( $icon ) . '" /></svg>';
1400 1257 }
1401 1258
1402 1259 if ( $echo ) {
1403 1260 echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1404 - return null;
1261 + } else {
1262 + return $icon;
1405 1263 }
1406 -
1407 - return $icon;
1408 1264 }
1409 1265
1410 1266 /**
1411 1267 * Run kses for icons. It needs to add a few filters first in order to preserve some custom style values.
@@ -1412,9 +1268,8 @@
1412 1268 *
1413 1269 * @since 5.0.13
1414 1270 *
1415 1271 * @param string $icon
1416 - *
1417 1272 * @return string
1418 1273 */
1419 1274 public static function kses_icon( $icon ) {
1420 1275 add_filter( 'safe_style_css', 'FrmAppHelper::allow_vars_in_styles' );
@@ -1430,15 +1285,13 @@
1430 1285 /**
1431 1286 * @since 5.0.13.1
1432 1287 *
1433 1288 * @param array $allowed_html
1434 - *
1435 1289 * @return array
1436 1290 */
1437 1291 public static function add_allowed_icon_tags( $allowed_html ) {
1438 1292 $allowed_html['svg']['data-open'] = true;
1439 1293 $allowed_html['svg']['title'] = true;
1440 - $allowed_html['svg']['tabindex'] = true;
1441 1294 return $allowed_html;
1442 1295 }
1443 1296
1444 1297 /**
@@ -1444,9 +1297,8 @@
1444 1297 /**
1445 1298 * @since 5.0.13
1446 1299 *
1447 1300 * @param array $allowed_attr
1448 - *
1449 1301 * @return array
1450 1302 */
1451 1303 public static function allow_vars_in_styles( $allowed_attr ) {
1452 1304 $allowed_attr[] = '--primary-700';
@@ -1459,9 +1311,9 @@
1459 1311 * @param bool $allow_css
1460 1312 * @param string $css_string
1461 1313 */
1462 1314 public static function allow_style( $allow_css, $css_string ) {
1463 - if ( ! $allow_css && str_starts_with( $css_string, '--primary-700:' ) ) {
1315 + if ( ! $allow_css && 0 === strpos( $css_string, '--primary-700:' ) ) {
1464 1316 $split = explode( ':', $css_string, 2 );
1465 1317 $allow_css = 2 === count( $split ) && self::is_a_valid_color( $split[1] );
1466 1318 }
1467 1319 return $allow_css;
@@ -1470,22 +1322,19 @@
1470 1322 /**
1471 1323 * @since 5.0.13
1472 1324 *
1473 1325 * @param string $value
1474 - *
1475 1326 * @return bool
1476 1327 */
1477 1328 private static function is_a_valid_color( $value ) {
1478 1329 $match = 0;
1479 -
1480 - if ( str_starts_with( $value, 'rgba(' ) ) {
1330 + if ( 0 === strpos( $value, 'rgba(' ) ) {
1481 1331 $match = preg_match( '/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/', $value );
1482 - } elseif ( str_starts_with( $value, 'rgb(' ) ) {
1332 + } elseif ( 0 === strpos( $value, 'rgb(' ) ) {
1483 1333 $match = preg_match( '/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/', $value );
1484 - } elseif ( str_starts_with( $value, '#' ) ) {
1334 + } elseif ( 0 === strpos( $value, '#' ) ) {
1485 1335 $match = preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})\b$/', $value );
1486 1336 }
1487 -
1488 1337 return (bool) $match;
1489 1338 }
1490 1339
1491 1340 /**
@@ -1491,9 +1340,8 @@
1491 1340 /**
1492 1341 * Include svg images.
1493 1342 *
1494 1343 * @since 4.0.02
1495 - *
1496 1344 * @return void
1497 1345 */
1498 1346 public static function include_svg() {
1499 1347 if ( self::$included_svg ) {
@@ -1512,20 +1360,17 @@
1512 1360 * @since 5.0.13 added $echo parameter.
1513 1361 *
1514 1362 * @param array $atts
1515 1363 * @param bool $echo
1516 - *
1517 1364 * @return string|void
1518 1365 */
1519 1366 public static function array_to_html_params( $atts, $echo = false ) {
1520 1367 $callback = function () use ( $atts ) {
1521 - if ( ! $atts ) {
1522 - return;
1368 + if ( $atts ) {
1369 + foreach ( $atts as $key => $value ) {
1370 + echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1371 + }
1523 1372 }
1524 -
1525 - foreach ( $atts as $key => $value ) {
1526 - echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
1527 - }
1528 1373 };
1529 1374 return self::clip( $callback, $echo );
1530 1375 }
1531 1376
@@ -1535,9 +1380,8 @@
1535 1380 * @since 5.0.13
1536 1381 *
1537 1382 * @param Closure $echo_function
1538 1383 * @param bool $echo
1539 - *
1540 1384 * @return string|null
1541 1385 */
1542 1386 public static function clip( $echo_function, $echo = false ) {
1543 1387 if ( ! $echo ) {
@@ -1547,9 +1391,13 @@
1547 1391 if ( is_callable( $echo_function ) ) {
1548 1392 $echo_function();
1549 1393 }
1550 1394
1551 - return $echo ? null : ob_get_clean();
1395 + if ( ! $echo ) {
1396 + $return = ob_get_contents();
1397 + ob_end_clean();
1398 + return $return;
1399 + }
1552 1400 }
1553 1401
1554 1402 /**
1555 1403 * @since 3.0
@@ -1554,18 +1402,15 @@
1554 1402 /**
1555 1403 * @since 3.0
1556 1404 *
1557 1405 * @param array $atts
1558 - *
1559 1406 * @return void
1560 1407 */
1561 1408 public static function get_admin_header( $atts ) {
1562 1409 $has_nav = ! empty( $atts['form'] ) && empty( $atts['is_template'] );
1563 -
1564 1410 if ( empty( $atts['close'] ) ) {
1565 1411 $atts['close'] = admin_url( 'admin.php?page=formidable' );
1566 1412 }
1567 -
1568 1413 if ( ! isset( $atts['import_link'] ) ) {
1569 1414 $atts['import_link'] = false;
1570 1415 }
1571 1416
@@ -1575,19 +1420,16 @@
1575 1420 /**
1576 1421 * @since 6.0
1577 1422 *
1578 1423 * @param string $type
1579 - *
1580 1424 * @return void
1581 1425 */
1582 1426 public static function import_link( $type = 'secondary' ) {
1583 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1584 1427 ?>
1585 1428 <a href="<?php echo esc_url( admin_url( 'admin.php?page=formidable-import' ) ); ?>" class="button frm-button-<?php echo esc_attr( $type ); ?> frm_animate_bg">
1586 1429 <?php esc_html_e( 'Import', 'formidable' ); ?>
1587 1430 </a>
1588 1431 <?php
1589 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1590 1432 }
1591 1433
1592 1434 /**
1593 1435 * Print applicable admin banner.
@@ -1594,9 +1436,8 @@
1594 1436 *
1595 1437 * @since 5.4.2
1596 1438 *
1597 1439 * @param bool $should_show_lite_upgrade
1598 - *
1599 1440 * @return void
1600 1441 */
1601 1442 public static function print_admin_banner( $should_show_lite_upgrade ) {
1602 1443 if ( ! current_user_can( 'administrator' ) ) {
@@ -1608,15 +1449,13 @@
1608 1449 // Print license warning or inbox banner and exit if either prints.
1609 1450 // And exit before printing the upgrade bar if it shouldn't be shown.
1610 1451 return;
1611 1452 }
1612 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1613 1453 ?>
1614 1454 <div class="frm-upgrade-bar">
1615 1455 <div class="frm-upgrade-bar-inner">
1616 1456 <?php
1617 1457 $cta_text = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_text' );
1618 -
1619 1458 if ( ! $cta_text ) {
1620 1459 $cta_text = __( 'upgrading to PRO', 'formidable' );
1621 1460 }
1622 1461
@@ -1621,13 +1460,17 @@
1621 1460 }
1622 1461
1623 1462 $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' );
1624 1463 $utm = array(
1625 - 'campaign' => 'settings-license',
1626 - 'content' => 'lite-banner',
1464 + 'medium' => 'settings-license',
1465 + 'content' => 'lite-banner',
1627 1466 );
1628 1467
1629 - $upgrade_link = $upgrade_link ? self::maybe_add_missing_utm( $upgrade_link, $utm ) : self::admin_upgrade_link( $utm );
1468 + if ( $upgrade_link ) {
1469 + $upgrade_link = self::maybe_add_missing_utm( $upgrade_link, $utm );
1470 + } else {
1471 + $upgrade_link = self::admin_upgrade_link( $utm );
1472 + }
1630 1473
1631 1474 printf(
1632 1475 /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */
1633 1476 esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ),
@@ -1638,9 +1481,8 @@
1638 1481 ?>
1639 1482 </div>
1640 1483 </div>
1641 1484 <?php
1642 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1643 1485 }
1644 1486
1645 1487 /**
1646 1488 * @since 5.4.2
@@ -1654,9 +1496,8 @@
1654 1496 /**
1655 1497 * Render a button for a new item (Form, Application, etc).
1656 1498 *
1657 1499 * @since 3.0
1658 - *
1659 1500 * @param array $atts {
1660 1501 * Details about the button.
1661 1502 *
1662 1503 * @type array $link_hook Custom link hook, calls do_action and exits early.
@@ -1663,9 +1504,8 @@
1663 1504 * @type string $new_link Href value, default #.
1664 1505 * @type string $class Custom class names, space separated.
1665 1506 * @type string $button_text Button text. Default "Add New".
1666 1507 * }
1667 - *
1668 1508 * @return void
1669 1509 */
1670 1510 public static function add_new_item_link( $atts ) {
1671 1511 if ( isset( $atts['link_hook'] ) ) {
@@ -1691,12 +1531,8 @@
1691 1531 }
1692 1532
1693 1533 /**
1694 1534 * @since 3.06
1695 - *
1696 - * @param array $atts
1697 - *
1698 - * @return void
1699 1535 */
1700 1536 public static function show_search_box( $atts ) {
1701 1537 $defaults = array(
1702 1538 'placeholder' => '',
@@ -1703,9 +1539,8 @@
1703 1539 'tosearch' => '',
1704 1540 'text' => __( 'Search', 'formidable' ),
1705 1541 'input_id' => '',
1706 1542 'value' => false,
1707 - 'class' => '',
1708 1543 );
1709 1544 $atts = array_merge( $defaults, $atts );
1710 1545
1711 1546 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
@@ -1712,9 +1547,8 @@
1712 1547 $atts['tosearch'] = 'frm-card';
1713 1548 }
1714 1549
1715 1550 $class = 'frm-search-input';
1716 -
1717 1551 if ( ! empty( $atts['tosearch'] ) ) {
1718 1552 $class .= ' frm-auto-search';
1719 1553 }
1720 1554
@@ -1738,15 +1572,14 @@
1738 1572
1739 1573 if ( ! empty( $atts['tosearch'] ) ) {
1740 1574 $input_atts['autocomplete'] = 'off';
1741 1575 }
1742 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1743 1576 ?>
1744 - <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>">
1577 + <p class="frm-search">
1745 1578 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
1746 1579 <?php echo esc_html( $atts['text'] ); ?>:
1747 1580 </label>
1748 - <?php self::icon_by_class( 'frmfont frm_search_icon frm_svg20' ); ?>
1581 + <span class="frmfont frm_search_icon"></span>
1749 1582 <input <?php self::array_to_html_params( $input_atts, true ); ?> />
1750 1583 <?php
1751 1584 if ( empty( $atts['tosearch'] ) ) {
1752 1585 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
@@ -1753,21 +1586,17 @@
1753 1586 }
1754 1587 ?>
1755 1588 </p>
1756 1589 <?php
1757 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1758 1590 }
1759 1591
1760 1592 /**
1761 - * @param string $type Hook type slug.
1762 - * @param object|null $object Optional related object.
1763 - *
1593 + * @param string $type
1764 1594 * @return void
1765 1595 */
1766 1596 public static function trigger_hook_load( $type, $object = null ) {
1767 1597 // Only load the form hooks once.
1768 1598 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
1769 -
1770 1599 if ( ! $hooks_loaded ) {
1771 1600 do_action( 'frm_load_' . $type . '_hooks' );
1772 1601 }
1773 1602 }
@@ -1826,14 +1655,14 @@
1826 1655 * True when value is 1, true, 'true', 'yes'
1827 1656 *
1828 1657 * @since 1.07.10
1829 1658 *
1830 - * @param bool|int|string $value The value to compare.
1659 + * @param string $value The value to compare.
1831 1660 *
1832 1661 * @return bool
1833 1662 */
1834 1663 public static function is_true( $value ) {
1835 - return true === $value || '1' === (string) $value || 'true' === $value || 'yes' === $value;
1664 + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value;
1836 1665 }
1837 1666
1838 1667 /**
1839 1668 * Gets all post from a specific post type.
@@ -1841,9 +1670,8 @@
1841 1670 *
1842 1671 * @since 4.10.01 Add `$post_type` argument.
1843 1672 *
1844 1673 * @param string $post_type Post type to query. Default is `page`.
1845 - *
1846 1674 * @return WP_Post[]
1847 1675 */
1848 1676 public static function get_pages( $post_type = 'page' ) {
1849 1677 $query = array(
@@ -1862,9 +1690,8 @@
1862 1690 *
1863 1691 * @since 5.0.09
1864 1692 *
1865 1693 * @param string $post_type Post type to query. Default is `page`.
1866 - *
1867 1694 * @return array
1868 1695 */
1869 1696 public static function get_post_ids_and_titles( $post_type = 'page' ) {
1870 1697 return FrmDb::get_results(
@@ -1889,9 +1716,10 @@
1889 1716 *
1890 1717 * @param array $args Selection arguments.
1891 1718 */
1892 1719 public static function maybe_autocomplete_pages_options( $args ) {
1893 - $args = self::preformat_selection_args( $args );
1720 + $args = self::preformat_selection_args( $args );
1721 +
1894 1722 $pages_count = wp_count_posts( $args['post_type'] );
1895 1723
1896 1724 if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) {
1897 1725 self::wp_pages_dropdown( $args );
@@ -1938,11 +1766,11 @@
1938 1766 'value_key' => 'value',
1939 1767 'label_key' => 'label',
1940 1768 );
1941 1769
1942 - $args = wp_parse_args( $args, $defaults );
1770 + $args = wp_parse_args( $args, $defaults );
1771 +
1943 1772 $html_attrs = array();
1944 -
1945 1773 if ( ! empty( $args['name'] ) ) {
1946 1774 $html_attrs['name'] = $args['name'];
1947 1775 }
1948 1776
@@ -1949,9 +1777,8 @@
1949 1777 if ( ! empty( $args['id'] ) ) {
1950 1778 $html_attrs['id'] = $args['id'];
1951 1779 }
1952 1780
1953 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1954 1781 if ( count( $args['source'] ) <= $args['dropdown_limit'] ) {
1955 1782 ?>
1956 1783 <select <?php self::array_to_html_params( $html_attrs, true ); ?>>
1957 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
@@ -1957,44 +1784,40 @@
1957 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1958 1785 <?php
1959 1786 foreach ( $args['source'] as $key => $source ) :
1960 1787 $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1961 -
1962 1788 if ( ! empty( $args['truncate'] ) ) {
1963 1789 $value_label['label'] = self::truncate( $value_label['label'], $args['truncate'] );
1964 1790 }
1965 1791 ?>
1966 - <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1792 + <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option>
1967 1793 <?php endforeach; ?>
1968 1794 </select>
1969 1795 <?php
1970 - return;
1971 - }
1972 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1796 + } else {
1797 + $options = array();
1798 + $autocomplete_value = '';
1799 + foreach ( $args['source'] as $key => $source ) {
1800 + $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1973 1801
1974 - $options = array();
1975 - $autocomplete_value = '';
1802 + if ( $value_label['value'] === $args['selected'] ) {
1803 + $autocomplete_value = $value_label['label'];
1804 + }
1976 1805
1977 - foreach ( $args['source'] as $key => $source ) {
1978 - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1979 -
1980 - if ( $value_label['value'] === $args['selected'] ) {
1981 - $autocomplete_value = $value_label['label'];
1806 + $options[] = $value_label;
1982 1807 }
1983 1808
1984 - $options[] = $value_label;
1985 - }
1986 -
1987 - $html_attrs['type'] = 'hidden';
1988 - $html_attrs['class'] = 'frm_autocomplete_value_input';
1989 - $html_attrs['value'] = $args['selected'];
1990 - ?>
1991 - <input type="text" class="frm-custom-search"
1992 - data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
1993 - placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1994 - value="<?php echo esc_attr( $autocomplete_value ); ?>" />
1995 - <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
1996 - <?php
1809 + $html_attrs['type'] = 'hidden';
1810 + $html_attrs['class'] = 'frm_autocomplete_value_input';
1811 + $html_attrs['value'] = $args['selected'];
1812 + ?>
1813 + <input type="text" class="frm-custom-search"
1814 + data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
1815 + placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1816 + value="<?php echo esc_attr( $autocomplete_value ); ?>" />
1817 + <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
1818 + <?php
1819 + }//end if
1997 1820 }
1998 1821
1999 1822 /**
2000 1823 * Gets dropdown value and label from autodropdown option.
@@ -2003,15 +1826,14 @@
2003 1826 *
2004 1827 * @param array|string $option Autocomplete option.
2005 1828 * @param string $key Array key of the option.
2006 1829 * @param array $args See {@see FrmAppHelper::maybe_autocomplete_options()}.
2007 - *
2008 1830 * @return array
2009 1831 */
2010 1832 private static function get_dropdown_value_and_label_from_option( $option, $key, $args ) {
2011 1833 if ( is_array( $option ) ) {
2012 - $value = $option[ $args['value_key'] ] ?? '';
2013 - $label = $option[ $args['label_key'] ] ?? '';
1834 + $value = isset( $option[ $args['value_key'] ] ) ? $option[ $args['value_key'] ] : '';
1835 + $label = isset( $option[ $args['label_key'] ] ) ? $option[ $args['label_key'] ] : '';
2014 1836 } else {
2015 1837 $value = $key;
2016 1838 $label = $option;
2017 1839 }
@@ -2028,9 +1850,8 @@
2028 1850 self::prep_page_dropdown_params( $page_id, $truncate, $args );
2029 1851
2030 1852 $pages = self::get_post_ids_and_titles( $args['post_type'] );
2031 1853 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
2032 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2033 1854 ?>
2034 1855 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
2035 1856 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
2036 1857 <?php foreach ( $pages as $page ) { ?>
@@ -2039,9 +1860,8 @@
2039 1860 </option>
2040 1861 <?php } ?>
2041 1862 </select>
2042 1863 <?php
2043 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2044 1864 }
2045 1865
2046 1866 /**
2047 1867 * Fill in missing parameters passed to wp_pages_dropdown().
@@ -2047,14 +1867,8 @@
2047 1867 * Fill in missing parameters passed to wp_pages_dropdown().
2048 1868 * This is for reverse compatibility with switching 3 params to 1.
2049 1869 *
2050 1870 * @since 4.03.06
2051 - *
2052 - * @param string $page_id Deprecated.
2053 - * @param bool $truncate Deprecated.
2054 - * @param mixed $args
2055 - *
2056 - * @return void
2057 1871 */
2058 1872 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
2059 1873 if ( ! is_array( $args ) ) {
2060 1874 $args = array(
@@ -2071,12 +1885,8 @@
2071 1885 * Filter to format args for page dropdown or autocomplete
2072 1886 *
2073 1887 * @since 4.03.06
2074 1888 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
2075 - *
2076 - * @param array $args
2077 - *
2078 - * @return array
2079 1889 */
2080 1890 private static function preformat_selection_args( $args ) {
2081 1891 $defaults = array(
2082 1892 'truncate' => false,
@@ -2089,18 +1899,13 @@
2089 1899
2090 1900 return array_merge( $defaults, $args );
2091 1901 }
2092 1902
2093 - /**
2094 - * @param int $post_id
2095 - *
2096 - * @return string
2097 - */
2098 1903 public static function post_edit_link( $post_id ) {
2099 1904 $post = get_post( $post_id );
2100 -
2101 1905 if ( $post ) {
2102 1906 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1907 +
2103 1908 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
2104 1909 }
2105 1910
2106 1911 return '';
@@ -2113,9 +1918,11 @@
2113 1918 *
2114 1919 * @return bool
2115 1920 */
2116 1921 public static function is_full_screen() {
2117 - return self::is_form_builder_page() || self::is_style_editor_page() || self::is_full_screen_view_builder_page();
1922 + return self::is_form_builder_page() ||
1923 + self::is_style_editor_page() ||
1924 + self::is_full_screen_view_builder_page();
2118 1925 }
2119 1926
2120 1927 /**
2121 1928 * Check if user is on the style editor or its alternative URL.
@@ -2125,9 +1932,8 @@
2125 1932 * @since 5.5.3
2126 1933 * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
2127 1934 *
2128 1935 * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
2129 - *
2130 1936 * @return bool
2131 1937 */
2132 1938 public static function is_style_editor_page( $view = '' ) {
2133 1939 if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
@@ -2164,9 +1970,8 @@
2164 1970 * @param array|string $capability
2165 1971 * @param string $multiple 'single' and 'multiple'.
2166 1972 */
2167 1973 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
2168 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2169 1974 ?>
2170 1975 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
2171 1976 <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?>
2172 1977 class="frm_multiselect">
@@ -2172,14 +1977,12 @@
2172 1977 class="frm_multiselect">
2173 1978 <?php self::roles_options( $capability ); ?>
2174 1979 </select>
2175 1980 <?php
2176 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2177 1981 }
2178 1982
2179 1983 /**
2180 1984 * @since 4.07
2181 - *
2182 1985 * @param array|string $selected
2183 1986 * @param string $current
2184 1987 */
2185 1988 private static function selected( $selected, $current ) {
@@ -2194,9 +1997,8 @@
2194 1997 * @param array|string $capability
2195 1998 */
2196 1999 public static function roles_options( $capability ) {
2197 2000 global $frm_vars;
2198 -
2199 2001 if ( isset( $frm_vars['editable_roles'] ) ) {
2200 2002 $editable_roles = $frm_vars['editable_roles'];
2201 2003 } else {
2202 2004 $editable_roles = get_editable_roles();
@@ -2205,9 +2007,9 @@
2205 2007
2206 2008 foreach ( $editable_roles as $role => $details ) {
2207 2009 $name = translate_user_role( $details['name'] );
2208 2010 ?>
2209 - <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?></option>
2011 + <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?> </option>
2210 2012 <?php
2211 2013 unset( $role, $details );
2212 2014 }
2213 2015 }
@@ -2217,9 +2019,8 @@
2217 2019 *
2218 2020 * @since 5.0 Parameter `$type` supports `pro_only` value.
2219 2021 *
2220 2022 * @param string $type Supports `auto`, `pro`, or `pro_only`.
2221 - *
2222 2023 * @return array
2223 2024 */
2224 2025 public static function frm_capabilities( $type = 'auto' ) {
2225 2026 if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
@@ -2237,8 +2038,14 @@
2237 2038 * @param array<string,string> $pro_cap
2238 2039 */
2239 2040 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
2240 2041
2042 + if ( ! array_key_exists( 'frm_edit_displays', $pro_cap ) && is_callable( 'FrmProAppHelper::views_is_installed' ) && FrmProAppHelper::views_is_installed() ) {
2043 + // For backward compatibility, add the Add/Edit Views permission if Pro is not up to date.
2044 + // This was added in 6.5.4. Remove this in the future.
2045 + $pro_cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
2046 + }
2047 +
2241 2048 if ( 'pro_only' === $type ) {
2242 2049 return $pro_cap;
2243 2050 }
2244 2051
@@ -2284,18 +2091,21 @@
2284 2091 if ( $role === 'loggedin' || ! $role ) {
2285 2092 return is_user_logged_in();
2286 2093 }
2287 2094
2288 - if ( (int) $role === 1 ) {
2095 + if ( $role == 1 ) {
2289 2096 $role = 'administrator';
2290 2097 }
2291 2098
2292 - return is_user_logged_in() ? current_user_can( $role ) : false;
2099 + if ( ! is_user_logged_in() ) {
2100 + return false;
2101 + }
2102 +
2103 + return current_user_can( $role );
2293 2104 }
2294 2105
2295 2106 /**
2296 2107 * @param array|string $needed_role
2297 - *
2298 2108 * @return bool
2299 2109 */
2300 2110 public static function user_has_permission( $needed_role ) {
2301 2111 if ( is_array( $needed_role ) ) {
@@ -2309,20 +2119,18 @@
2309 2119 }
2310 2120
2311 2121 $can = self::current_user_can( $needed_role );
2312 2122
2313 - if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ), true ) ) {
2123 + if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
2314 2124 return $can;
2315 2125 }
2316 2126
2317 2127 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
2318 -
2319 2128 foreach ( $roles as $role ) {
2320 2129 if ( current_user_can( $role ) ) {
2321 2130 return true;
2322 2131 }
2323 -
2324 - if ( $role === $needed_role ) {
2132 + if ( $role == $needed_role ) {
2325 2133 break;
2326 2134 }
2327 2135 }
2328 2136
@@ -2343,9 +2151,8 @@
2343 2151
2344 2152 $user_id = get_current_user_id();
2345 2153 $user = new WP_User( $user_id );
2346 2154 $frm_roles = self::frm_capabilities();
2347 -
2348 2155 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2349 2156 $user->add_cap( $frm_role );
2350 2157 unset( $frm_role, $frm_role_description );
2351 2158 }
@@ -2356,22 +2163,18 @@
2356 2163 *
2357 2164 * @since 2.0.6
2358 2165 *
2359 2166 * @param string $cap
2360 - *
2361 2167 * @return void
2362 2168 */
2363 2169 public static function force_capability( $cap = 'frm_change_settings' ) {
2364 - if ( ! current_user_can( 'administrator' ) || current_user_can( $cap ) ) {
2365 - return;
2170 + if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
2171 + $role = get_role( 'administrator' );
2172 + $frm_roles = self::frm_capabilities();
2173 + foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2174 + $role->add_cap( $frm_role );
2175 + }
2366 2176 }
2367 -
2368 - $role = get_role( 'administrator' );
2369 - $frm_roles = self::frm_capabilities();
2370 -
2371 - foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2372 - $role->add_cap( $frm_role );
2373 - }
2374 2177 }
2375 2178
2376 2179 /**
2377 2180 * Check if the user has permission for action.
@@ -2379,22 +2182,17 @@
2379 2182 *
2380 2183 * @since 2.0
2381 2184 *
2382 2185 * @param string $permission
2383 - * @param string $show_message
2384 2186 */
2385 2187 public static function permission_check( $permission, $show_message = 'show' ) {
2386 2188 $permission_error = self::permission_nonce_error( $permission );
2387 -
2388 - if ( $permission_error === false ) {
2389 - return;
2189 + if ( $permission_error !== false ) {
2190 + if ( 'hide' == $show_message ) {
2191 + $permission_error = '';
2192 + }
2193 + wp_die( esc_html( $permission_error ) );
2390 2194 }
2391 -
2392 - if ( 'hide' === $show_message ) {
2393 - $permission_error = '';
2394 - }
2395 -
2396 - wp_die( esc_html( $permission_error ) );
2397 2195 }
2398 2196
2399 2197 /**
2400 2198 * Check user permission and nonce
@@ -2401,27 +2199,24 @@
2401 2199 *
2402 2200 * @since 2.0
2403 2201 *
2404 2202 * @param string $permission
2405 - * @param string $nonce_name
2406 - * @param string $nonce
2407 2203 *
2408 2204 * @return false|string The permission message or false if allowed
2409 2205 */
2410 2206 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
2411 - if ( $permission && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2207 + if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2412 2208 $frm_settings = self::get_settings();
2209 +
2413 2210 return $frm_settings->admin_permission;
2414 2211 }
2415 2212
2416 2213 $error = false;
2417 -
2418 - if ( ! $nonce_name ) {
2214 + if ( empty( $nonce_name ) ) {
2419 2215 return $error;
2420 2216 }
2421 2217
2422 2218 $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
2423 -
2424 2219 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
2425 2220 $frm_settings = self::get_settings();
2426 2221 $error = $frm_settings->admin_permission;
2427 2222 }
@@ -2428,14 +2223,8 @@
2428 2223
2429 2224 return $error;
2430 2225 }
2431 2226
2432 - /**
2433 - * @param array|string $values
2434 - * @param string $current
2435 - *
2436 - * @return void
2437 - */
2438 2227 public static function checked( $values, $current ) {
2439 2228 if ( self::check_selected( $values, $current ) ) {
2440 2229 echo ' checked="checked"';
2441 2230 }
@@ -2440,47 +2229,38 @@
2440 2229 echo ' checked="checked"';
2441 2230 }
2442 2231 }
2443 2232
2444 - /**
2445 - * @param array|string $values
2446 - * @param string|null $current
2447 - *
2448 - * @return bool
2449 - */
2450 2233 public static function check_selected( $values, $current ) {
2451 - $values = self::recursive_function_map( $values, 'trim' );
2452 - $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2234 + $values = self::recursive_function_map( $values, 'trim' );
2235 + $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
2236 +
2453 2237 $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) );
2454 2238
2455 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons
2456 - return is_array( $values ) ? in_array( $current, $values ) : $values == $current;
2239 + return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
2457 2240 }
2458 2241
2459 - /**
2460 - * @param array|string $value
2461 - * @param callable|string $function
2462 - *
2463 - * @return array|string
2464 - */
2465 2242 public static function recursive_function_map( $value, $function ) {
2466 2243 if ( is_array( $value ) ) {
2467 2244 $original_function = $function;
2468 - $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function );
2469 -
2470 - if ( self::is_assoc( $value ) ) {
2245 + if ( count( $value ) ) {
2246 + $function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
2247 + } else {
2248 + $function = array( $function );
2249 + }
2250 + if ( ! self::is_assoc( $value ) ) {
2251 + $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2252 + } else {
2471 2253 foreach ( $value as $k => $v ) {
2472 2254 if ( ! is_array( $v ) ) {
2473 2255 $value[ $k ] = call_user_func( $original_function, $v );
2474 2256 }
2475 2257 }
2476 - } else {
2477 - $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2478 2258 }
2479 2259 } else {
2480 2260 $value = self::maybe_update_value_if_null( $value, $function );
2481 2261 $value = call_user_func( $function, $value );
2482 - }//end if
2262 + }
2483 2263
2484 2264 return $value;
2485 2265 }
2486 2266
@@ -2487,27 +2267,20 @@
2487 2267 /**
2488 2268 * Updates value to empty string if it is null and being passed to a string function.
2489 2269 *
2490 2270 * @since 6.8.4
2491 - *
2492 2271 * @param mixed $value
2493 2272 * @param string $function
2494 - *
2495 2273 * @return mixed
2496 2274 */
2497 2275 private static function maybe_update_value_if_null( $value, $function ) {
2498 2276 if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) {
2499 - return '';
2277 + $value = '';
2500 2278 }
2501 2279
2502 2280 return $value;
2503 2281 }
2504 2282
2505 - /**
2506 - * @param array $array
2507 - *
2508 - * @return bool
2509 - */
2510 2283 public static function is_assoc( $array ) {
2511 2284 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
2512 2285 }
2513 2286
@@ -2512,22 +2285,16 @@
2512 2285 }
2513 2286
2514 2287 /**
2515 2288 * Flatten a multi-dimensional array
2516 - *
2517 - * @param array $array
2518 - * @param string $keys
2519 - *
2520 - * @return array
2521 2289 */
2522 2290 public static function array_flatten( $array, $keys = 'keep' ) {
2523 2291 $return = array();
2524 -
2525 2292 foreach ( $array as $key => $value ) {
2526 2293 if ( is_array( $value ) ) {
2527 2294 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
2528 2295 } elseif ( $keys === 'keep' ) {
2529 - $return[ $key ] = $value;
2296 + $return[ $key ] = $value;
2530 2297 } else {
2531 2298 $return[] = $value;
2532 2299 }
2533 2300 }
@@ -2541,9 +2308,8 @@
2541 2308 * @since 6.16.1
2542 2309 *
2543 2310 * @param string $sep
2544 2311 * @param array $array
2545 - *
2546 2312 * @return string
2547 2313 */
2548 2314 public static function safe_implode( $sep, $array ) {
2549 2315 $array = self::array_flatten( $array );
@@ -2552,18 +2318,15 @@
2552 2318
2553 2319 /**
2554 2320 * @param string $text
2555 2321 * @param bool $is_rich_text
2556 - *
2557 2322 * @return string
2558 2323 */
2559 2324 public static function esc_textarea( $text, $is_rich_text = false ) {
2560 2325 $safe_text = str_replace( '&quot;', '"', $text );
2561 -
2562 2326 if ( ! $is_rich_text ) {
2563 2327 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
2564 2328 }
2565 -
2566 2329 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
2567 2330
2568 2331 /**
2569 2332 * @param string $safe_text
@@ -2575,59 +2338,44 @@
2575 2338 /**
2576 2339 * Add auto paragraphs to text areas
2577 2340 *
2578 2341 * @since 2.0
2579 - *
2580 - * @param mixed $content
2581 - *
2582 - * @return mixed
2583 2342 */
2584 2343 public static function use_wpautop( $content ) {
2585 2344 if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) {
2586 - return wpautop( str_replace( '<br>', '<br />', $content ) );
2345 + $content = wpautop( str_replace( '<br>', '<br />', $content ) );
2587 2346 }
2588 2347
2589 2348 return $content;
2590 2349 }
2591 2350
2592 - /**
2593 - * Replace quotes with their HTML entities.
2594 - *
2595 - * @param string $val
2596 - *
2597 - * @return string
2598 - */
2599 2351 public static function replace_quotes( $val ) {
2600 2352 // Replace double quotes.
2601 2353 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
2602 2354
2603 2355 // Replace single quotes.
2604 - return str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2356 + $val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
2357 +
2358 + return $val;
2605 2359 }
2606 2360
2607 2361 /**
2608 - * @param string $handle
2609 - * @param int|string $default
2610 - *
2611 - * @return int|string
2362 + * @param string $handle
2612 2363 */
2613 2364 public static function script_version( $handle, $default = 0 ) {
2614 2365 global $wp_scripts;
2615 -
2616 2366 if ( ! $wp_scripts ) {
2617 2367 return $default;
2618 2368 }
2619 2369
2620 2370 $ver = $default;
2621 -
2622 2371 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
2623 2372 return $ver;
2624 2373 }
2625 2374
2626 2375 $query = $wp_scripts->registered[ $handle ];
2627 -
2628 2376 if ( is_object( $query ) && ! empty( $query->ver ) ) {
2629 - return $query->ver;
2377 + $ver = $query->ver;
2630 2378 }
2631 2379
2632 2380 return $ver;
2633 2381 }
@@ -2636,9 +2384,8 @@
2636 2384 * @since 5.0.13 added $echo param.
2637 2385 *
2638 2386 * @param string $url
2639 2387 * @param bool $echo
2640 - *
2641 2388 * @return string|null
2642 2389 */
2643 2390 public static function js_redirect( $url, $echo = false ) {
2644 2391 $callback = function () use ( $url ) {
@@ -2646,13 +2393,8 @@
2646 2393 };
2647 2394 return self::clip( $callback, $echo );
2648 2395 }
2649 2396
2650 - /**
2651 - * @param int|string $user_id
2652 - *
2653 - * @return int|string
2654 - */
2655 2397 public static function get_user_id_param( $user_id ) {
2656 2398 if ( ! $user_id || is_numeric( $user_id ) ) {
2657 2399 return $user_id;
2658 2400 }
@@ -2657,13 +2399,16 @@
2657 2399 return $user_id;
2658 2400 }
2659 2401
2660 2402 $user_id = sanitize_text_field( $user_id );
2661 -
2662 2403 if ( $user_id === 'current' ) {
2663 2404 $user_id = get_current_user_id();
2664 2405 } else {
2665 - $user = is_email( $user_id ) ? get_user_by( 'email', $user_id ) : get_user_by( 'login', $user_id );
2406 + if ( is_email( $user_id ) ) {
2407 + $user = get_user_by( 'email', $user_id );
2408 + } else {
2409 + $user = get_user_by( 'login', $user_id );
2410 + }
2666 2411
2667 2412 if ( $user ) {
2668 2413 $user_id = $user->ID;
2669 2414 }
@@ -2675,9 +2420,8 @@
2675 2420
2676 2421 /**
2677 2422 * @param string $filename
2678 2423 * @param array $atts
2679 - *
2680 2424 * @return false|string
2681 2425 */
2682 2426 public static function get_file_contents( $filename, $atts = array() ) {
2683 2427 if ( ! is_file( $filename ) ) {
@@ -2686,9 +2430,12 @@
2686 2430
2687 2431 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
2688 2432 ob_start();
2689 2433 include $filename;
2690 - return ob_get_clean();
2434 + $contents = ob_get_contents();
2435 + ob_end_clean();
2436 +
2437 + return $contents;
2691 2438 }
2692 2439
2693 2440 /**
2694 2441 * @param string $name
@@ -2698,9 +2445,8 @@
2698 2445 * @param int $num_chars
2699 2446 */
2700 2447 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
2701 2448 $key = '';
2702 -
2703 2449 if ( $name ) {
2704 2450 $key = sanitize_key( $name );
2705 2451 $key = self::maybe_clear_long_key( $key, $column );
2706 2452 }
@@ -2720,31 +2466,31 @@
2720 2466 $column
2721 2467 );
2722 2468
2723 2469 // Create a unique field id if it has already been used.
2724 - if ( ! in_array( $key, $similar_keys, true ) ) {
2725 - return $key;
2726 - }
2470 + if ( in_array( $key, $similar_keys, true ) ) {
2471 + $key = self::maybe_truncate_key_before_appending( $column, $key );
2727 2472
2728 - $key = self::maybe_truncate_key_before_appending( $column, $key );
2473 + /**
2474 + * Allow for a custom separator between the attempted key and the generated suffix.
2475 + *
2476 + * @since 5.2.03
2477 + *
2478 + * @param string $separator. Default empty.
2479 + * @param string $key the key without the added suffix.
2480 + */
2481 + $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2729 2482
2730 - /**
2731 - * Allow for a custom separator between the attempted key and the generated suffix.
2732 - *
2733 - * @since 5.2.03
2734 - *
2735 - * @param string $separator. Default empty.
2736 - * @param string $key the key without the added suffix.
2737 - */
2738 - $separator = apply_filters( 'frm_unique_' . $column . '_separator', '', $key );
2483 + $suffix = 2;
2484 + do {
2485 + $key_check = $key . $separator . $suffix;
2486 + ++$suffix;
2487 + } while ( in_array( $key_check, $similar_keys, true ) );
2739 2488
2740 - $suffix = 2;
2741 - do {
2742 - $key_check = $key . $separator . $suffix;
2743 - ++$suffix;
2744 - } while ( in_array( $key_check, $similar_keys, true ) );
2489 + $key = $key_check;
2490 + }//end if
2745 2491
2746 - return $key_check;
2492 + return $key;
2747 2493 }
2748 2494
2749 2495 /**
2750 2496 * Avoid trying to append to a really long key,
@@ -2751,26 +2497,20 @@
2751 2497 * The database limit is 100 for form and field keys so we want to avoid getting too close.
2752 2498 *
2753 2499 * @param string $column
2754 2500 * @param string $key
2755 - *
2756 2501 * @return string
2757 2502 */
2758 2503 private static function maybe_truncate_key_before_appending( $column, $key ) {
2759 - if ( ! in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2760 - return $key;
2761 - }
2762 -
2763 - $max_key_length_before_truncating = 60;
2764 -
2765 - if ( strlen( $key ) > $max_key_length_before_truncating ) {
2766 - $key = substr( $key, 0, $max_key_length_before_truncating );
2767 -
2768 - if ( is_numeric( $key ) ) {
2769 - $key .= 'a';
2504 + if ( in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2505 + $max_key_length_before_truncating = 60;
2506 + if ( strlen( $key ) > $max_key_length_before_truncating ) {
2507 + $key = substr( $key, 0, $max_key_length_before_truncating );
2508 + if ( is_numeric( $key ) ) {
2509 + $key .= 'a';
2510 + }
2770 2511 }
2771 2512 }
2772 -
2773 2513 return $key;
2774 2514 }
2775 2515
2776 2516 /**
@@ -2777,14 +2517,13 @@
2777 2517 * Possibly reset a key to avoid conflicts with column size limits.
2778 2518 *
2779 2519 * @param string $key
2780 2520 * @param string $column
2781 - *
2782 2521 * @return string either the original key value, or an empty string if the key was too long.
2783 2522 */
2784 2523 private static function maybe_clear_long_key( $key, $column ) {
2785 2524 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
2786 - return '';
2525 + $key = '';
2787 2526 }
2788 2527 return $key;
2789 2528 }
2790 2529
@@ -2791,22 +2530,20 @@
2791 2530 /**
2792 2531 * @since 6.21 This is changed from `private` to `public`.
2793 2532 *
2794 2533 * @param int $num_chars
2795 - *
2796 2534 * @return string
2797 2535 */
2798 2536 public static function generate_new_key( $num_chars ) {
2799 - $max_slug_value = 36 ** $num_chars;
2537 + $max_slug_value = pow( 36, $num_chars );
2800 2538
2801 2539 // We want to have at least 2 characters in the slug.
2802 2540 $min_slug_value = 37;
2803 - return base_convert( random_int( $min_slug_value, $max_slug_value ), 10, 36 );
2541 + return base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
2804 2542 }
2805 2543
2806 2544 /**
2807 2545 * @param string $key
2808 - *
2809 2546 * @return string
2810 2547 */
2811 2548 private static function prevent_numeric_and_reserved_keys( $key ) {
2812 2549 if ( is_numeric( $key ) ) {
@@ -2820,14 +2557,12 @@
2820 2557 'editlink',
2821 2558 'siteurl',
2822 2559 'evenodd',
2823 2560 );
2824 -
2825 2561 if ( in_array( $key, $not_allowed, true ) ) {
2826 2562 $key .= 'a';
2827 2563 }
2828 2564 }
2829 -
2830 2565 return $key;
2831 2566 }
2832 2567
2833 2568 /**
@@ -2846,9 +2581,9 @@
2846 2581 if ( ! $record ) {
2847 2582 return false;
2848 2583 }
2849 2584
2850 - if ( ! $post_values ) {
2585 + if ( empty( $post_values ) ) {
2851 2586 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
2852 2587 }
2853 2588
2854 2589 $values = array(
@@ -2856,9 +2591,9 @@
2856 2591 'fields' => array(),
2857 2592 );
2858 2593
2859 2594 foreach ( array( 'name', 'description' ) as $var ) {
2860 - $default_val = $record->{$var} ?? '';
2595 + $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
2861 2596 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
2862 2597 unset( $var, $default_val );
2863 2598 }
2864 2599
@@ -2876,67 +2611,46 @@
2876 2611
2877 2612 return $values;
2878 2613 }
2879 2614
2880 - /**
2881 - * @param array|string $fields
2882 - * @param object $record
2883 - * @param array $values
2884 - * @param array $args
2885 - *
2886 - * @return void
2887 - */
2888 2615 private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
2889 - if ( ! $fields ) {
2890 - return;
2891 - }
2892 -
2893 - foreach ( (array) $fields as $field ) {
2894 - if ( ! self::is_admin_page() ) {
2895 - // Don't prep default values on the form settings page.
2896 - $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
2616 + if ( ! empty( $fields ) ) {
2617 + foreach ( (array) $fields as $field ) {
2618 + if ( ! self::is_admin_page() ) {
2619 + // Don't prep default values on the form settings page.
2620 + $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
2621 + }
2622 + $args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
2623 + self::fill_field_defaults( $field, $record, $values, $args );
2897 2624 }
2898 -
2899 - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id;
2900 - self::fill_field_defaults( $field, $record, $values, $args );
2901 2625 }
2902 2626 }
2903 2627
2904 - /**
2905 - * @param object $field
2906 - * @param object $record
2907 - * @param array $values
2908 - * @param array $args
2909 - *
2910 - * @return void
2911 - */
2912 2628 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
2913 2629 $post_values = $args['post_values'];
2914 2630
2915 2631 if ( $args['default'] ) {
2916 2632 $meta_value = $field->default_value;
2917 - } elseif ( $record->post_id && self::pro_is_installed() && ! empty( $field->field_options['post_field'] ) ) {
2633 + } elseif ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) {
2918 2634 if ( ! isset( $field->field_options['custom_field'] ) ) {
2919 2635 $field->field_options['custom_field'] = '';
2920 2636 }
2921 -
2922 - $meta_value = FrmProEntryMetaHelper::get_post_value(
2923 - $record->post_id,
2924 - $field->field_options['post_field'],
2925 - $field->field_options['custom_field'],
2926 - array(
2927 - 'truncate' => false,
2928 - 'type' => $field->type,
2929 - 'form_id' => $field->form_id,
2930 - 'field' => $field,
2931 - )
2932 - );
2637 + $meta_value = FrmProEntryMetaHelper::get_post_value(
2638 + $record->post_id,
2639 + $field->field_options['post_field'],
2640 + $field->field_options['custom_field'],
2641 + array(
2642 + 'truncate' => false,
2643 + 'type' => $field->type,
2644 + 'form_id' => $field->form_id,
2645 + 'field' => $field,
2646 + )
2647 + );
2933 2648 } else {
2934 2649 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
2935 2650 }//end if
2936 2651
2937 - $field_type = $post_values['field_options'][ 'type_' . $field->id ] ?? $field->type;
2938 -
2652 + $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
2939 2653 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
2940 2654 $new_value = $post_values['item_meta'][ $field->id ];
2941 2655 self::unserialize_or_decode( $new_value );
2942 2656 } else {
@@ -2951,9 +2665,9 @@
2951 2665 $args['field_type'] = $field_type;
2952 2666
2953 2667 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
2954 2668
2955 - if ( empty( $field_array['unique'] ) ) {
2669 + if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
2956 2670 $field_array['unique_msg'] = '';
2957 2671 }
2958 2672
2959 2673 $field_array = array_merge( (array) $field->field_options, $field_array );
@@ -3020,21 +2734,15 @@
3020 2734 }
3021 2735
3022 2736 /**
3023 2737 * Set to POST value or default
3024 - *
3025 - * @param array $post_values
3026 - * @param array $values
3027 - *
3028 - * @return void
3029 2738 */
3030 2739 private static function fill_form_defaults( $post_values, array &$values ) {
3031 2740 $form_defaults = FrmFormsHelper::get_default_opts();
3032 2741
3033 2742 foreach ( $form_defaults as $opt => $default ) {
3034 - // phpcs:ignore Universal.Operators.StrictComparisons
3035 2743 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
3036 - $values[ $opt ] = $post_values['options'][ $opt ] ?? $default;
2744 + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default;
3037 2745 }
3038 2746
3039 2747 unset( $opt, $default );
3040 2748 }
@@ -3044,9 +2752,9 @@
3044 2752 }
3045 2753
3046 2754 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
3047 2755 if ( ! isset( $values[ $h . '_html' ] ) ) {
3048 - $values[ $h . '_html' ] = $post_values['options'][ $h . '_html' ] ?? FrmFormsHelper::get_default_html( $h );
2756 + $values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
3049 2757 }
3050 2758 unset( $h );
3051 2759 }
3052 2760 }
@@ -3058,14 +2766,16 @@
3058 2766 *
3059 2767 * @return bool|int
3060 2768 */
3061 2769 public static function custom_style_value( $post_values ) {
3062 - if ( $post_values && isset( $post_values['options']['custom_style'] ) ) {
3063 - return absint( $post_values['options']['custom_style'] );
2770 + if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
2771 + $custom_style = absint( $post_values['options']['custom_style'] );
2772 + } else {
2773 + $frm_settings = self::get_settings();
2774 + $custom_style = ( $frm_settings->load_style !== 'none' );
3064 2775 }
3065 2776
3066 - $frm_settings = self::get_settings();
3067 - return $frm_settings->load_style !== 'none';
2777 + return $custom_style;
3068 2778 }
3069 2779
3070 2780 /**
3071 2781 * @param mixed $original_string
@@ -3071,9 +2781,8 @@
3071 2781 * @param mixed $original_string
3072 2782 * @param int|string $length
3073 2783 * @param int $minword
3074 2784 * @param string $continue
3075 - *
3076 2785 * @return string
3077 2786 */
3078 2787 public static function truncate( $original_string, $length, $minword = 3, $continue = '...' ) {
3079 2788 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
@@ -3079,24 +2788,24 @@
3079 2788 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
3080 2789 return '';
3081 2790 }
3082 2791
3083 - $length = (int) $length;
2792 + $length = (int) $length;
2793 + $str = wp_strip_all_tags( (string) $original_string );
2794 + $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3084 2795
3085 - if ( $length === 0 ) {
2796 + if ( $length == 0 ) {
3086 2797 return '';
3087 2798 }
3088 2799
3089 - $str = wp_strip_all_tags( (string) $original_string );
3090 - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3091 -
3092 2800 if ( $length <= 10 ) {
3093 2801 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
3094 2802 return $sub . ( $length < $original_len ? $continue : '' );
3095 2803 }
3096 2804
3097 - $sub = '';
3098 - $len = 0;
2805 + $sub = '';
2806 + $len = 0;
2807 +
3099 2808 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
3100 2809
3101 2810 if ( ! is_array( $words ) ) {
3102 2811 return $original_string;
@@ -3102,11 +2811,10 @@
3102 2811 return $original_string;
3103 2812 }
3104 2813
3105 2814 foreach ( $words as $word ) {
3106 - $part = ( $sub !== '' ? ' ' : '' ) . $word;
2815 + $part = ( $sub != '' ? ' ' : '' ) . $word;
3107 2816 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
3108 -
3109 2817 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
3110 2818 break;
3111 2819 }
3112 2820
@@ -3131,9 +2839,8 @@
3131 2839 * @since 6.5.4
3132 2840 *
3133 2841 * @param string $sub Current substring.
3134 2842 * @param int $length The length limit.
3135 - *
3136 2843 * @return string
3137 2844 */
3138 2845 private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) {
3139 2846 if ( strlen( $sub ) < $length + 50 ) {
@@ -3141,9 +2848,8 @@
3141 2848 return $sub;
3142 2849 }
3143 2850
3144 2851 $first_space = strpos( $sub, ' ', $length );
3145 -
3146 2852 if ( false !== $first_space ) {
3147 2853 // Ignore anything with spaces.
3148 2854 return $sub;
3149 2855 }
@@ -3150,18 +2856,11 @@
3150 2856
3151 2857 return substr( $sub, 0, $length + 10 );
3152 2858 }
3153 2859
3154 - /**
3155 - * @param array $function_names
3156 - * @param array $args
3157 - *
3158 - * @return mixed
3159 - */
3160 2860 public static function mb_function( $function_names, $args ) {
3161 2861 $mb_function_name = $function_names[0];
3162 2862 $function_name = $function_names[1];
3163 -
3164 2863 if ( function_exists( $mb_function_name ) ) {
3165 2864 $function_name = $mb_function_name;
3166 2865 }
3167 2866
@@ -3167,21 +2866,14 @@
3167 2866
3168 2867 return call_user_func_array( $function_name, $args );
3169 2868 }
3170 2869
3171 - /**
3172 - * @param string $date
3173 - * @param string $date_format
3174 - * @param string $time_format
3175 - *
3176 - * @return string
3177 - */
3178 2870 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
3179 - if ( ! $date ) {
2871 + if ( empty( $date ) ) {
3180 2872 return $date;
3181 2873 }
3182 2874
3183 - if ( ! $date_format ) {
2875 + if ( empty( $date_format ) ) {
3184 2876 $date_format = get_option( 'date_format' );
3185 2877 }
3186 2878
3187 2879 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
@@ -3189,10 +2881,10 @@
3189 2881 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
3190 2882 }
3191 2883
3192 2884 $formatted = self::get_localized_date( $date_format, $date );
3193 - $do_time = gmdate( 'H:i:s', strtotime( $date ) ) !== '00:00:00';
3194 2885
2886 + $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
3195 2887 if ( $do_time ) {
3196 2888 $formatted .= self::add_time_to_date( $time_format, $date );
3197 2889 }
3198 2890
@@ -3201,35 +2893,30 @@
3201 2893
3202 2894 /**
3203 2895 * @param string $time_format
3204 2896 * @param string $date
3205 - *
3206 2897 * @return string
3207 2898 */
3208 2899 private static function add_time_to_date( $time_format, $date ) {
3209 - if ( ! $time_format ) {
2900 + if ( empty( $time_format ) ) {
3210 2901 $time_format = get_option( 'time_format' );
3211 2902 }
3212 2903
3213 2904 $trimmed_format = trim( $time_format );
3214 -
3215 - if ( $time_format && $trimmed_format ) {
3216 - return ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
2905 + $time = '';
2906 + if ( $time_format && ! empty( $trimmed_format ) ) {
2907 + $time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
3217 2908 }
3218 2909
3219 - return '';
2910 + return $time;
3220 2911 }
3221 2912
3222 2913 /**
3223 2914 * @since 2.0.8
3224 - *
3225 - * @param string $date_format
3226 - * @param string $date
3227 - *
3228 - * @return string
3229 2915 */
3230 2916 public static function get_localized_date( $date_format, $date ) {
3231 2917 $date = get_date_from_gmt( $date );
2918 +
3232 2919 return date_i18n( $date_format, strtotime( $date ) );
3233 2920 }
3234 2921
3235 2922 /**
@@ -3234,16 +2921,19 @@
3234 2921
3235 2922 /**
3236 2923 * Gets the time ago in words.
3237 2924 *
3238 - * @param int $from In seconds.
3239 - * @param int|string $to In seconds.
3240 - * @param int|string $levels Number of time units to include or a specific unit.
2925 + * @param int $from In seconds.
2926 + * @param int|string $to In seconds.
3241 2927 *
3242 - * @return string Time ago.
2928 + * @return string $time_ago
3243 2929 */
3244 2930 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
3245 - $now = ! $to && 0 !== $to ? new DateTime() : new DateTime( '@' . $to );
2931 + if ( empty( $to ) && 0 !== $to ) {
2932 + $now = new DateTime();
2933 + } else {
2934 + $now = new DateTime( '@' . $to );
2935 + }
3246 2936 $ago = new DateTime( '@' . $from );
3247 2937
3248 2938 // Get the time difference
3249 2939 $diff_object = $now->diff( $ago );
@@ -3257,9 +2947,8 @@
3257 2947
3258 2948 if ( ! is_numeric( $levels ) ) {
3259 2949 // Show time in specified unit.
3260 2950 $levels = self::get_unit( $levels );
3261 -
3262 2951 if ( isset( $time_strings[ $levels ] ) ) {
3263 2952 $diff = array(
3264 2953 $levels => self::time_format( $levels, $diff ),
3265 2954 );
@@ -3266,14 +2955,13 @@
3266 2955 $time_strings = array(
3267 2956 $levels => $time_strings[ $levels ],
3268 2957 );
3269 2958 }
3270 -
3271 2959 $levels = 1;
3272 2960 }
3273 2961
3274 2962 foreach ( $time_strings as $k => $v ) {
3275 - if ( ! empty( $diff[ $k ] ) ) {
2963 + if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
3276 2964 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
3277 2965 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
3278 2966 // Account for 0.
3279 2967 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
@@ -3281,21 +2969,17 @@
3281 2969 unset( $time_strings[ $k ] );
3282 2970 }
3283 2971 }
3284 2972
3285 - $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
3286 - $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2973 + $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
2974 + $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2975 + $time_ago_string = implode( ' ', $time_strings );
3287 2976
3288 - return implode( ' ', $time_strings );
2977 + return $time_ago_string;
3289 2978 }
3290 2979
3291 2980 /**
3292 2981 * @since 4.05.01
3293 - *
3294 - * @param string $unit
3295 - * @param array $diff
3296 - *
3297 - * @return int
3298 2982 */
3299 2983 private static function time_format( $unit, $diff ) {
3300 2984 $return = array(
3301 2985 'y' => 'y',
@@ -3300,14 +2984,14 @@
3300 2984 $return = array(
3301 2985 'y' => 'y',
3302 2986 'd' => 'days',
3303 2987 );
3304 -
3305 2988 if ( isset( $return[ $unit ] ) ) {
3306 2989 return $diff[ $return[ $unit ] ];
3307 2990 }
3308 2991
3309 2992 $total = $diff['days'] * self::convert_time( 'd', $unit );
2993 +
3310 2994 $times = array( 'h', 'i', 's' );
3311 2995
3312 2996 foreach ( $times as $time ) {
3313 2997 if ( ! isset( $diff[ $time ] ) ) {
@@ -3321,13 +3005,8 @@
3321 3005 }
3322 3006
3323 3007 /**
3324 3008 * @since 4.05.01
3325 - *
3326 - * @param string $from
3327 - * @param string $to
3328 - *
3329 - * @return int
3330 3009 */
3331 3010 private static function convert_time( $from, $to ) {
3332 3011 $convert = array(
3333 3012 's' => 1,
@@ -3343,26 +3022,20 @@
3343 3022 }
3344 3023
3345 3024 /**
3346 3025 * @since 4.05.01
3347 - *
3348 - * @param string $unit
3349 - *
3350 - * @return int|string
3351 3026 */
3352 3027 private static function get_unit( $unit ) {
3353 3028 $units = self::get_time_strings();
3354 -
3355 3029 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
3356 3030 return $unit;
3357 3031 }
3358 3032
3359 3033 foreach ( $units as $u => $strings ) {
3360 - if ( in_array( $unit, $strings, true ) ) {
3034 + if ( in_array( $unit, $strings ) ) {
3361 3035 return $u;
3362 3036 }
3363 3037 }
3364 -
3365 3038 return 1;
3366 3039 }
3367 3040
3368 3041 /**
@@ -3369,9 +3042,8 @@
3369 3042 * Get the translatable time strings. The untranslated version is a failsafe
3370 3043 * in case languages are changing for the unit set in the shortcode.
3371 3044 *
3372 3045 * @since 2.0.20
3373 - *
3374 3046 * @return array
3375 3047 */
3376 3048 private static function get_time_strings() {
3377 3049 return array(
@@ -3418,13 +3090,12 @@
3418 3090 /**
3419 3091 * @param int $r_count
3420 3092 * @param int $current_p
3421 3093 * @param int $p_size
3422 - *
3423 3094 * @return int
3424 3095 */
3425 3096 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
3426 - return $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size;
3097 + return ( $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size );
3427 3098 }
3428 3099
3429 3100 /**
3430 3101 * @param int $r_count
@@ -3429,13 +3100,11 @@
3429 3100 /**
3430 3101 * @param int $r_count
3431 3102 * @param int $current_p
3432 3103 * @param int $p_size
3433 - *
3434 3104 * @return int
3435 3105 */
3436 3106 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
3437 - // phpcs:ignore Universal.Operators.StrictComparisons
3438 3107 if ( $current_p == 1 ) {
3439 3108 return 1;
3440 3109 }
3441 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
@@ -3441,22 +3110,17 @@
3441 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
3442 3111 }
3443 3112
3444 3113 /**
3445 - * @param array $json_vars
3446 - *
3447 3114 * @return array
3448 3115 */
3449 3116 public static function json_to_array( $json_vars ) {
3450 3117 $vars = array();
3451 -
3452 3118 foreach ( $json_vars as $jv ) {
3453 3119 $jv_name = explode( '[', $jv['name'] );
3454 3120 $last = count( $jv_name ) - 1;
3455 -
3456 3121 foreach ( $jv_name as $p => $n ) {
3457 3122 $name = trim( $n, ']' );
3458 -
3459 3123 if ( ! isset( $l1 ) ) {
3460 3124 $l1 = $name;
3461 3125 }
3462 3126
@@ -3467,9 +3131,9 @@
3467 3131 if ( ! isset( $l3 ) ) {
3468 3132 $l3 = $name;
3469 3133 }
3470 3134
3471 - $this_val = $p === $last ? $jv['value'] : array();
3135 + $this_val = $p == $last ? $jv['value'] : array();
3472 3136
3473 3137 switch ( $p ) {
3474 3138 case 0:
3475 3139 $l1 = $name;
@@ -3502,15 +3166,10 @@
3502 3166
3503 3167 /**
3504 3168 * @param string $name
3505 3169 * @param string $l1
3506 - * @param mixed $val
3507 - * @param array $vars
3508 - *
3509 - * @return void
3510 3170 */
3511 3171 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
3512 - // phpcs:ignore Universal.Operators.StrictComparisons
3513 3172 if ( $name == '' ) {
3514 3173 $vars[] = $val;
3515 3174 } elseif ( ! isset( $vars[ $l1 ] ) ) {
3516 3175 $vars[ $l1 ] = $val;
@@ -3516,26 +3175,19 @@
3516 3175 $vars[ $l1 ] = $val;
3517 3176 }
3518 3177 }
3519 3178
3520 - /**
3521 - * @param string $name
3522 - * @param string $class
3523 - * @param string $form_name
3524 - *
3525 - * @return void
3526 - */
3527 3179 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
3528 3180 $tooltips = array(
3529 3181 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
3530 - 'email_to' => __( 'Add one or more recipient addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com. [default-email] is the address set in the global "Default Email Address" settings.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3182 + 'email_to' => __( 'Add one or more recipient addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com. [admin_email] is the address set in WP General Settings.', 'formidable' ),
3531 3183 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3532 3184 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3533 - 'reply_to' => __( 'If you would like a different reply to address than the "from" address, add a single address here. FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3185 + 'reply_to' => __( 'If you would like a different reply to address than the "from" address, add a single address here. FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3534 3186 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
3535 3187 /* translators: %1$s: Form name, %2$s: Date */
3536 - '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
3537 - 'new_tab' => __( 'This option will open the link in a new browser tab. Please note that some popup blockers may prevent this from happening, in which case the link will be displayed.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3188 + 'email_subject' => esc_attr( sprintf( __( 'If you leave the subject blank, the default will be used: %1$s Form submitted on %2$s', 'formidable' ), $form_name, self::site_name() ) ),
3189 + 'new_tab' => __( 'This option will open the link in a new browser tab. Please note that some popup blockers may prevent this from happening, in which case the link will be displayed.', 'formidable' ),
3538 3190 );
3539 3191
3540 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3541 3193 return;
@@ -3540,9 +3192,9 @@
3540 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3541 3193 return;
3542 3194 }
3543 3195
3544 - if ( 'open' === $class ) {
3196 + if ( 'open' == $class ) {
3545 3197 echo ' frm_help"';
3546 3198 } else {
3547 3199 echo ' class="frm_help"';
3548 3200 }
@@ -3548,9 +3200,9 @@
3548 3200 }
3549 3201
3550 3202 echo ' title="' . esc_attr( $tooltips[ $name ] );
3551 3203
3552 - if ( 'open' !== $class ) {
3204 + if ( 'open' != $class ) {
3553 3205 echo '"';
3554 3206 }
3555 3207 }
3556 3208
@@ -3555,28 +3207,20 @@
3555 3207 }
3556 3208
3557 3209 /**
3558 3210 * Add the current_page class to that page in the form nav
3559 - *
3560 - * @param int|string $page
3561 - * @param int|string $current_page
3562 - * @param array $action
3563 - *
3564 - * @return void
3565 3211 */
3566 3212 public static function select_current_page( $page, $current_page, $action = array() ) {
3567 - // phpcs:ignore Universal.Operators.StrictComparisons
3568 3213 if ( $current_page != $page ) {
3569 3214 return;
3570 3215 }
3571 3216
3572 3217 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
3573 -
3574 3218 if ( 'lite-reports' === $frm_action ) {
3575 3219 $frm_action = 'reports';
3576 3220 }
3577 3221
3578 - if ( ! $action || ( $frm_action && in_array( $frm_action, $action, true ) ) ) {
3222 + if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
3579 3223 echo ' class="current_page"';
3580 3224 }
3581 3225 }
3582 3226
@@ -3606,19 +3250,14 @@
3606 3250
3607 3251 // Add extra slashes for \r\n since WP strips them.
3608 3252 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
3609 3253
3610 - // Allow for &quot
3611 - return str_replace( '&quot;', '\\"', $post_content );
3254 + // allow for &quot
3255 + $post_content = str_replace( '&quot;', '\\"', $post_content );
3256 +
3257 + return $post_content;
3612 3258 }
3613 3259
3614 - /**
3615 - * @param array|string $val
3616 - * @param int|string $key
3617 - * @param array $post_content
3618 - *
3619 - * @return void
3620 - */
3621 3260 private static function prepare_action_slashes( $val, $key, &$post_content ) {
3622 3261 if ( ! isset( $post_content[ $key ] ) || is_numeric( $val ) ) {
3623 3262 return;
3624 3263 }
@@ -3627,17 +3266,15 @@
3627 3266 foreach ( $val as $k1 => $v1 ) {
3628 3267 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
3629 3268 unset( $k1, $v1 );
3630 3269 }
3270 + } else {
3271 + // Strip all slashes so everything is the same, no matter where the value is coming from
3272 + $val = stripslashes( $val );
3631 3273
3632 - return;
3274 + // Add backslashes before double quotes and forward slashes only
3275 + $post_content[ $key ] = addcslashes( $val, '"\\/' );
3633 3276 }
3634 -
3635 - // Strip all slashes so everything is the same, no matter where the value is coming from
3636 - $val = stripslashes( $val );
3637 -
3638 - // Add backslashes before double quotes and forward slashes only
3639 - $post_content[ $key ] = addcslashes( $val, '"\\/' );
3640 3277 }
3641 3278
3642 3279 /**
3643 3280 * Check for either json or serialized data. This is temporary while transitioning
@@ -3645,9 +3282,8 @@
3645 3282 *
3646 3283 * @since 4.02.03
3647 3284 *
3648 3285 * @param array|string $value
3649 - *
3650 3286 * @return void
3651 3287 */
3652 3288 public static function unserialize_or_decode( &$value ) {
3653 3289 if ( is_array( $value ) ) {
@@ -3653,9 +3289,13 @@
3653 3289 if ( is_array( $value ) ) {
3654 3290 return;
3655 3291 }
3656 3292
3657 - $value = is_serialized( $value ) ? self::maybe_unserialize_array( $value ) : self::maybe_json_decode( $value, false );
3293 + if ( is_serialized( $value ) ) {
3294 + $value = self::maybe_unserialize_array( $value );
3295 + } else {
3296 + $value = self::maybe_json_decode( $value, false );
3297 + }
3658 3298 }
3659 3299
3660 3300 /**
3661 3301 * Safely unserialize an array if necessary.
@@ -3663,9 +3303,8 @@
3663 3303 *
3664 3304 * @since 6.2
3665 3305 *
3666 3306 * @param mixed $value
3667 - *
3668 3307 * @return mixed
3669 3308 */
3670 3309 public static function maybe_unserialize_array( $value ) {
3671 3310 if ( ! is_string( $value ) ) {
@@ -3672,15 +3311,18 @@
3672 3311 return $value;
3673 3312 }
3674 3313
3675 3314 // Since we only expect an array, skip anything that doesn't start with a:.
3676 - if ( ! is_serialized( $value ) || ! str_starts_with( $value, 'a:' ) ) {
3315 + if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
3677 3316 return $value;
3678 3317 }
3679 3318
3680 3319 $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
3320 + if ( is_array( $parsed ) ) {
3321 + $value = $parsed;
3322 + }
3681 3323
3682 - return is_array( $parsed ) ? $parsed : $value;
3324 + return $value;
3683 3325 }
3684 3326
3685 3327 /**
3686 3328 * Decode a JSON string.
@@ -3685,12 +3327,11 @@
3685 3327 /**
3686 3328 * Decode a JSON string.
3687 3329 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
3688 3330 *
3689 - * @param array|string|null $string
3690 - * @param bool $single_to_array
3691 - *
3692 - * @return array|string|null
3331 + * @param mixed $string
3332 + * @param bool $single_to_array
3333 + * @return mixed
3693 3334 */
3694 3335 public static function maybe_json_decode( $string, $single_to_array = true ) {
3695 3336 if ( is_array( $string ) || is_null( $string ) ) {
3696 3337 return $string;
@@ -3695,19 +3336,20 @@
3695 3336 if ( is_array( $string ) || is_null( $string ) ) {
3696 3337 return $string;
3697 3338 }
3698 3339
3699 - $new_string = json_decode( $string, true );
3700 - $single_value = false;
3701 -
3702 - if ( ! $single_to_array ) {
3703 - $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
3340 + $new_string = json_decode( $string, true );
3341 + if ( function_exists( 'json_last_error' ) ) {
3342 + // php 5.3+
3343 + $single_value = false;
3344 + if ( ! $single_to_array ) {
3345 + $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
3346 + }
3347 + if ( json_last_error() == JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3348 + $string = $new_string;
3349 + }
3704 3350 }
3705 3351
3706 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3707 - return $new_string;
3708 - }
3709 -
3710 3352 return $string;
3711 3353 }
3712 3354
3713 3355 /**
@@ -3713,9 +3355,8 @@
3713 3355 /**
3714 3356 * @since 6.2.3
3715 3357 *
3716 3358 * @param string $value
3717 - *
3718 3359 * @return string
3719 3360 */
3720 3361 public static function maybe_utf8_encode( $value ) {
3721 3362 $from_format = 'ISO-8859-1';
@@ -3724,15 +3365,13 @@
3724 3365 if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
3725 3366 if ( mb_check_encoding( $value, $from_format ) ) {
3726 3367 return mb_convert_encoding( $value, $to_format, $from_format );
3727 3368 }
3728 -
3729 3369 return $value;
3730 3370 }
3731 3371
3732 3372 if ( function_exists( 'iconv' ) ) {
3733 3373 $converted = iconv( $from_format, $to_format, $value );
3734 -
3735 3374 // Value is false if $value is not ISO-8859-1.
3736 3375 if ( false !== $converted ) {
3737 3376 return $converted;
3738 3377 }
@@ -3744,12 +3383,8 @@
3744 3383 /**
3745 3384 * Reformat the json serialized array in name => value array.
3746 3385 *
3747 3386 * @since 4.02.03
3748 - *
3749 - * @param array $form
3750 - *
3751 - * @return void
3752 3387 */
3753 3388 public static function format_form_data( &$form ) {
3754 3389 $formatted = array();
3755 3390
@@ -3756,21 +3391,18 @@
3756 3391 foreach ( $form as $input ) {
3757 3392 if ( ! isset( $input['name'] ) ) {
3758 3393 continue;
3759 3394 }
3760 -
3761 3395 $key = $input['name'];
3762 -
3763 - if ( ! isset( $formatted[ $key ] ) ) {
3396 + if ( isset( $formatted[ $key ] ) ) {
3397 + if ( is_array( $formatted[ $key ] ) ) {
3398 + $formatted[ $key ][] = $input['value'];
3399 + } else {
3400 + $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3401 + }
3402 + } else {
3764 3403 $formatted[ $key ] = $input['value'];
3765 - continue;
3766 3404 }
3767 -
3768 - if ( is_array( $formatted[ $key ] ) ) {
3769 - $formatted[ $key ][] = $input['value'];
3770 - } else {
3771 - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3772 - }
3773 3405 }
3774 3406
3775 3407 parse_str( http_build_query( $formatted ), $form );
3776 3408 }
@@ -3778,13 +3410,15 @@
3778 3410 /**
3779 3411 * @since 4.02.03
3780 3412 *
3781 3413 * @param array|string $value
3782 - *
3783 3414 * @return string
3784 3415 */
3785 3416 public static function maybe_json_encode( $value ) {
3786 - return is_array( $value ) ? wp_json_encode( $value ) : $value;
3417 + if ( is_array( $value ) ) {
3418 + $value = wp_json_encode( $value );
3419 + }
3420 + return $value;
3787 3421 }
3788 3422
3789 3423 /**
3790 3424 * Echo The javascript to open and highlight the Formidable menu
@@ -3791,19 +3425,18 @@
3791 3425 *
3792 3426 * @since 1.07.10
3793 3427 *
3794 3428 * @param string $post_type The name of the post type that may need to be highlighted.
3795 - *
3796 3429 * @return void
3797 3430 */
3798 3431 public static function maybe_highlight_menu( $post_type ) {
3799 3432 global $post;
3800 3433
3801 - if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] !== $post_type ) {
3434 + if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
3802 3435 return;
3803 3436 }
3804 3437
3805 - if ( is_object( $post ) && $post->post_type !== $post_type ) {
3438 + if ( is_object( $post ) && $post->post_type != $post_type ) {
3806 3439 return;
3807 3440 }
3808 3441
3809 3442 self::load_admin_wide_js();
@@ -3815,9 +3448,8 @@
3815 3448 *
3816 3449 * @since 2.0
3817 3450 *
3818 3451 * @param bool $load
3819 - *
3820 3452 * @return void
3821 3453 */
3822 3454 public static function load_admin_wide_js( $load = true ) {
3823 3455 $version = self::plugin_version();
@@ -3828,9 +3460,9 @@
3828 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
3829 3461 'url' => self::plugin_url(),
3830 3462 'app_url' => 'https://formidableforms.com/',
3831 3463 'applicationsUrl' => admin_url( 'admin.php?page=formidable-applications' ),
3832 - 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3464 + 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ),
3833 3465 'loading' => __( 'Loading&hellip;', 'formidable' ),
3834 3466 'nonce' => wp_create_nonce( 'frm_ajax' ),
3835 3467 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
3836 3468 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(),
@@ -3843,9 +3475,8 @@
3843 3475 }
3844 3476
3845 3477 /**
3846 3478 * @since 2.0.9
3847 - *
3848 3479 * @return void
3849 3480 */
3850 3481 public static function load_font_style() {
3851 3482 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
@@ -3852,9 +3483,8 @@
3852 3483 }
3853 3484
3854 3485 /**
3855 3486 * @param string $location
3856 - *
3857 3487 * @return void
3858 3488 */
3859 3489 public static function localize_script( $location ) {
3860 3490 global $wp_scripts, $wp_version;
@@ -3877,9 +3507,8 @@
3877 3507 'include_resend_email' => false,
3878 3508 );
3879 3509
3880 3510 $data = $wp_scripts->get_data( 'formidable', 'data' );
3881 -
3882 3511 if ( ! $data ) {
3883 3512 wp_localize_script( 'formidable', 'frm_js', $script_strings );
3884 3513 }
3885 3514
@@ -3886,9 +3515,9 @@
3886 3515 if ( $location === 'admin' ) {
3887 3516 $admin_script_strings = array(
3888 3517 'desc' => __( '(Click to add description)', 'formidable' ),
3889 3518 'blank' => __( '(Blank)', 'formidable' ),
3890 - 'no_label' => self::get_no_label_text(),
3519 + 'no_label' => __( '(no label)', 'formidable' ),
3891 3520 'ok' => __( 'OK', 'formidable' ),
3892 3521 'cancel' => __( 'Cancel', 'formidable' ),
3893 3522 'default_label' => __( 'Default', 'formidable' ),
3894 3523 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3896,9 +3525,9 @@
3896 3525 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3897 3526 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3898 3527 'confirm' => __( 'Are you sure?', 'formidable' ),
3899 3528 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3900 - 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3529 + 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ),
3901 3530 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3902 3531 'default_unique' => FrmFieldsHelper::default_unique_msg(),
3903 3532 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3904 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
@@ -3904,9 +3533,9 @@
3904 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
3905 3534 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3906 3535 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3907 3536 'new_option' => __( 'New Option', 'formidable' ),
3908 - 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3537 + 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ),
3909 3538 'enter_password' => __( 'Enter Password', 'formidable' ),
3910 3539 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3911 3540 'import_complete' => __( 'Import Complete', 'formidable' ),
3912 3541 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
@@ -3922,11 +3551,11 @@
3922 3551 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ),
3923 3552 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ),
3924 3553 'unsafe_params' => FrmFormsHelper::reserved_words(),
3925 3554 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
3926 - 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3555 + 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
3927 3556 /* Translators: %s is the name of a parameter that is a reserved word. More than one word could be listed here, though that would not be common. */
3928 - 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3557 + 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
3929 3558 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3930 3559 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3931 3560 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3932 3561 'install' => __( 'Install', 'formidable' ),
@@ -3947,9 +3576,9 @@
3947 3576 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
3948 3577 'noTitleText' => FrmFormsHelper::get_no_title_text(),
3949 3578
3950 3579 // In older versions this event listener causes the section to immediately close again
3951 - // When the h3 element is clicked. It's only required in WP 6.7+.
3580 + // when the h3 element is clicked. It's only required in WP 6.7+.
3952 3581 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ),
3953 3582 );
3954 3583 /**
3955 3584 * @param array $admin_script_strings
@@ -3956,9 +3585,8 @@
3956 3585 */
3957 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3958 3587
3959 3588 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
3960 -
3961 3589 if ( ! $data ) {
3962 3590 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
3963 3591 }
3964 3592 }//end if
@@ -3964,19 +3592,8 @@
3964 3592 }//end if
3965 3593 }
3966 3594
3967 3595 /**
3968 - * Get the no label text.
3969 - *
3970 - * @since 6.25.1
3971 - *
3972 - * @return string
3973 - */
3974 - public static function get_no_label_text() {
3975 - return __( '(no label)', 'formidable' );
3976 - }
3977 -
3978 - /**
3979 3596 * @since 6.5
3980 3597 *
3981 3598 * @return string
3982 3599 */
@@ -4018,9 +3635,8 @@
4018 3635 *
4019 3636 * @since 1.07.10
4020 3637 *
4021 3638 * @param float $min_version The version the add-on requires.
4022 - *
4023 3639 * @return void
4024 3640 */
4025 3641 public static function min_version_notice( $min_version ) {
4026 3642 $frm_version = self::plugin_version();
@@ -4030,11 +3646,11 @@
4030 3646 return;
4031 3647 }
4032 3648
4033 3649 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
4034 - 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
4035 - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
4036 - '</div></td></tr>';
3650 + echo '<tr class="plugin-update-tr active"><th colspan="' . absint( $wp_list_table->get_column_count() ) . '" class="check-column plugin-update colspanchange"><div class="update-message">' .
3651 + esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
3652 + '</div></td></tr>';
4037 3653 }
4038 3654
4039 3655 /**
4040 3656 * If Pro is far outdated, show a message.
@@ -4040,10 +3656,8 @@
4040 3656 * If Pro is far outdated, show a message.
4041 3657 *
4042 3658 * @since 4.0.01
4043 3659 *
4044 - * @param string $min_version
4045 - *
4046 3660 * @return void
4047 3661 */
4048 3662 public static function min_pro_version_notice( $min_version ) {
4049 3663 if ( ! self::is_formidable_admin() ) {
@@ -4053,14 +3667,25 @@
4053 3667
4054 3668 self::php_version_notice();
4055 3669
4056 3670 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
4057 -
4058 3671 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
4059 3672 return;
4060 3673 }
4061 3674
4062 - include self::plugin_path() . '/classes/views/addons/min-version-notice.php';
3675 + $expired = FrmAddonsController::is_license_expired();
3676 + ?>
3677 + <div class="frm-banner-alert frm_error_style frm_previous_install">
3678 + <?php
3679 + esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
3680 + if ( empty( $expired ) ) {
3681 + echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
3682 + } else {
3683 + echo '<br/>Please <a href="https://formidableforms.com/account/downloads/?utm_source=WordPress&utm_medium=outdated">renew now</a> to get the latest version.';
3684 + }
3685 + ?>
3686 + </div>
3687 + <?php
4063 3688 }
4064 3689
4065 3690 /**
4066 3691 * If Pro is installed, check the version number.
@@ -4067,9 +3692,8 @@
4067 3692 *
4068 3693 * @since 4.0.01
4069 3694 *
4070 3695 * @param string $min_version
4071 - *
4072 3696 * @return bool
4073 3697 */
4074 3698 public static function meets_min_pro_version( $min_version ) {
4075 3699 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
@@ -4078,19 +3702,16 @@
4078 3702 /**
4079 3703 * Show a message if the PHP version is below the recommendations.
4080 3704 *
4081 3705 * @since 4.0.02
4082 - *
4083 3706 * @return void
4084 3707 */
4085 3708 private static function php_version_notice() {
4086 3709 $message = array();
4087 -
4088 3710 if ( version_compare( phpversion(), '7.0', '<' ) ) {
4089 - $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
3711 + $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' );
4090 3712 }
4091 3713
4092 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4093 3714 foreach ( $message as $m ) {
4094 3715 ?>
4095 3716 <div class="frm-banner-alert frm_error_style frm_previous_install">
4096 3717 <?php echo esc_html( $m ); ?>
@@ -4096,14 +3717,12 @@
4096 3717 <?php echo esc_html( $m ); ?>
4097 3718 </div>
4098 3719 <?php
4099 3720 }
4100 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4101 3721 }
4102 3722
4103 3723 /**
4104 3724 * @param string $type
4105 - *
4106 3725 * @return array<string,string>
4107 3726 */
4108 3727 public static function locales( $type = 'date' ) {
4109 3728 $locales = array(
@@ -4197,12 +3816,12 @@
4197 3816 'zu' => __( 'Zulu', 'formidable' ),
4198 3817 );
4199 3818
4200 3819 if ( $type === 'captcha' ) {
4201 - // Remove the languages unavailable for the captcha
3820 + // remove the languages unavailable for the captcha
4202 3821 $unset = array( 'sq', 'bs', 'eo', 'fo', 'fr-CH', 'sr-SR', 'ar-DZ', 'be', 'cy-GB', 'kk', 'km', 'ky', 'lb', 'mk', 'nb', 'nn', 'rm', 'tj' );
4203 3822 } else {
4204 - // Remove the languages unavailable for the datepicker
3823 + // remove the languages unavailable for the datepicker
4205 3824 $unset = array( 'fil', 'fr-CA', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419', 'mr', 'lo', 'kn', 'si', 'gu', 'bn', 'zu', 'ur', 'te', 'sw', 'am' );
4206 3825 }
4207 3826
4208 3827 $locales = array_diff_key( $locales, array_flip( $unset ) );
@@ -4213,13 +3832,14 @@
4213 3832 * @since 5.4.5 Added $args parameter with type.
4214 3833 *
4215 3834 * @param array<string,string> $locales
4216 3835 * @param array $args {
4217 - *
4218 3836 * @type string $type
4219 3837 * }
4220 3838 */
4221 - return apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3839 + $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3840 +
3841 + return $locales;
4222 3842 }
4223 3843
4224 3844 /**
4225 3845 * @return string
@@ -4226,14 +3846,12 @@
4226 3846 */
4227 3847 public static function get_menu_icon_class() {
4228 3848 if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
4229 3849 $settings = FrmProAppHelper::get_settings();
4230 -
4231 3850 if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
4232 3851 return $settings->menu_icon;
4233 3852 }
4234 3853 }
4235 -
4236 3854 return 'frmfont frm_logo_icon';
4237 3855 }
4238 3856
4239 3857 /**
@@ -4251,9 +3869,10 @@
4251 3869 * @type array $input_attrs Attributes of value input.
4252 3870 * }
4253 3871 */
4254 3872 public static function images_dropdown( $args ) {
4255 - $args = self::fill_default_images_dropdown_args( $args );
3873 + $args = self::fill_default_images_dropdown_args( $args );
3874 +
4256 3875 $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
4257 3876 ob_start();
4258 3877 include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
4259 3878 $output = ob_get_clean();
@@ -4274,9 +3893,8 @@
4274 3893 *
4275 3894 * @since 5.0.04
4276 3895 *
4277 3896 * @param array $args The arguments.
4278 - *
4279 3897 * @return array
4280 3898 */
4281 3899 private static function fill_default_images_dropdown_args( $args ) {
4282 3900 $defaults = array(
@@ -4289,8 +3907,14 @@
4289 3907
4290 3908 $new_args['options'] = (array) $new_args['options'];
4291 3909 $new_args['input_attrs'] = (array) $new_args['input_attrs'];
4292 3910
3911 + // Set the number of columns.
3912 + $new_args['col_class'] = ceil( 12 / count( $new_args['options'] ) );
3913 + if ( $new_args['col_class'] > 6 ) {
3914 + $new_args['col_class'] = ceil( $new_args['col_class'] / 2 );
3915 + }
3916 +
4293 3917 /**
4294 3918 * Allows modifying the arguments of images_dropdown() method.
4295 3919 *
4296 3920 * @since 5.0.04
@@ -4306,9 +3930,8 @@
4306 3930 *
4307 3931 * @since 5.0.04
4308 3932 *
4309 3933 * @param array $args The arguments.
4310 - *
4311 3934 * @return string
4312 3935 */
4313 3936 private static function get_images_dropdown_input_attrs( $args ) {
4314 3937 $input_attrs = $args['input_attrs'];
@@ -4315,9 +3938,8 @@
4315 3938 $input_attrs['type'] = 'radio';
4316 3939 $input_attrs['name'] = $args['name'];
4317 3940
4318 3941 $input_attrs_str = '';
4319 -
4320 3942 foreach ( $input_attrs as $key => $input_attr ) {
4321 3943 $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
4322 3944 }
4323 3945
@@ -4333,13 +3955,8 @@
4333 3955 }
4334 3956
4335 3957 /**
4336 3958 * @since 6.7.1
4337 - *
4338 - * @param array $option Option data.
4339 - * @param array $args The arguments of images_dropdown() method.
4340 - *
4341 - * @return array
4342 3959 */
4343 3960 public static function get_images_dropdown_atts( $option, $args ) {
4344 3961 $image = self::get_images_dropdown_option_image( $option, $args );
4345 3962 $classes = self::get_images_dropdown_option_classes( $option, $args );
@@ -4353,9 +3970,8 @@
4353 3970 * @since 5.0.04
4354 3971 *
4355 3972 * @param array $option Option data.
4356 3973 * @param array $args The arguments of images_dropdown() method.
4357 - *
4358 3974 * @return string
4359 3975 */
4360 3976 private static function get_images_dropdown_option_image( $option, $args ) {
4361 3977 $image = self::icon_by_class(
@@ -4384,9 +4000,8 @@
4384 4000 * @since 5.0.04
4385 4001 *
4386 4002 * @param array $option Option data.
4387 4003 * @param array $args The arguments of images_dropdown() method.
4388 - *
4389 4004 * @return string
4390 4005 */
4391 4006 private static function get_images_dropdown_option_classes( $option, $args ) {
4392 4007 $classes = '';
@@ -4414,19 +4029,17 @@
4414 4029 * @since 5.0.04
4415 4030 *
4416 4031 * @param array $option Option data.
4417 4032 * @param array $args The arguments of images_dropdown() method.
4418 - *
4419 4033 * @return string
4420 4034 */
4421 4035 private static function get_images_dropdown_option_html_attrs( $option, $args ) {
4422 4036 $html_attrs = '';
4423 -
4424 4037 if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
4425 4038 $html_attrs_arr = array();
4426 4039
4427 4040 foreach ( $option['custom_attrs'] as $key => $value ) {
4428 - if ( in_array( $key, array( 'type', 'class', 'data-value' ), true ) ) {
4041 + if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
4429 4042 continue;
4430 4043 }
4431 4044
4432 4045 $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
@@ -4484,9 +4097,8 @@
4484 4097 * @since 5.0.07
4485 4098 *
4486 4099 * @param array $values
4487 4100 * @param array $keys
4488 - *
4489 4101 * @return array
4490 4102 */
4491 4103 public static function maybe_filter_array( $values, $keys ) {
4492 4104 $allow_unfiltered_html = self::allow_unfiltered_html();
@@ -4511,14 +4123,13 @@
4511 4123 * @since 5.0.13
4512 4124 *
4513 4125 * @param string $value
4514 4126 * @param array|string $allowed 'all' for everything included as defaults.
4515 - *
4516 4127 * @return string
4517 4128 */
4518 4129 public static function maybe_kses( $value, $allowed = 'all' ) {
4519 4130 if ( self::should_never_allow_unfiltered_html() ) {
4520 - return self::kses( $value, $allowed );
4131 + $value = self::kses( $value, $allowed );
4521 4132 }
4522 4133 return $value;
4523 4134 }
4524 4135
@@ -4528,18 +4139,17 @@
4528 4139 * @since 6.11.2
4529 4140 *
4530 4141 * @param string $key
4531 4142 * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed.
4532 - *
4533 4143 * @return bool
4534 4144 */
4535 4145 public static function input_key_is_safe( $key, $context = 'display' ) {
4536 4146 if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) {
4537 4147 $safe = true;
4538 - } elseif ( str_starts_with( $key, 'data-' ) ) {
4148 + } elseif ( 0 === strpos( $key, 'data-' ) ) {
4539 4149 // Allow all data attributes.
4540 4150 $safe = true;
4541 - } elseif ( str_starts_with( $key, 'aria-' ) ) {
4151 + } elseif ( 0 === strpos( $key, 'aria-' ) ) {
4542 4152 // Allow all aria attributes.
4543 4153 $safe = true;
4544 4154 } else {
4545 4155 $safe_keys = array(
@@ -4581,9 +4191,16 @@
4581 4191
4582 4192 /**
4583 4193 * @since 5.0.16
4584 4194 *
4585 - * @param string $medium
4195 + * @return bool
4196 + */
4197 + public static function show_landing_pages() {
4198 + return self::show_new_feature( 'landing' );
4199 + }
4200 +
4201 + /**
4202 + * @since 5.0.16
4586 4203 *
4587 4204 * @return array
4588 4205 */
4589 4206 public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
@@ -4591,9 +4208,8 @@
4591 4208 'medium' => $medium,
4592 4209 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
4593 4210 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
4594 4211 'screenshot' => 'landing.png',
4595 - 'learn-more' => self::get_doc_url( 'landing-page-forms', 'form-landing-page-settings', false ),
4596 4212 );
4597 4213 return self::get_upgrade_data_params( 'landing', $params );
4598 4214 }
4599 4215
@@ -4600,35 +4216,24 @@
4600 4216 /**
4601 4217 * @since 5.0.17
4602 4218 *
4603 4219 * @param string $feature
4604 - *
4605 4220 * @return bool
4606 4221 */
4607 4222 public static function show_new_feature( $feature ) {
4608 4223 $link = FrmAddonsController::install_link( $feature );
4609 -
4610 - if ( array_key_exists( 'status', $link ) || array_key_exists( 'class', $link ) ) {
4611 - return true;
4612 - }
4613 -
4614 - return 'coupons' === $feature && class_exists( 'FrmCouponsAppController' );
4224 + return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
4615 4225 }
4616 4226
4617 4227 /**
4618 - * Enhances upgrade data parameters with installation link and plan requirement information.
4619 - *
4620 4228 * @since 5.0.17
4621 4229 *
4622 - * @param string $plugin The plugin slug to get installation data for.
4623 - * @param array $params Initial parameters for the upgrade data.
4624 - * @param bool $detailed Whether to include detailed information.
4625 - *
4626 - * @return array Modified parameters with installation data.
4230 + * @param string $plugin
4231 + * @param array $params
4232 + * @return array
4627 4233 */
4628 - public static function get_upgrade_data_params( $plugin, $params, $detailed = false ) {
4234 + public static function get_upgrade_data_params( $plugin, $params ) {
4629 4235 $link = FrmAddonsController::install_link( $plugin );
4630 -
4631 4236 if ( ! $link ) {
4632 4237 return $params;
4633 4238 }
4634 4239
@@ -4634,20 +4239,15 @@
4634 4239
4635 4240 if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
4636 4241 $params['oneclick'] = json_encode( $link );
4637 4242 unset( $params['message'] );
4638 -
4639 4243 if ( ! isset( $params['medium'] ) ) {
4640 4244 $params['medium'] = $plugin;
4641 4245 }
4642 4246 } else {
4643 - $params['requires'] = $params['requires'] ?? FrmFormsHelper::get_plan_required( $link );
4247 + $params['requires'] = FrmFormsHelper::get_plan_required( $link );
4644 4248 }
4645 4249
4646 - if ( $detailed ) {
4647 - $params['plugin-status'] = $link['status'] ?? '';
4648 - }
4649 -
4650 4250 return $params;
4651 4251 }
4652 4252
4653 4253 /**
@@ -4656,9 +4256,8 @@
4656 4256 *
4657 4257 * @since 5.0.17
4658 4258 *
4659 4259 * @param string $text
4660 - *
4661 4260 * @return bool
4662 4261 */
4663 4262 public static function ctype_xdigit( $text ) {
4664 4263 if ( function_exists( 'ctype_xdigit' ) ) {
@@ -4673,14 +4272,12 @@
4673 4272 * @since 5.2.01
4674 4273 */
4675 4274 public static function set_current_screen_and_hook_suffix() {
4676 4275 global $hook_suffix;
4677 -
4678 4276 if ( is_null( $hook_suffix ) ) {
4679 4277 // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
4680 4278 $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
4681 4279 }
4682 -
4683 4280 set_current_screen();
4684 4281 }
4685 4282
4686 4283 /**
@@ -4687,9 +4284,9 @@
4687 4284 * Shows pill text.
4688 4285 *
4689 4286 * @since 5.2.02
4690 4287 *
4691 - * @param string|null $text Text in the pill. Default is NEW.
4288 + * @param string $text Text in the pill. Default is NEW.
4692 4289 */
4693 4290 public static function show_pill_text( $text = null ) {
4694 4291 if ( null === $text ) {
4695 4292 $text = __( 'NEW', 'formidable' );
@@ -4702,9 +4299,8 @@
4702 4299 *
4703 4300 * @since 5.2.07
4704 4301 *
4705 4302 * @param mixed $num Number.
4706 - *
4707 4303 * @return false|int Returns `false` if the passed parameter is not number.
4708 4304 */
4709 4305 public static function count_decimals( $num ) {
4710 4306 if ( ! is_numeric( $num ) ) {
@@ -4712,9 +4308,8 @@
4712 4308 }
4713 4309
4714 4310 $num = (string) $num;
4715 4311 $parts = explode( '.', $num );
4716 -
4717 4312 if ( 1 === count( $parts ) ) {
4718 4313 return 0;
4719 4314 }
4720 4315
@@ -4796,20 +4391,17 @@
4796 4391 * @since 5.5.5
4797 4392 *
4798 4393 * @param string $url
4799 4394 * @param string $expected_extension
4800 - *
4801 4395 * @return bool
4802 4396 */
4803 4397 public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
4804 - $file_is_in_expected_s3_bucket = str_starts_with( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4805 -
4398 + $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4806 4399 if ( ! $file_is_in_expected_s3_bucket ) {
4807 4400 return false;
4808 4401 }
4809 4402
4810 4403 $parsed = parse_url( $url );
4811 -
4812 4404 if ( ! is_array( $parsed ) ) {
4813 4405 // URL is malformed.
4814 4406 return false;
4815 4407 }
@@ -4815,10 +4407,14 @@
4815 4407 }
4816 4408
4817 4409 $path = $parsed['path'];
4818 4410 $ext = pathinfo( $path, PATHINFO_EXTENSION );
4819 - // The URL isn't to an XML file.
4820 - return $expected_extension === $ext;
4411 + if ( $expected_extension !== $ext ) {
4412 + // The URL isn't to an XML file.
4413 + return false;
4414 + }
4415 +
4416 + return true;
4821 4417 }
4822 4418
4823 4419 /**
4824 4420 * Display a dismissable warning message and save its dismissal state.
@@ -4826,9 +4422,8 @@
4826 4422 * @since 6.3
4827 4423 *
4828 4424 * @param string $message The warning message to display.
4829 4425 * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
4830 - *
4831 4426 * @return void
4832 4427 */
4833 4428 public static function add_dismissable_warning_message( $message = '', $option = '' ) {
4834 4429 if ( ! $message || ! $option ) {
@@ -4871,9 +4466,8 @@
4871 4466 *
4872 4467 * @since 6.3
4873 4468 *
4874 4469 * @param string $option The unique identifier for the dismissal state of the message.
4875 - *
4876 4470 * @return void
4877 4471 */
4878 4472 public static function dismiss_warning_message( $option = '' ) {
4879 4473 self::permission_check( 'frm_change_settings' );
@@ -4879,9 +4473,9 @@
4879 4473 self::permission_check( 'frm_change_settings' );
4880 4474 check_ajax_referer( 'frm_ajax', 'nonce' );
4881 4475
4882 4476 if ( $option ) {
4883 - update_option( $option, true, false );
4477 + update_option( $option, true, 'no' );
4884 4478 }
4885 4479
4886 4480 wp_send_json_success();
4887 4481 }
@@ -4895,8 +4489,17 @@
4895 4489 * @return string
4896 4490 */
4897 4491 public static function copy_for_lite_license() {
4898 4492 $message = __( 'You\'re using Formidable Forms Lite - no license needed. Enjoy!', 'formidable' ) . ' 🙂';
4493 +
4494 + if ( is_callable( 'FrmProAddonsController::get_readable_license_type' ) && ! class_exists( 'FrmProDashboardController' ) ) {
4495 + // Manage PRO versions without PRO dashboard functionality.
4496 + $license_type = FrmProAddonsController::get_readable_license_type();
4497 + if ( 'lite' !== strtolower( $license_type ) ) {
4498 + $message = 'Formidable Pro ' . $license_type;
4499 + }
4500 + }
4501 +
4899 4502 return apply_filters( 'frm_license_type_text', $message );
4900 4503 }
4901 4504
4902 4505 /**
@@ -4902,9 +4505,8 @@
4902 4505 /**
4903 4506 * Removes scripts that are unnecessarily loaded across the pages!
4904 4507 *
4905 4508 * @since 6.9
4906 - *
4907 4509 * @return void
4908 4510 */
4909 4511 public static function dequeue_extra_global_scripts() {
4910 4512 wp_dequeue_script( 'frm-surveys-admin' );
@@ -4922,21 +4524,18 @@
4922 4524 * @return void
4923 4525 */
4924 4526 public static function tooltip_icon( $tooltip_text, $atts = array() ) {
4925 4527 $atts['title'] = $tooltip_text;
4926 -
4927 4528 if ( isset( $atts['class'] ) ) {
4928 4529 $atts['class'] .= ' frm_help';
4929 4530 } else {
4930 4531 $atts['class'] = 'frm_help';
4931 4532 }
4932 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4933 4533 ?>
4934 4534 <span <?php self::array_to_html_params( $atts, true ); ?>>
4935 4535 <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?>
4936 4536 </span>
4937 4537 <?php
4938 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4939 4538 }
4940 4539
4941 4540 /**
4942 4541 * Prints errors for settings in onboarding wizard or template settings.
@@ -4957,10 +4556,8 @@
4957 4556 )
4958 4557 );
4959 4558
4960 4559 $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden';
4961 -
4962 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4963 4560 ?>
4964 4561 <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>">
4965 4562 <?php
4966 4563 if ( is_array( $args['errors'] ) ) {
@@ -4974,9 +4571,8 @@
4974 4571 }
4975 4572 ?>
4976 4573 </span>
4977 4574 <?php
4978 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4979 4575 }
4980 4576
4981 4577 /**
4982 4578 * Check if GDPR is enabled.
@@ -4999,57 +4595,6 @@
4999 4595 */
5000 4596 public static function no_gdpr_cookies() {
5001 4597 $frm_settings = self::get_settings();
5002 4598 return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies;
5003 - }
5004 -
5005 - /**
5006 - * Check if a string is valid UTF-8.
5007 - *
5008 - * @since 6.24
5009 - *
5010 - * @param string $string The string to check.
5011 - *
5012 - * @return bool
5013 - */
5014 - public static function is_valid_utf8( $string ) {
5015 - // wp_is_valid_utf8 is added in WP 6.9.
5016 - if ( function_exists( 'wp_is_valid_utf8' ) ) {
5017 - return wp_is_valid_utf8( $string );
5018 - }
5019 -
5020 - // As of WP 6.9, seems_utf8 is deprecated.
5021 - return function_exists( 'seems_utf8' ) ? seems_utf8( $string ) : false;
5022 - }
5023 -
5024 - /**
5025 - * Get a documentation URL with UTM parameters and affiliate tracking.
5026 - *
5027 - * @since 6.26
5028 - *
5029 - * @param string $path The relative path to append to the base URL.
5030 - * @param string $campaign The campaign to use for UTM parameters.
5031 - * @param bool $add_kb_base Whether to prepend 'knowledgebase/' to the path. Default true.
5032 - *
5033 - * @return string The processed URL with UTM parameters and affiliate tracking.
5034 - */
5035 - public static function get_doc_url( $path, $campaign, $add_kb_base = true ) {
5036 - $path = trim( $path, '/' );
5037 -
5038 - if ( $add_kb_base ) {
5039 - $path = 'knowledgebase/' . $path;
5040 - }
5041 -
5042 - return self::maybe_add_missing_utm( 'https://formidableforms.com/' . $path, array( 'campaign' => $campaign ) );
5043 - }
5044 -
5045 - /**
5046 - * @since 5.0.16
5047 - * @deprecated 6.26
5048 - *
5049 - * @return bool
5050 - */
5051 - public static function show_landing_pages() {
5052 - _deprecated_function( __METHOD__, '6.26' );
5053 - return true;
5054 4599 }
5055 4600 }