PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.22
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.22
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/helpers/FrmAppHelper.php +420 -867 6.286.22 View file →
@@ -9,9 +9,9 @@
9 9 * Version of the database we are moving to.
10 10 *
11 11 * @var int
12 12 */
13 - public static $db_version = 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.28';
32 + public static $plug_version = '6.22';
33 33
34 34 /**
35 35 * @var bool
36 36 */
@@ -55,9 +55,9 @@
55 55 /**
56 56 * @return string
57 57 */
58 58 public static function plugin_path() {
59 - return dirname( __DIR__, 2 );
59 + return dirname( dirname( __DIR__ ) );
60 60 }
61 61
62 62 /**
63 63 * @return string
@@ -85,9 +85,8 @@
85 85 * Get the name of this site
86 86 * Used for [sitename] shortcode
87 87 *
88 88 * @since 2.0
89 - *
90 89 * @return string
91 90 */
92 91 public static function site_name() {
93 92 return get_option( 'blogname' );
@@ -94,15 +93,13 @@
94 93 }
95 94
96 95 /**
97 96 * @param string $url
98 - *
99 97 * @return string
100 98 */
101 99 public static function make_affiliate_url( $url ) {
102 100 $affiliate_id = self::get_affiliate();
103 -
104 - if ( $affiliate_id ) {
101 + if ( ! empty( $affiliate_id ) ) {
105 102 $url = str_replace( array( 'http://', 'https://' ), '', $url );
106 103 $url = 'http://www.shareasale.com/r.cfm?u=' . absint( $affiliate_id ) . '&b=841990&m=64739&afftrack=plugin&urllink=' . urlencode( $url );
107 104 }
108 105
@@ -117,124 +114,55 @@
117 114 }
118 115
119 116 /**
120 117 * @since 3.04.02
121 - *
122 - * @param array|string $args If a string is passed, it is used for the utm_campaign attribute.
118 + * @param array|string $args
123 119 * @param string $page
124 120 */
125 121 public static function admin_upgrade_link( $args, $page = '' ) {
126 - if ( $page ) {
122 + if ( empty( $page ) ) {
123 + $page = 'https://formidableforms.com/lite-upgrade/';
124 + } else {
127 125 $page = str_replace( 'https://formidableforms.com/', '', $page );
128 126 $page = 'https://formidableforms.com/' . $page;
127 + }
128 +
129 + $anchor = '';
130 + if ( is_array( $args ) ) {
131 + $medium = isset( $args['medium'] ) ? $args['medium'] : '';
132 + if ( isset( $args['content'] ) ) {
133 + $content = $args['content'];
134 + }
135 + if ( isset( $args['anchor'] ) ) {
136 + $anchor = '#' . $args['anchor'];
137 + }
129 138 } else {
130 - $page = 'https://formidableforms.com/lite-upgrade/';
139 + $medium = $args;
131 140 }
132 141
133 - $args = is_array( $args ) ? self::adjust_legacy_utm_args( $args ) : array( 'campaign' => $args );
134 -
135 142 $query_args = array(
136 - 'utm_source' => 'plugin',
137 - 'utm_medium' => self::get_utm_medium(),
143 + 'utm_source' => 'WordPress',
144 + 'utm_medium' => $medium,
145 + 'utm_campaign' => 'liteplugin',
138 146 );
139 - $query_args = self::maybe_add_utm_license( $query_args );
140 147
141 - if ( isset( $args['campaign'] ) ) {
142 - $query_args['utm_campaign'] = $args['campaign'];
148 + if ( isset( $content ) ) {
149 + $query_args['utm_content'] = $content;
143 150 }
144 151
145 - if ( isset( $args['content'] ) ) {
146 - $query_args['utm_content'] = $args['content'];
147 - }
148 -
149 - if ( isset( $args['param'] ) ) {
152 + if ( is_array( $args ) && isset( $args['param'] ) ) {
150 153 $query_args['f'] = $args['param'];
151 154 }
152 155
153 - if ( ! empty( $args['plan'] ) ) {
156 + if ( is_array( $args ) && ! empty( $args['plan'] ) ) {
154 157 $query_args['plan'] = $args['plan'];
155 158 }
156 159
157 - $link = add_query_arg( $query_args, $page );
158 -
159 - if ( isset( $args['anchor'] ) ) {
160 - $link .= '#' . $args['anchor'];
161 - }
162 -
160 + $link = add_query_arg( $query_args, $page ) . $anchor;
163 161 return self::make_affiliate_url( $link );
164 162 }
165 163
166 164 /**
167 - * If medium is "pro", add an additional utm_license param with their active license type.
168 - *
169 - * @since 6.25.1
170 - *
171 - * @param array $query_args
172 - * @param string $link
173 - *
174 - * @return array
175 - */
176 - private static function maybe_add_utm_license( $query_args, $link = '' ) {
177 - $medium = $query_args['utm_medium'] ?? self::pull_medium_from_link( $link );
178 -
179 - if ( 'pro' === $medium && is_callable( 'FrmProAddonsController::get_readable_license_type' ) ) {
180 - $query_args['utm_license'] = strtolower( FrmProAddonsController::get_readable_license_type() );
181 - }
182 -
183 - return $query_args;
184 - }
185 -
186 - /**
187 - * @since 6.26
188 - *
189 - * @param string $link
190 - *
191 - * @return string
192 - */
193 - private static function pull_medium_from_link( $link ) {
194 - if ( ! $link ) {
195 - return '';
196 - }
197 -
198 - $parsed = parse_url( $link );
199 -
200 - if ( ! is_array( $parsed ) || ! isset( $parsed['query'] ) ) {
201 - return '';
202 - }
203 -
204 - $query_args = wp_parse_args( $parsed['query'] );
205 -
206 - return ! empty( $query_args['utm_medium'] ) ? $query_args['utm_medium'] : '';
207 - }
208 -
209 - /**
210 - * @since 6.25.1
211 - *
212 - * @return string
213 - */
214 - private static function get_utm_medium() {
215 - return self::pro_is_connected() ? 'pro' : 'lite';
216 - }
217 -
218 - /**
219 - * Change campaign from "liteplugin" to what we're currently using for medium.
220 - *
221 - * @since 6.25.1
222 - *
223 - * @param array $args
224 - *
225 - * @return array
226 - */
227 - private static function adjust_legacy_utm_args( $args ) {
228 - if ( isset( $args['medium'] ) ) {
229 - $args['campaign'] = $args['medium'];
230 - unset( $args['medium'] );
231 - }
232 -
233 - return $args;
234 - }
235 -
236 - /**
237 165 * @since 6.21
238 166 *
239 167 * @param string $cta_link
240 168 * @param array $utm
@@ -239,29 +167,26 @@
239 167 * @param string $cta_link
240 168 * @param array $utm
241 169 */
242 170 public static function maybe_add_missing_utm( $cta_link, $utm ) {
243 - $utm = self::adjust_legacy_utm_args( $utm );
244 171 $query_args = array();
245 172
246 - if ( ! str_contains( $cta_link, 'utm_source' ) ) {
247 - $query_args['utm_source'] = 'plugin';
173 + if ( false === strpos( $cta_link, 'utm_source' ) ) {
174 + $query_args['utm_source'] = 'WordPress';
248 175 }
249 176
250 - if ( ! str_contains( $cta_link, 'utm_medium' ) ) {
251 - $query_args['utm_medium'] = self::get_utm_medium();
177 + if ( false === strpos( $cta_link, 'utm_campaign' ) ) {
178 + $query_args['utm_campaign'] = 'liteplugin';
252 179 }
253 180
254 - if ( ! str_contains( $cta_link, 'utm_campaign' ) && isset( $utm['campaign'] ) ) {
255 - $query_args['utm_campaign'] = $utm['campaign'];
181 + if ( false === strpos( $cta_link, 'utm_medium' ) && isset( $utm['medium'] ) ) {
182 + $query_args['utm_medium'] = $utm['medium'];
256 183 }
257 184
258 - if ( ! str_contains( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) {
185 + if ( false === strpos( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) {
259 186 $query_args['utm_content'] = $utm['content'];
260 187 }
261 188
262 - $query_args = self::maybe_add_utm_license( $query_args, $cta_link );
263 -
264 189 return $query_args ? add_query_arg( $query_args, $cta_link ) : $cta_link;
265 190 }
266 191
267 192 /**
@@ -269,15 +194,13 @@
269 194 *
270 195 * @since 2.0
271 196 *
272 197 * @param array $args - May include the form id when values need translation.
273 - *
274 - * @return FrmSettings
198 + * @return FrmSettings $frm_settings
275 199 */
276 200 public static function get_settings( $args = array() ) {
277 201 global $frm_settings;
278 -
279 - if ( ! $frm_settings ) {
202 + if ( empty( $frm_settings ) ) {
280 203 $frm_settings = new FrmSettings( $args );
281 204 } elseif ( isset( $args['current_form'] ) ) {
282 205 // If the global has already been set, allow strings to be filtered.
283 206 $frm_settings->maybe_filter_for_form( $args );
@@ -289,13 +212,11 @@
289 212 /**
290 213 * @return string
291 214 */
292 215 public static function get_menu_name() {
293 - if ( ! self::pro_is_installed() || FrmAddonsController::is_license_expired() ) {
294 - return 'Formidable';
295 - }
216 + $frm_settings = self::get_settings();
296 217
297 - return self::get_settings()->menu;
218 + return FrmAddonsController::is_license_expired() ? 'Formidable' : $frm_settings->menu;
298 219 }
299 220
300 221 /**
301 222 * Determine if the current branding is set to 'formidable'.
@@ -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' ) ) {
@@ -974,15 +860,12 @@
974 860 * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&amp;'
975 861 * this MUST be done, else we'll be back to the '& entity' problem.
976 862 *
977 863 * @since 4.0.04
978 - *
979 - * @param mixed $value Value to decode, passed by reference.
980 864 */
981 865 public static function decode_specialchars( &$value ) {
982 866 if ( is_array( $value ) ) {
983 867 $temp_values = $value;
984 -
985 868 foreach ( $temp_values as $k => $v ) {
986 869 self::decode_specialchars( $value[ $k ] );
987 870 }
988 871 } else {
@@ -996,13 +879,13 @@
996 879 * Adapted from wp_specialchars_decode().
997 880 *
998 881 * @since 4.03.01
999 882 *
1000 - * @param string $string The string to prep, passed by reference.
883 + * @param string $string The string to prep.
1001 884 */
1002 885 private static function decode_amp( &$string ) {
1003 886 // Don't bother if there are no entities - saves a lot of processing
1004 - if ( ! $string || ! str_contains( $string, '&' ) ) {
887 + if ( empty( $string ) || strpos( $string, '&' ) === false ) {
1005 888 return;
1006 889 }
1007 890
1008 891 $translation = array(
@@ -1040,15 +923,16 @@
1040 923 * Sanitize the value, and allow some HTML
1041 924 *
1042 925 * @since 2.0
1043 926 *
1044 - * @param string $value The value to sanitize.
1045 - * @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.
1046 929 *
1047 930 * @return string
1048 931 */
1049 932 public static function kses( $value, $allowed = array() ) {
1050 933 $allowed_html = self::allowed_html( $allowed );
934 +
1051 935 return wp_kses( $value, $allowed_html );
1052 936 }
1053 937
1054 938 /**
@@ -1057,9 +941,8 @@
1057 941 * @since 6.18
1058 942 *
1059 943 * @param string $value The value to sanitize and output.
1060 944 * @param array|string $allowed Allowed HTML tags and attributes.
1061 - *
1062 945 * @return void
1063 946 */
1064 947 public static function kses_echo( $value, $allowed = array() ) {
1065 948 echo self::kses( $value, $allowed ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -1070,23 +953,21 @@
1070 953 *
1071 954 * @since 5.0.13
1072 955 *
1073 956 * @param string $html
1074 - *
1075 957 * @return string
1076 958 */
1077 959 public static function kses_submit_button( $html ) {
1078 - $included_button_action = str_contains( $html, '[button_action]' );
1079 - $included_back_hook = str_contains( $html, '[back_hook]' );
1080 - $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]' );
1081 963 add_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1082 964 add_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1083 965 $html = self::kses( $html, 'all' );
1084 966 remove_filter( 'safe_style_css', 'FrmAppHelper::allow_visibility_style' );
1085 967 remove_filter( 'frm_striphtml_allowed_tags', 'FrmAppHelper::add_allowed_submit_button_tags' );
1086 -
1087 968 if ( $included_button_action ) {
1088 - if ( str_contains( $html, '<input type="submit"' ) ) {
969 + if ( false !== strpos( $html, '<input type="submit"' ) ) {
1089 970 $pattern = '/(<input type="submit")([^>]*)(\/>)/';
1090 971 $html = preg_replace( $pattern, '$1$2[button_action] $3', $html, 1 );
1091 972 } else {
1092 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
@@ -1092,17 +973,14 @@
1092 973 $pattern = '/(<button)(.*)(class=")(.*)(frm_button_submit)(.*)(")(.*)([^>]+)(>)/';
1093 974 $html = preg_replace( $pattern, '$1$2$3$4$5$6$7 [button_action]$8$9$10', $html, 1 );
1094 975 }
1095 976 }
1096 -
1097 977 if ( $included_back_hook ) {
1098 978 $html = str_replace( 'class="frm_prev_page"', 'class="frm_prev_page" [back_hook]', $html );
1099 979 }
1100 -
1101 980 if ( $included_draft_hook ) {
1102 - 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 );
1103 982 }
1104 -
1105 983 return $html;
1106 984 }
1107 985
1108 986 /**
@@ -1108,9 +986,8 @@
1108 986 /**
1109 987 * @since 5.0.13
1110 988 *
1111 989 * @param array $allowed_attr
1112 - *
1113 990 * @return array
1114 991 */
1115 992 public static function allow_visibility_style( $allowed_attr ) {
1116 993 $allowed_attr[] = 'visibility';
@@ -1120,9 +997,8 @@
1120 997 /**
1121 998 * @since 5.0.13
1122 999 *
1123 1000 * @param array $allowed_html
1124 - *
1125 1001 * @return array
1126 1002 */
1127 1003 public static function add_allowed_submit_button_tags( $allowed_html ) {
1128 1004 $allowed_html['input'] = array(
@@ -1139,22 +1015,17 @@
1139 1015 }
1140 1016
1141 1017 /**
1142 1018 * @since 2.05.03
1143 - *
1144 - * @param array|string $allowed
1145 - *
1146 - * @return array
1147 1019 */
1148 1020 private static function allowed_html( $allowed ) {
1149 1021 $html = self::safe_html();
1150 1022 $allowed_html = array();
1151 -
1152 1023 if ( $allowed === 'all' ) {
1153 1024 $allowed_html = $html;
1154 - } elseif ( $allowed ) {
1025 + } elseif ( ! empty( $allowed ) ) {
1155 1026 foreach ( (array) $allowed as $a ) {
1156 - $allowed_html[ $a ] = $html[ $a ] ?? array();
1027 + $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
1157 1028 }
1158 1029 }
1159 1030
1160 1031 return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
@@ -1161,10 +1032,8 @@
1161 1032 }
1162 1033
1163 1034 /**
1164 1035 * @since 2.05.03
1165 - *
1166 - * @return array
1167 1036 */
1168 1037 private static function safe_html() {
1169 1038 $allow_class = array(
1170 1039 'class' => true,
@@ -1316,16 +1185,14 @@
1316 1185 return;
1317 1186 }
1318 1187
1319 1188 $action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' );
1320 -
1321 - if ( ! $action_name ) {
1189 + if ( empty( $action_name ) ) {
1322 1190 return;
1323 1191 }
1324 1192
1325 1193 $new_action = self::get_param( $action_name, '', 'get', 'sanitize_text_field' );
1326 -
1327 - if ( $new_action ) {
1194 + if ( ! empty( $new_action ) ) {
1328 1195 $_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', self::get_server_value( 'REQUEST_URI' ) );
1329 1196 }
1330 1197 }
1331 1198
@@ -1332,23 +1199,21 @@
1332 1199 /**
1333 1200 * Check the WP query for a parameter
1334 1201 *
1335 1202 * @since 2.0
1336 - *
1337 - * @param array|string $value
1338 - * @param string $param
1339 - *
1340 1203 * @return array|string
1341 1204 */
1342 1205 public static function get_query_var( $value, $param ) {
1343 - // phpcs:ignore Universal.Operators.StrictComparisons
1344 1206 if ( $value != '' ) {
1345 1207 return $value;
1346 1208 }
1347 1209
1348 1210 global $wp_query;
1211 + if ( isset( $wp_query->query_vars[ $param ] ) ) {
1212 + $value = $wp_query->query_vars[ $param ];
1213 + }
1349 1214
1350 - return $wp_query->query_vars[ $param ] ?? $value;
1215 + return $value;
1351 1216 }
1352 1217
1353 1218 /**
1354 1219 * Try to show the SVG if possible. Otherwise, use the font icon.
@@ -1356,21 +1221,20 @@
1356 1221 * @since 4.0.02
1357 1222 *
1358 1223 * @param string $class
1359 1224 * @param array $atts
1360 - *
1361 1225 * @return string|null
1362 1226 */
1363 1227 public static function icon_by_class( $class, $atts = array() ) {
1364 1228 $echo = ! isset( $atts['echo'] ) || $atts['echo'];
1365 -
1366 1229 if ( isset( $atts['echo'] ) ) {
1367 1230 unset( $atts['echo'] );
1368 1231 }
1369 1232
1370 1233 $html_atts = self::array_to_html_params( $atts );
1371 - $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1372 1234
1235 + $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
1236 +
1373 1237 // Replace icons that have been removed or renamed.
1374 1238 $deprecated = array(
1375 1239 'frm_clone_solid_icon' => 'frm_clone_icon',
1376 1240 'frm_keyalt_icon' => 'frm_key_icon',
@@ -1375,9 +1239,8 @@
1375 1239 'frm_clone_solid_icon' => 'frm_clone_icon',
1376 1240 'frm_keyalt_icon' => 'frm_key_icon',
1377 1241 'frm_keyalt_solid_icon' => 'frm_key_solid_icon',
1378 1242 );
1379 -
1380 1243 if ( isset( $deprecated[ $icon ] ) ) {
1381 1244 $icon = $deprecated[ $icon ];
1382 1245 $class = str_replace( $icon, $deprecated[ $icon ], $class );
1383 1246 }
@@ -1384,24 +1247,21 @@
1384 1247
1385 1248 if ( $icon === $class ) {
1386 1249 $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
1387 1250 } else {
1388 - $class = str_contains( $icon, ' ' ) ? ' ' . $icon : '';
1389 -
1390 - if ( str_contains( $icon, ' ' ) ) {
1251 + $class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
1252 + if ( strpos( $icon, ' ' ) ) {
1391 1253 $icon = explode( ' ', $icon );
1392 1254 $icon = reset( $icon );
1393 1255 }
1394 -
1395 - $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>';
1396 1257 }
1397 1258
1398 1259 if ( $echo ) {
1399 1260 echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1400 - return null;
1261 + } else {
1262 + return $icon;
1401 1263 }
1402 -
1403 - return $icon;
1404 1264 }
1405 1265
1406 1266 /**
1407 1267 * Run kses for icons. It needs to add a few filters first in order to preserve some custom style values.
@@ -1408,9 +1268,8 @@
1408 1268 *
1409 1269 * @since 5.0.13
1410 1270 *
1411 1271 * @param string $icon
1412 - *
1413 1272 * @return string
1414 1273 */
1415 1274 public static function kses_icon( $icon ) {
1416 1275 add_filter( 'safe_style_css', 'FrmAppHelper::allow_vars_in_styles' );
@@ -1426,15 +1285,13 @@
1426 1285 /**
1427 1286 * @since 5.0.13.1
1428 1287 *
1429 1288 * @param array $allowed_html
1430 - *
1431 1289 * @return array
1432 1290 */
1433 1291 public static function add_allowed_icon_tags( $allowed_html ) {
1434 1292 $allowed_html['svg']['data-open'] = true;
1435 1293 $allowed_html['svg']['title'] = true;
1436 - $allowed_html['svg']['tabindex'] = true;
1437 1294 return $allowed_html;
1438 1295 }
1439 1296
1440 1297 /**
@@ -1440,9 +1297,8 @@
1440 1297 /**
1441 1298 * @since 5.0.13
1442 1299 *
1443 1300 * @param array $allowed_attr
1444 - *
1445 1301 * @return array
1446 1302 */
1447 1303 public static function allow_vars_in_styles( $allowed_attr ) {
1448 1304 $allowed_attr[] = '--primary-700';
@@ -1455,9 +1311,9 @@
1455 1311 * @param bool $allow_css
1456 1312 * @param string $css_string
1457 1313 */
1458 1314 public static function allow_style( $allow_css, $css_string ) {
1459 - if ( ! $allow_css && str_starts_with( $css_string, '--primary-700:' ) ) {
1315 + if ( ! $allow_css && 0 === strpos( $css_string, '--primary-700:' ) ) {
1460 1316 $split = explode( ':', $css_string, 2 );
1461 1317 $allow_css = 2 === count( $split ) && self::is_a_valid_color( $split[1] );
1462 1318 }
1463 1319 return $allow_css;
@@ -1466,22 +1322,19 @@
1466 1322 /**
1467 1323 * @since 5.0.13
1468 1324 *
1469 1325 * @param string $value
1470 - *
1471 1326 * @return bool
1472 1327 */
1473 1328 private static function is_a_valid_color( $value ) {
1474 1329 $match = 0;
1475 -
1476 - if ( str_starts_with( $value, 'rgba(' ) ) {
1330 + if ( 0 === strpos( $value, 'rgba(' ) ) {
1477 1331 $match = preg_match( '/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/', $value );
1478 - } elseif ( str_starts_with( $value, 'rgb(' ) ) {
1332 + } elseif ( 0 === strpos( $value, 'rgb(' ) ) {
1479 1333 $match = preg_match( '/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/', $value );
1480 - } elseif ( str_starts_with( $value, '#' ) ) {
1334 + } elseif ( 0 === strpos( $value, '#' ) ) {
1481 1335 $match = preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})\b$/', $value );
1482 1336 }
1483 -
1484 1337 return (bool) $match;
1485 1338 }
1486 1339
1487 1340 /**
@@ -1487,9 +1340,8 @@
1487 1340 /**
1488 1341 * Include svg images.
1489 1342 *
1490 1343 * @since 4.0.02
1491 - *
1492 1344 * @return void
1493 1345 */
1494 1346 public static function include_svg() {
1495 1347 if ( self::$included_svg ) {
@@ -1508,9 +1360,8 @@
1508 1360 * @since 5.0.13 added $echo parameter.
1509 1361 *
1510 1362 * @param array $atts
1511 1363 * @param bool $echo
1512 - *
1513 1364 * @return string|void
1514 1365 */
1515 1366 public static function array_to_html_params( $atts, $echo = false ) {
1516 1367 $callback = function () use ( $atts ) {
@@ -1529,9 +1380,8 @@
1529 1380 * @since 5.0.13
1530 1381 *
1531 1382 * @param Closure $echo_function
1532 1383 * @param bool $echo
1533 - *
1534 1384 * @return string|null
1535 1385 */
1536 1386 public static function clip( $echo_function, $echo = false ) {
1537 1387 if ( ! $echo ) {
@@ -1541,9 +1391,13 @@
1541 1391 if ( is_callable( $echo_function ) ) {
1542 1392 $echo_function();
1543 1393 }
1544 1394
1545 - return $echo ? null : ob_get_clean();
1395 + if ( ! $echo ) {
1396 + $return = ob_get_contents();
1397 + ob_end_clean();
1398 + return $return;
1399 + }
1546 1400 }
1547 1401
1548 1402 /**
1549 1403 * @since 3.0
@@ -1548,18 +1402,15 @@
1548 1402 /**
1549 1403 * @since 3.0
1550 1404 *
1551 1405 * @param array $atts
1552 - *
1553 1406 * @return void
1554 1407 */
1555 1408 public static function get_admin_header( $atts ) {
1556 1409 $has_nav = ! empty( $atts['form'] ) && empty( $atts['is_template'] );
1557 -
1558 1410 if ( empty( $atts['close'] ) ) {
1559 1411 $atts['close'] = admin_url( 'admin.php?page=formidable' );
1560 1412 }
1561 -
1562 1413 if ( ! isset( $atts['import_link'] ) ) {
1563 1414 $atts['import_link'] = false;
1564 1415 }
1565 1416
@@ -1569,19 +1420,16 @@
1569 1420 /**
1570 1421 * @since 6.0
1571 1422 *
1572 1423 * @param string $type
1573 - *
1574 1424 * @return void
1575 1425 */
1576 1426 public static function import_link( $type = 'secondary' ) {
1577 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1578 1427 ?>
1579 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">
1580 1429 <?php esc_html_e( 'Import', 'formidable' ); ?>
1581 1430 </a>
1582 1431 <?php
1583 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1584 1432 }
1585 1433
1586 1434 /**
1587 1435 * Print applicable admin banner.
@@ -1588,9 +1436,8 @@
1588 1436 *
1589 1437 * @since 5.4.2
1590 1438 *
1591 1439 * @param bool $should_show_lite_upgrade
1592 - *
1593 1440 * @return void
1594 1441 */
1595 1442 public static function print_admin_banner( $should_show_lite_upgrade ) {
1596 1443 if ( ! current_user_can( 'administrator' ) ) {
@@ -1602,15 +1449,13 @@
1602 1449 // Print license warning or inbox banner and exit if either prints.
1603 1450 // And exit before printing the upgrade bar if it shouldn't be shown.
1604 1451 return;
1605 1452 }
1606 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1607 1453 ?>
1608 1454 <div class="frm-upgrade-bar">
1609 1455 <div class="frm-upgrade-bar-inner">
1610 1456 <?php
1611 1457 $cta_text = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_text' );
1612 -
1613 1458 if ( ! $cta_text ) {
1614 1459 $cta_text = __( 'upgrading to PRO', 'formidable' );
1615 1460 }
1616 1461
@@ -1615,13 +1460,17 @@
1615 1460 }
1616 1461
1617 1462 $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' );
1618 1463 $utm = array(
1619 - 'campaign' => 'settings-license',
1620 - 'content' => 'lite-banner',
1464 + 'medium' => 'settings-license',
1465 + 'content' => 'lite-banner',
1621 1466 );
1622 1467
1623 - $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 + }
1624 1473
1625 1474 printf(
1626 1475 /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */
1627 1476 esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ),
@@ -1632,9 +1481,8 @@
1632 1481 ?>
1633 1482 </div>
1634 1483 </div>
1635 1484 <?php
1636 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1637 1485 }
1638 1486
1639 1487 /**
1640 1488 * @since 5.4.2
@@ -1648,9 +1496,8 @@
1648 1496 /**
1649 1497 * Render a button for a new item (Form, Application, etc).
1650 1498 *
1651 1499 * @since 3.0
1652 - *
1653 1500 * @param array $atts {
1654 1501 * Details about the button.
1655 1502 *
1656 1503 * @type array $link_hook Custom link hook, calls do_action and exits early.
@@ -1657,9 +1504,8 @@
1657 1504 * @type string $new_link Href value, default #.
1658 1505 * @type string $class Custom class names, space separated.
1659 1506 * @type string $button_text Button text. Default "Add New".
1660 1507 * }
1661 - *
1662 1508 * @return void
1663 1509 */
1664 1510 public static function add_new_item_link( $atts ) {
1665 1511 if ( isset( $atts['link_hook'] ) ) {
@@ -1685,12 +1531,8 @@
1685 1531 }
1686 1532
1687 1533 /**
1688 1534 * @since 3.06
1689 - *
1690 - * @param array $atts
1691 - *
1692 - * @return void
1693 1535 */
1694 1536 public static function show_search_box( $atts ) {
1695 1537 $defaults = array(
1696 1538 'placeholder' => '',
@@ -1697,9 +1539,8 @@
1697 1539 'tosearch' => '',
1698 1540 'text' => __( 'Search', 'formidable' ),
1699 1541 'input_id' => '',
1700 1542 'value' => false,
1701 - 'class' => '',
1702 1543 );
1703 1544 $atts = array_merge( $defaults, $atts );
1704 1545
1705 1546 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
@@ -1706,9 +1547,8 @@
1706 1547 $atts['tosearch'] = 'frm-card';
1707 1548 }
1708 1549
1709 1550 $class = 'frm-search-input';
1710 -
1711 1551 if ( ! empty( $atts['tosearch'] ) ) {
1712 1552 $class .= ' frm-auto-search';
1713 1553 }
1714 1554
@@ -1732,15 +1572,14 @@
1732 1572
1733 1573 if ( ! empty( $atts['tosearch'] ) ) {
1734 1574 $input_atts['autocomplete'] = 'off';
1735 1575 }
1736 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1737 1576 ?>
1738 - <p class="frm-search <?php echo esc_attr( $atts['class'] ); ?>">
1577 + <p class="frm-search">
1739 1578 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
1740 1579 <?php echo esc_html( $atts['text'] ); ?>:
1741 1580 </label>
1742 - <?php self::icon_by_class( 'frmfont frm_search_icon frm_svg20' ); ?>
1581 + <span class="frmfont frm_search_icon"></span>
1743 1582 <input <?php self::array_to_html_params( $input_atts, true ); ?> />
1744 1583 <?php
1745 1584 if ( empty( $atts['tosearch'] ) ) {
1746 1585 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
@@ -1747,21 +1586,17 @@
1747 1586 }
1748 1587 ?>
1749 1588 </p>
1750 1589 <?php
1751 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1752 1590 }
1753 1591
1754 1592 /**
1755 - * @param string $type Hook type slug.
1756 - * @param object|null $object Optional related object.
1757 - *
1593 + * @param string $type
1758 1594 * @return void
1759 1595 */
1760 1596 public static function trigger_hook_load( $type, $object = null ) {
1761 1597 // Only load the form hooks once.
1762 1598 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
1763 -
1764 1599 if ( ! $hooks_loaded ) {
1765 1600 do_action( 'frm_load_' . $type . '_hooks' );
1766 1601 }
1767 1602 }
@@ -1820,14 +1655,14 @@
1820 1655 * True when value is 1, true, 'true', 'yes'
1821 1656 *
1822 1657 * @since 1.07.10
1823 1658 *
1824 - * @param bool|int|string $value The value to compare.
1659 + * @param string $value The value to compare.
1825 1660 *
1826 1661 * @return bool
1827 1662 */
1828 1663 public static function is_true( $value ) {
1829 - return true === $value || '1' === (string) $value || 'true' === $value || 'yes' === $value;
1664 + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value;
1830 1665 }
1831 1666
1832 1667 /**
1833 1668 * Gets all post from a specific post type.
@@ -1835,9 +1670,8 @@
1835 1670 *
1836 1671 * @since 4.10.01 Add `$post_type` argument.
1837 1672 *
1838 1673 * @param string $post_type Post type to query. Default is `page`.
1839 - *
1840 1674 * @return WP_Post[]
1841 1675 */
1842 1676 public static function get_pages( $post_type = 'page' ) {
1843 1677 $query = array(
@@ -1856,9 +1690,8 @@
1856 1690 *
1857 1691 * @since 5.0.09
1858 1692 *
1859 1693 * @param string $post_type Post type to query. Default is `page`.
1860 - *
1861 1694 * @return array
1862 1695 */
1863 1696 public static function get_post_ids_and_titles( $post_type = 'page' ) {
1864 1697 return FrmDb::get_results(
@@ -1883,9 +1716,10 @@
1883 1716 *
1884 1717 * @param array $args Selection arguments.
1885 1718 */
1886 1719 public static function maybe_autocomplete_pages_options( $args ) {
1887 - $args = self::preformat_selection_args( $args );
1720 + $args = self::preformat_selection_args( $args );
1721 +
1888 1722 $pages_count = wp_count_posts( $args['post_type'] );
1889 1723
1890 1724 if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) {
1891 1725 self::wp_pages_dropdown( $args );
@@ -1932,11 +1766,11 @@
1932 1766 'value_key' => 'value',
1933 1767 'label_key' => 'label',
1934 1768 );
1935 1769
1936 - $args = wp_parse_args( $args, $defaults );
1770 + $args = wp_parse_args( $args, $defaults );
1771 +
1937 1772 $html_attrs = array();
1938 -
1939 1773 if ( ! empty( $args['name'] ) ) {
1940 1774 $html_attrs['name'] = $args['name'];
1941 1775 }
1942 1776
@@ -1943,9 +1777,8 @@
1943 1777 if ( ! empty( $args['id'] ) ) {
1944 1778 $html_attrs['id'] = $args['id'];
1945 1779 }
1946 1780
1947 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1948 1781 if ( count( $args['source'] ) <= $args['dropdown_limit'] ) {
1949 1782 ?>
1950 1783 <select <?php self::array_to_html_params( $html_attrs, true ); ?>>
1951 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
@@ -1951,44 +1784,40 @@
1951 1784 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1952 1785 <?php
1953 1786 foreach ( $args['source'] as $key => $source ) :
1954 1787 $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1955 -
1956 1788 if ( ! empty( $args['truncate'] ) ) {
1957 1789 $value_label['label'] = self::truncate( $value_label['label'], $args['truncate'] );
1958 1790 }
1959 1791 ?>
1960 - <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>
1961 1793 <?php endforeach; ?>
1962 1794 </select>
1963 1795 <?php
1964 - return;
1965 - }
1966 - // 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 );
1967 1801
1968 - $options = array();
1969 - $autocomplete_value = '';
1802 + if ( $value_label['value'] === $args['selected'] ) {
1803 + $autocomplete_value = $value_label['label'];
1804 + }
1970 1805
1971 - foreach ( $args['source'] as $key => $source ) {
1972 - $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args );
1973 -
1974 - if ( $value_label['value'] === $args['selected'] ) {
1975 - $autocomplete_value = $value_label['label'];
1806 + $options[] = $value_label;
1976 1807 }
1977 1808
1978 - $options[] = $value_label;
1979 - }
1980 -
1981 - $html_attrs['type'] = 'hidden';
1982 - $html_attrs['class'] = 'frm_autocomplete_value_input';
1983 - $html_attrs['value'] = $args['selected'];
1984 - ?>
1985 - <input type="text" class="frm-custom-search"
1986 - data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>"
1987 - placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1988 - value="<?php echo esc_attr( $autocomplete_value ); ?>" />
1989 - <input <?php self::array_to_html_params( $html_attrs, true ); ?> />
1990 - <?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
1991 1820 }
1992 1821
1993 1822 /**
1994 1823 * Gets dropdown value and label from autodropdown option.
@@ -1997,15 +1826,14 @@
1997 1826 *
1998 1827 * @param array|string $option Autocomplete option.
1999 1828 * @param string $key Array key of the option.
2000 1829 * @param array $args See {@see FrmAppHelper::maybe_autocomplete_options()}.
2001 - *
2002 1830 * @return array
2003 1831 */
2004 1832 private static function get_dropdown_value_and_label_from_option( $option, $key, $args ) {
2005 1833 if ( is_array( $option ) ) {
2006 - $value = $option[ $args['value_key'] ] ?? '';
2007 - $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'] ] : '';
2008 1836 } else {
2009 1837 $value = $key;
2010 1838 $label = $option;
2011 1839 }
@@ -2022,9 +1850,8 @@
2022 1850 self::prep_page_dropdown_params( $page_id, $truncate, $args );
2023 1851
2024 1852 $pages = self::get_post_ids_and_titles( $args['post_type'] );
2025 1853 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
2026 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2027 1854 ?>
2028 1855 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
2029 1856 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
2030 1857 <?php foreach ( $pages as $page ) { ?>
@@ -2033,9 +1860,8 @@
2033 1860 </option>
2034 1861 <?php } ?>
2035 1862 </select>
2036 1863 <?php
2037 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2038 1864 }
2039 1865
2040 1866 /**
2041 1867 * Fill in missing parameters passed to wp_pages_dropdown().
@@ -2041,14 +1867,8 @@
2041 1867 * Fill in missing parameters passed to wp_pages_dropdown().
2042 1868 * This is for reverse compatibility with switching 3 params to 1.
2043 1869 *
2044 1870 * @since 4.03.06
2045 - *
2046 - * @param string $page_id Deprecated.
2047 - * @param bool $truncate Deprecated.
2048 - * @param mixed $args
2049 - *
2050 - * @return void
2051 1871 */
2052 1872 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
2053 1873 if ( ! is_array( $args ) ) {
2054 1874 $args = array(
@@ -2065,12 +1885,8 @@
2065 1885 * Filter to format args for page dropdown or autocomplete
2066 1886 *
2067 1887 * @since 4.03.06
2068 1888 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
2069 - *
2070 - * @param array $args
2071 - *
2072 - * @return array
2073 1889 */
2074 1890 private static function preformat_selection_args( $args ) {
2075 1891 $defaults = array(
2076 1892 'truncate' => false,
@@ -2083,18 +1899,13 @@
2083 1899
2084 1900 return array_merge( $defaults, $args );
2085 1901 }
2086 1902
2087 - /**
2088 - * @param int $post_id
2089 - *
2090 - * @return string
2091 - */
2092 1903 public static function post_edit_link( $post_id ) {
2093 1904 $post = get_post( $post_id );
2094 -
2095 1905 if ( $post ) {
2096 1906 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1907 +
2097 1908 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
2098 1909 }
2099 1910
2100 1911 return '';
@@ -2107,9 +1918,11 @@
2107 1918 *
2108 1919 * @return bool
2109 1920 */
2110 1921 public static function is_full_screen() {
2111 - 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();
2112 1925 }
2113 1926
2114 1927 /**
2115 1928 * Check if user is on the style editor or its alternative URL.
@@ -2119,9 +1932,8 @@
2119 1932 * @since 5.5.3
2120 1933 * @since 6.0 Added the $view parameter. Previously there was only a 'edit' view.
2121 1934 *
2122 1935 * @param string $view Supports 'edit', 'list', and ''. If '', both 'edit' and 'list' will match.
2123 - *
2124 1936 * @return bool
2125 1937 */
2126 1938 public static function is_style_editor_page( $view = '' ) {
2127 1939 if ( ! self::is_admin_page( 'formidable-styles' ) && ! self::is_admin_page( 'formidable-styles2' ) ) {
@@ -2158,9 +1970,8 @@
2158 1970 * @param array|string $capability
2159 1971 * @param string $multiple 'single' and 'multiple'.
2160 1972 */
2161 1973 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
2162 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
2163 1974 ?>
2164 1975 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
2165 1976 <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?>
2166 1977 class="frm_multiselect">
@@ -2166,14 +1977,12 @@
2166 1977 class="frm_multiselect">
2167 1978 <?php self::roles_options( $capability ); ?>
2168 1979 </select>
2169 1980 <?php
2170 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
2171 1981 }
2172 1982
2173 1983 /**
2174 1984 * @since 4.07
2175 - *
2176 1985 * @param array|string $selected
2177 1986 * @param string $current
2178 1987 */
2179 1988 private static function selected( $selected, $current ) {
@@ -2188,9 +1997,8 @@
2188 1997 * @param array|string $capability
2189 1998 */
2190 1999 public static function roles_options( $capability ) {
2191 2000 global $frm_vars;
2192 -
2193 2001 if ( isset( $frm_vars['editable_roles'] ) ) {
2194 2002 $editable_roles = $frm_vars['editable_roles'];
2195 2003 } else {
2196 2004 $editable_roles = get_editable_roles();
@@ -2199,9 +2007,9 @@
2199 2007
2200 2008 foreach ( $editable_roles as $role => $details ) {
2201 2009 $name = translate_user_role( $details['name'] );
2202 2010 ?>
2203 - <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>
2204 2012 <?php
2205 2013 unset( $role, $details );
2206 2014 }
2207 2015 }
@@ -2211,9 +2019,8 @@
2211 2019 *
2212 2020 * @since 5.0 Parameter `$type` supports `pro_only` value.
2213 2021 *
2214 2022 * @param string $type Supports `auto`, `pro`, or `pro_only`.
2215 - *
2216 2023 * @return array
2217 2024 */
2218 2025 public static function frm_capabilities( $type = 'auto' ) {
2219 2026 if ( ! self::pro_is_installed() && ! in_array( $type, array( 'pro', 'pro_only' ), true ) ) {
@@ -2231,8 +2038,14 @@
2231 2038 * @param array<string,string> $pro_cap
2232 2039 */
2233 2040 $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap );
2234 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 +
2235 2048 if ( 'pro_only' === $type ) {
2236 2049 return $pro_cap;
2237 2050 }
2238 2051
@@ -2278,18 +2091,21 @@
2278 2091 if ( $role === 'loggedin' || ! $role ) {
2279 2092 return is_user_logged_in();
2280 2093 }
2281 2094
2282 - if ( (int) $role === 1 ) {
2095 + if ( $role == 1 ) {
2283 2096 $role = 'administrator';
2284 2097 }
2285 2098
2286 - 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 );
2287 2104 }
2288 2105
2289 2106 /**
2290 2107 * @param array|string $needed_role
2291 - *
2292 2108 * @return bool
2293 2109 */
2294 2110 public static function user_has_permission( $needed_role ) {
2295 2111 if ( is_array( $needed_role ) ) {
@@ -2303,20 +2119,18 @@
2303 2119 }
2304 2120
2305 2121 $can = self::current_user_can( $needed_role );
2306 2122
2307 - if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ), true ) ) {
2123 + if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
2308 2124 return $can;
2309 2125 }
2310 2126
2311 2127 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
2312 -
2313 2128 foreach ( $roles as $role ) {
2314 2129 if ( current_user_can( $role ) ) {
2315 2130 return true;
2316 2131 }
2317 -
2318 - if ( $role === $needed_role ) {
2132 + if ( $role == $needed_role ) {
2319 2133 break;
2320 2134 }
2321 2135 }
2322 2136
@@ -2337,9 +2151,8 @@
2337 2151
2338 2152 $user_id = get_current_user_id();
2339 2153 $user = new WP_User( $user_id );
2340 2154 $frm_roles = self::frm_capabilities();
2341 -
2342 2155 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2343 2156 $user->add_cap( $frm_role );
2344 2157 unset( $frm_role, $frm_role_description );
2345 2158 }
@@ -2350,9 +2163,8 @@
2350 2163 *
2351 2164 * @since 2.0.6
2352 2165 *
2353 2166 * @param string $cap
2354 - *
2355 2167 * @return void
2356 2168 */
2357 2169 public static function force_capability( $cap = 'frm_change_settings' ) {
2358 2170 if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
@@ -2357,9 +2169,8 @@
2357 2169 public static function force_capability( $cap = 'frm_change_settings' ) {
2358 2170 if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
2359 2171 $role = get_role( 'administrator' );
2360 2172 $frm_roles = self::frm_capabilities();
2361 -
2362 2173 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
2363 2174 $role->add_cap( $frm_role );
2364 2175 }
2365 2176 }
@@ -2371,22 +2182,17 @@
2371 2182 *
2372 2183 * @since 2.0
2373 2184 *
2374 2185 * @param string $permission
2375 - * @param string $show_message
2376 2186 */
2377 2187 public static function permission_check( $permission, $show_message = 'show' ) {
2378 2188 $permission_error = self::permission_nonce_error( $permission );
2379 -
2380 - if ( $permission_error === false ) {
2381 - return;
2189 + if ( $permission_error !== false ) {
2190 + if ( 'hide' == $show_message ) {
2191 + $permission_error = '';
2192 + }
2193 + wp_die( esc_html( $permission_error ) );
2382 2194 }
2383 -
2384 - if ( 'hide' === $show_message ) {
2385 - $permission_error = '';
2386 - }
2387 -
2388 - wp_die( esc_html( $permission_error ) );
2389 2195 }
2390 2196
2391 2197 /**
2392 2198 * Check user permission and nonce
@@ -2393,27 +2199,24 @@
2393 2199 *
2394 2200 * @since 2.0
2395 2201 *
2396 2202 * @param string $permission
2397 - * @param string $nonce_name
2398 - * @param string $nonce
2399 2203 *
2400 2204 * @return false|string The permission message or false if allowed
2401 2205 */
2402 2206 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
2403 - if ( $permission && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2207 + if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
2404 2208 $frm_settings = self::get_settings();
2209 +
2405 2210 return $frm_settings->admin_permission;
2406 2211 }
2407 2212
2408 2213 $error = false;
2409 -
2410 - if ( ! $nonce_name ) {
2214 + if ( empty( $nonce_name ) ) {
2411 2215 return $error;
2412 2216 }
2413 2217
2414 2218 $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
2415 -
2416 2219 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
2417 2220 $frm_settings = self::get_settings();
2418 2221 $error = $frm_settings->admin_permission;
2419 2222 }
@@ -2420,14 +2223,8 @@
2420 2223
2421 2224 return $error;
2422 2225 }
2423 2226
2424 - /**
2425 - * @param array|string $values
2426 - * @param string $current
2427 - *
2428 - * @return void
2429 - */
2430 2227 public static function checked( $values, $current ) {
2431 2228 if ( self::check_selected( $values, $current ) ) {
2432 2229 echo ' checked="checked"';
2433 2230 }
@@ -2432,34 +2229,25 @@
2432 2229 echo ' checked="checked"';
2433 2230 }
2434 2231 }
2435 2232
2436 - /**
2437 - * @param array|string $values
2438 - * @param string|null $current
2439 - *
2440 - * @return bool
2441 - */
2442 2233 public static function check_selected( $values, $current ) {
2443 - $values = self::recursive_function_map( $values, 'trim' );
2444 - $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 +
2445 2237 $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) );
2446 2238
2447 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons
2448 - return is_array( $values ) ? in_array( $current, $values ) : $values == $current;
2239 + return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
2449 2240 }
2450 2241
2451 - /**
2452 - * @param array|string $value
2453 - * @param callable|string $function
2454 - *
2455 - * @return array|string
2456 - */
2457 2242 public static function recursive_function_map( $value, $function ) {
2458 2243 if ( is_array( $value ) ) {
2459 2244 $original_function = $function;
2460 - $function = count( $value ) ? explode( ', ', FrmDb::prepare_array_values( $value, $function ) ) : array( $function );
2461 -
2245 + if ( count( $value ) ) {
2246 + $function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
2247 + } else {
2248 + $function = array( $function );
2249 + }
2462 2250 if ( ! self::is_assoc( $value ) ) {
2463 2251 $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
2464 2252 } else {
2465 2253 foreach ( $value as $k => $v ) {
@@ -2470,9 +2258,9 @@
2470 2258 }
2471 2259 } else {
2472 2260 $value = self::maybe_update_value_if_null( $value, $function );
2473 2261 $value = call_user_func( $function, $value );
2474 - }//end if
2262 + }
2475 2263
2476 2264 return $value;
2477 2265 }
2478 2266
@@ -2479,27 +2267,20 @@
2479 2267 /**
2480 2268 * Updates value to empty string if it is null and being passed to a string function.
2481 2269 *
2482 2270 * @since 6.8.4
2483 - *
2484 2271 * @param mixed $value
2485 2272 * @param string $function
2486 - *
2487 2273 * @return mixed
2488 2274 */
2489 2275 private static function maybe_update_value_if_null( $value, $function ) {
2490 2276 if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) {
2491 - return '';
2277 + $value = '';
2492 2278 }
2493 2279
2494 2280 return $value;
2495 2281 }
2496 2282
2497 - /**
2498 - * @param array $array
2499 - *
2500 - * @return bool
2501 - */
2502 2283 public static function is_assoc( $array ) {
2503 2284 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
2504 2285 }
2505 2286
@@ -2504,22 +2285,16 @@
2504 2285 }
2505 2286
2506 2287 /**
2507 2288 * Flatten a multi-dimensional array
2508 - *
2509 - * @param array $array
2510 - * @param string $keys
2511 - *
2512 - * @return array
2513 2289 */
2514 2290 public static function array_flatten( $array, $keys = 'keep' ) {
2515 2291 $return = array();
2516 -
2517 2292 foreach ( $array as $key => $value ) {
2518 2293 if ( is_array( $value ) ) {
2519 2294 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
2520 2295 } elseif ( $keys === 'keep' ) {
2521 - $return[ $key ] = $value;
2296 + $return[ $key ] = $value;
2522 2297 } else {
2523 2298 $return[] = $value;
2524 2299 }
2525 2300 }
@@ -2533,9 +2308,8 @@
2533 2308 * @since 6.16.1
2534 2309 *
2535 2310 * @param string $sep
2536 2311 * @param array $array
2537 - *
2538 2312 * @return string
2539 2313 */
2540 2314 public static function safe_implode( $sep, $array ) {
2541 2315 $array = self::array_flatten( $array );
@@ -2544,18 +2318,15 @@
2544 2318
2545 2319 /**
2546 2320 * @param string $text
2547 2321 * @param bool $is_rich_text
2548 - *
2549 2322 * @return string
2550 2323 */
2551 2324 public static function esc_textarea( $text, $is_rich_text = false ) {
2552 2325 $safe_text = str_replace( '&quot;', '"', $text );
2553 -
2554 2326 if ( ! $is_rich_text ) {
2555 2327 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
2556 2328 }
2557 -
2558 2329 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
2559 2330
2560 2331 /**
2561 2332 * @param string $safe_text
@@ -2567,59 +2338,44 @@
2567 2338 /**
2568 2339 * Add auto paragraphs to text areas
2569 2340 *
2570 2341 * @since 2.0
2571 - *
2572 - * @param mixed $content
2573 - *
2574 - * @return mixed
2575 2342 */
2576 2343 public static function use_wpautop( $content ) {
2577 2344 if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) {
2578 - return wpautop( str_replace( '<br>', '<br />', $content ) );
2345 + $content = wpautop( str_replace( '<br>', '<br />', $content ) );
2579 2346 }
2580 2347
2581 2348 return $content;
2582 2349 }
2583 2350
2584 - /**
2585 - * Replace quotes with their HTML entities.
2586 - *
2587 - * @param string $val
2588 - *
2589 - * @return string
2590 - */
2591 2351 public static function replace_quotes( $val ) {
2592 2352 // Replace double quotes.
2593 2353 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
2594 2354
2595 2355 // Replace single quotes.
2596 - 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;
2597 2359 }
2598 2360
2599 2361 /**
2600 - * @param string $handle
2601 - * @param int|string $default
2602 - *
2603 - * @return int|string
2362 + * @param string $handle
2604 2363 */
2605 2364 public static function script_version( $handle, $default = 0 ) {
2606 2365 global $wp_scripts;
2607 -
2608 2366 if ( ! $wp_scripts ) {
2609 2367 return $default;
2610 2368 }
2611 2369
2612 2370 $ver = $default;
2613 -
2614 2371 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
2615 2372 return $ver;
2616 2373 }
2617 2374
2618 2375 $query = $wp_scripts->registered[ $handle ];
2619 -
2620 2376 if ( is_object( $query ) && ! empty( $query->ver ) ) {
2621 - return $query->ver;
2377 + $ver = $query->ver;
2622 2378 }
2623 2379
2624 2380 return $ver;
2625 2381 }
@@ -2628,9 +2384,8 @@
2628 2384 * @since 5.0.13 added $echo param.
2629 2385 *
2630 2386 * @param string $url
2631 2387 * @param bool $echo
2632 - *
2633 2388 * @return string|null
2634 2389 */
2635 2390 public static function js_redirect( $url, $echo = false ) {
2636 2391 $callback = function () use ( $url ) {
@@ -2638,13 +2393,8 @@
2638 2393 };
2639 2394 return self::clip( $callback, $echo );
2640 2395 }
2641 2396
2642 - /**
2643 - * @param int|string $user_id
2644 - *
2645 - * @return int|string
2646 - */
2647 2397 public static function get_user_id_param( $user_id ) {
2648 2398 if ( ! $user_id || is_numeric( $user_id ) ) {
2649 2399 return $user_id;
2650 2400 }
@@ -2649,13 +2399,16 @@
2649 2399 return $user_id;
2650 2400 }
2651 2401
2652 2402 $user_id = sanitize_text_field( $user_id );
2653 -
2654 2403 if ( $user_id === 'current' ) {
2655 2404 $user_id = get_current_user_id();
2656 2405 } else {
2657 - $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 + }
2658 2411
2659 2412 if ( $user ) {
2660 2413 $user_id = $user->ID;
2661 2414 }
@@ -2667,9 +2420,8 @@
2667 2420
2668 2421 /**
2669 2422 * @param string $filename
2670 2423 * @param array $atts
2671 - *
2672 2424 * @return false|string
2673 2425 */
2674 2426 public static function get_file_contents( $filename, $atts = array() ) {
2675 2427 if ( ! is_file( $filename ) ) {
@@ -2678,9 +2430,12 @@
2678 2430
2679 2431 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
2680 2432 ob_start();
2681 2433 include $filename;
2682 - return ob_get_clean();
2434 + $contents = ob_get_contents();
2435 + ob_end_clean();
2436 +
2437 + return $contents;
2683 2438 }
2684 2439
2685 2440 /**
2686 2441 * @param string $name
@@ -2690,9 +2445,8 @@
2690 2445 * @param int $num_chars
2691 2446 */
2692 2447 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
2693 2448 $key = '';
2694 -
2695 2449 if ( $name ) {
2696 2450 $key = sanitize_key( $name );
2697 2451 $key = self::maybe_clear_long_key( $key, $column );
2698 2452 }
@@ -2712,31 +2466,31 @@
2712 2466 $column
2713 2467 );
2714 2468
2715 2469 // Create a unique field id if it has already been used.
2716 - if ( ! in_array( $key, $similar_keys, true ) ) {
2717 - return $key;
2718 - }
2470 + if ( in_array( $key, $similar_keys, true ) ) {
2471 + $key = self::maybe_truncate_key_before_appending( $column, $key );
2719 2472
2720 - $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 );
2721 2482
2722 - /**
2723 - * Allow for a custom separator between the attempted key and the generated suffix.
2724 - *
2725 - * @since 5.2.03
2726 - *
2727 - * @param string $separator. Default empty.
2728 - * @param string $key the key without the added suffix.
2729 - */
2730 - $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 ) );
2731 2488
2732 - $suffix = 2;
2733 - do {
2734 - $key_check = $key . $separator . $suffix;
2735 - ++$suffix;
2736 - } while ( in_array( $key_check, $similar_keys, true ) );
2489 + $key = $key_check;
2490 + }//end if
2737 2491
2738 - return $key_check;
2492 + return $key;
2739 2493 }
2740 2494
2741 2495 /**
2742 2496 * Avoid trying to append to a really long key,
@@ -2743,26 +2497,20 @@
2743 2497 * The database limit is 100 for form and field keys so we want to avoid getting too close.
2744 2498 *
2745 2499 * @param string $column
2746 2500 * @param string $key
2747 - *
2748 2501 * @return string
2749 2502 */
2750 2503 private static function maybe_truncate_key_before_appending( $column, $key ) {
2751 - if ( ! in_array( $column, array( 'form_key', 'field_key' ), true ) ) {
2752 - return $key;
2753 - }
2754 -
2755 - $max_key_length_before_truncating = 60;
2756 -
2757 - if ( strlen( $key ) > $max_key_length_before_truncating ) {
2758 - $key = substr( $key, 0, $max_key_length_before_truncating );
2759 -
2760 - if ( is_numeric( $key ) ) {
2761 - $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 + }
2762 2511 }
2763 2512 }
2764 -
2765 2513 return $key;
2766 2514 }
2767 2515
2768 2516 /**
@@ -2769,14 +2517,13 @@
2769 2517 * Possibly reset a key to avoid conflicts with column size limits.
2770 2518 *
2771 2519 * @param string $key
2772 2520 * @param string $column
2773 - *
2774 2521 * @return string either the original key value, or an empty string if the key was too long.
2775 2522 */
2776 2523 private static function maybe_clear_long_key( $key, $column ) {
2777 2524 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
2778 - return '';
2525 + $key = '';
2779 2526 }
2780 2527 return $key;
2781 2528 }
2782 2529
@@ -2783,22 +2530,20 @@
2783 2530 /**
2784 2531 * @since 6.21 This is changed from `private` to `public`.
2785 2532 *
2786 2533 * @param int $num_chars
2787 - *
2788 2534 * @return string
2789 2535 */
2790 2536 public static function generate_new_key( $num_chars ) {
2791 - $max_slug_value = 36 ** $num_chars;
2537 + $max_slug_value = pow( 36, $num_chars );
2792 2538
2793 2539 // We want to have at least 2 characters in the slug.
2794 2540 $min_slug_value = 37;
2795 - 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 );
2796 2542 }
2797 2543
2798 2544 /**
2799 2545 * @param string $key
2800 - *
2801 2546 * @return string
2802 2547 */
2803 2548 private static function prevent_numeric_and_reserved_keys( $key ) {
2804 2549 if ( is_numeric( $key ) ) {
@@ -2812,14 +2557,12 @@
2812 2557 'editlink',
2813 2558 'siteurl',
2814 2559 'evenodd',
2815 2560 );
2816 -
2817 2561 if ( in_array( $key, $not_allowed, true ) ) {
2818 2562 $key .= 'a';
2819 2563 }
2820 2564 }
2821 -
2822 2565 return $key;
2823 2566 }
2824 2567
2825 2568 /**
@@ -2838,9 +2581,9 @@
2838 2581 if ( ! $record ) {
2839 2582 return false;
2840 2583 }
2841 2584
2842 - if ( ! $post_values ) {
2585 + if ( empty( $post_values ) ) {
2843 2586 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
2844 2587 }
2845 2588
2846 2589 $values = array(
@@ -2848,9 +2591,9 @@
2848 2591 'fields' => array(),
2849 2592 );
2850 2593
2851 2594 foreach ( array( 'name', 'description' ) as $var ) {
2852 - $default_val = $record->{$var} ?? '';
2595 + $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
2853 2596 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
2854 2597 unset( $var, $default_val );
2855 2598 }
2856 2599
@@ -2868,67 +2611,46 @@
2868 2611
2869 2612 return $values;
2870 2613 }
2871 2614
2872 - /**
2873 - * @param array|string $fields
2874 - * @param object $record
2875 - * @param array $values
2876 - * @param array $args
2877 - *
2878 - * @return void
2879 - */
2880 2615 private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
2881 - if ( ! $fields ) {
2882 - return;
2883 - }
2884 -
2885 - foreach ( (array) $fields as $field ) {
2886 - if ( ! self::is_admin_page() ) {
2887 - // Don't prep default values on the form settings page.
2888 - $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 );
2889 2624 }
2890 -
2891 - $args['parent_form_id'] = $args['parent_form_id'] ?? $field->form_id;
2892 - self::fill_field_defaults( $field, $record, $values, $args );
2893 2625 }
2894 2626 }
2895 2627
2896 - /**
2897 - * @param object $field
2898 - * @param object $record
2899 - * @param array $values
2900 - * @param array $args
2901 - *
2902 - * @return void
2903 - */
2904 2628 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
2905 2629 $post_values = $args['post_values'];
2906 2630
2907 2631 if ( $args['default'] ) {
2908 2632 $meta_value = $field->default_value;
2909 - } 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'] ) {
2910 2634 if ( ! isset( $field->field_options['custom_field'] ) ) {
2911 2635 $field->field_options['custom_field'] = '';
2912 2636 }
2913 -
2914 - $meta_value = FrmProEntryMetaHelper::get_post_value(
2915 - $record->post_id,
2916 - $field->field_options['post_field'],
2917 - $field->field_options['custom_field'],
2918 - array(
2919 - 'truncate' => false,
2920 - 'type' => $field->type,
2921 - 'form_id' => $field->form_id,
2922 - 'field' => $field,
2923 - )
2924 - );
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 + );
2925 2648 } else {
2926 2649 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
2927 2650 }//end if
2928 2651
2929 - $field_type = $post_values['field_options'][ 'type_' . $field->id ] ?? $field->type;
2930 -
2652 + $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
2931 2653 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
2932 2654 $new_value = $post_values['item_meta'][ $field->id ];
2933 2655 self::unserialize_or_decode( $new_value );
2934 2656 } else {
@@ -2943,9 +2665,9 @@
2943 2665 $args['field_type'] = $field_type;
2944 2666
2945 2667 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
2946 2668
2947 - if ( empty( $field_array['unique'] ) ) {
2669 + if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
2948 2670 $field_array['unique_msg'] = '';
2949 2671 }
2950 2672
2951 2673 $field_array = array_merge( (array) $field->field_options, $field_array );
@@ -3012,21 +2734,15 @@
3012 2734 }
3013 2735
3014 2736 /**
3015 2737 * Set to POST value or default
3016 - *
3017 - * @param array $post_values
3018 - * @param array $values
3019 - *
3020 - * @return void
3021 2738 */
3022 2739 private static function fill_form_defaults( $post_values, array &$values ) {
3023 2740 $form_defaults = FrmFormsHelper::get_default_opts();
3024 2741
3025 2742 foreach ( $form_defaults as $opt => $default ) {
3026 - // phpcs:ignore Universal.Operators.StrictComparisons
3027 2743 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
3028 - $values[ $opt ] = $post_values['options'][ $opt ] ?? $default;
2744 + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default;
3029 2745 }
3030 2746
3031 2747 unset( $opt, $default );
3032 2748 }
@@ -3036,9 +2752,9 @@
3036 2752 }
3037 2753
3038 2754 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
3039 2755 if ( ! isset( $values[ $h . '_html' ] ) ) {
3040 - $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 ) );
3041 2757 }
3042 2758 unset( $h );
3043 2759 }
3044 2760 }
@@ -3050,14 +2766,16 @@
3050 2766 *
3051 2767 * @return bool|int
3052 2768 */
3053 2769 public static function custom_style_value( $post_values ) {
3054 - if ( $post_values && isset( $post_values['options']['custom_style'] ) ) {
3055 - 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' );
3056 2775 }
3057 2776
3058 - $frm_settings = self::get_settings();
3059 - return $frm_settings->load_style !== 'none';
2777 + return $custom_style;
3060 2778 }
3061 2779
3062 2780 /**
3063 2781 * @param mixed $original_string
@@ -3063,9 +2781,8 @@
3063 2781 * @param mixed $original_string
3064 2782 * @param int|string $length
3065 2783 * @param int $minword
3066 2784 * @param string $continue
3067 - *
3068 2785 * @return string
3069 2786 */
3070 2787 public static function truncate( $original_string, $length, $minword = 3, $continue = '...' ) {
3071 2788 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
@@ -3071,24 +2788,24 @@
3071 2788 if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) {
3072 2789 return '';
3073 2790 }
3074 2791
3075 - $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 ) );
3076 2795
3077 - if ( $length === 0 ) {
2796 + if ( $length == 0 ) {
3078 2797 return '';
3079 2798 }
3080 2799
3081 - $str = wp_strip_all_tags( (string) $original_string );
3082 - $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
3083 -
3084 2800 if ( $length <= 10 ) {
3085 2801 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
3086 2802 return $sub . ( $length < $original_len ? $continue : '' );
3087 2803 }
3088 2804
3089 - $sub = '';
3090 - $len = 0;
2805 + $sub = '';
2806 + $len = 0;
2807 +
3091 2808 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
3092 2809
3093 2810 if ( ! is_array( $words ) ) {
3094 2811 return $original_string;
@@ -3094,11 +2811,10 @@
3094 2811 return $original_string;
3095 2812 }
3096 2813
3097 2814 foreach ( $words as $word ) {
3098 - $part = ( $sub !== '' ? ' ' : '' ) . $word;
2815 + $part = ( $sub != '' ? ' ' : '' ) . $word;
3099 2816 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
3100 -
3101 2817 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
3102 2818 break;
3103 2819 }
3104 2820
@@ -3123,9 +2839,8 @@
3123 2839 * @since 6.5.4
3124 2840 *
3125 2841 * @param string $sub Current substring.
3126 2842 * @param int $length The length limit.
3127 - *
3128 2843 * @return string
3129 2844 */
3130 2845 private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) {
3131 2846 if ( strlen( $sub ) < $length + 50 ) {
@@ -3133,9 +2848,8 @@
3133 2848 return $sub;
3134 2849 }
3135 2850
3136 2851 $first_space = strpos( $sub, ' ', $length );
3137 -
3138 2852 if ( false !== $first_space ) {
3139 2853 // Ignore anything with spaces.
3140 2854 return $sub;
3141 2855 }
@@ -3142,18 +2856,11 @@
3142 2856
3143 2857 return substr( $sub, 0, $length + 10 );
3144 2858 }
3145 2859
3146 - /**
3147 - * @param array $function_names
3148 - * @param array $args
3149 - *
3150 - * @return mixed
3151 - */
3152 2860 public static function mb_function( $function_names, $args ) {
3153 2861 $mb_function_name = $function_names[0];
3154 2862 $function_name = $function_names[1];
3155 -
3156 2863 if ( function_exists( $mb_function_name ) ) {
3157 2864 $function_name = $mb_function_name;
3158 2865 }
3159 2866
@@ -3159,21 +2866,14 @@
3159 2866
3160 2867 return call_user_func_array( $function_name, $args );
3161 2868 }
3162 2869
3163 - /**
3164 - * @param string $date
3165 - * @param string $date_format
3166 - * @param string $time_format
3167 - *
3168 - * @return string
3169 - */
3170 2870 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
3171 - if ( ! $date ) {
2871 + if ( empty( $date ) ) {
3172 2872 return $date;
3173 2873 }
3174 2874
3175 - if ( ! $date_format ) {
2875 + if ( empty( $date_format ) ) {
3176 2876 $date_format = get_option( 'date_format' );
3177 2877 }
3178 2878
3179 2879 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
@@ -3181,10 +2881,10 @@
3181 2881 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
3182 2882 }
3183 2883
3184 2884 $formatted = self::get_localized_date( $date_format, $date );
3185 - $do_time = gmdate( 'H:i:s', strtotime( $date ) ) !== '00:00:00';
3186 2885
2886 + $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
3187 2887 if ( $do_time ) {
3188 2888 $formatted .= self::add_time_to_date( $time_format, $date );
3189 2889 }
3190 2890
@@ -3193,35 +2893,30 @@
3193 2893
3194 2894 /**
3195 2895 * @param string $time_format
3196 2896 * @param string $date
3197 - *
3198 2897 * @return string
3199 2898 */
3200 2899 private static function add_time_to_date( $time_format, $date ) {
3201 - if ( ! $time_format ) {
2900 + if ( empty( $time_format ) ) {
3202 2901 $time_format = get_option( 'time_format' );
3203 2902 }
3204 2903
3205 2904 $trimmed_format = trim( $time_format );
3206 -
3207 - if ( $time_format && $trimmed_format ) {
3208 - 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 );
3209 2908 }
3210 2909
3211 - return '';
2910 + return $time;
3212 2911 }
3213 2912
3214 2913 /**
3215 2914 * @since 2.0.8
3216 - *
3217 - * @param string $date_format
3218 - * @param string $date
3219 - *
3220 - * @return string
3221 2915 */
3222 2916 public static function get_localized_date( $date_format, $date ) {
3223 2917 $date = get_date_from_gmt( $date );
2918 +
3224 2919 return date_i18n( $date_format, strtotime( $date ) );
3225 2920 }
3226 2921
3227 2922 /**
@@ -3226,16 +2921,19 @@
3226 2921
3227 2922 /**
3228 2923 * Gets the time ago in words.
3229 2924 *
3230 - * @param int $from In seconds.
3231 - * @param int|string $to In seconds.
3232 - * @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.
3233 2927 *
3234 - * @return string Time ago.
2928 + * @return string $time_ago
3235 2929 */
3236 2930 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
3237 - $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 + }
3238 2936 $ago = new DateTime( '@' . $from );
3239 2937
3240 2938 // Get the time difference
3241 2939 $diff_object = $now->diff( $ago );
@@ -3249,9 +2947,8 @@
3249 2947
3250 2948 if ( ! is_numeric( $levels ) ) {
3251 2949 // Show time in specified unit.
3252 2950 $levels = self::get_unit( $levels );
3253 -
3254 2951 if ( isset( $time_strings[ $levels ] ) ) {
3255 2952 $diff = array(
3256 2953 $levels => self::time_format( $levels, $diff ),
3257 2954 );
@@ -3258,14 +2955,13 @@
3258 2955 $time_strings = array(
3259 2956 $levels => $time_strings[ $levels ],
3260 2957 );
3261 2958 }
3262 -
3263 2959 $levels = 1;
3264 2960 }
3265 2961
3266 2962 foreach ( $time_strings as $k => $v ) {
3267 - if ( ! empty( $diff[ $k ] ) ) {
2963 + if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
3268 2964 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
3269 2965 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
3270 2966 // Account for 0.
3271 2967 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
@@ -3273,21 +2969,17 @@
3273 2969 unset( $time_strings[ $k ] );
3274 2970 }
3275 2971 }
3276 2972
3277 - $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
3278 - $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 );
3279 2976
3280 - return implode( ' ', $time_strings );
2977 + return $time_ago_string;
3281 2978 }
3282 2979
3283 2980 /**
3284 2981 * @since 4.05.01
3285 - *
3286 - * @param string $unit
3287 - * @param array $diff
3288 - *
3289 - * @return int
3290 2982 */
3291 2983 private static function time_format( $unit, $diff ) {
3292 2984 $return = array(
3293 2985 'y' => 'y',
@@ -3292,14 +2984,14 @@
3292 2984 $return = array(
3293 2985 'y' => 'y',
3294 2986 'd' => 'days',
3295 2987 );
3296 -
3297 2988 if ( isset( $return[ $unit ] ) ) {
3298 2989 return $diff[ $return[ $unit ] ];
3299 2990 }
3300 2991
3301 2992 $total = $diff['days'] * self::convert_time( 'd', $unit );
2993 +
3302 2994 $times = array( 'h', 'i', 's' );
3303 2995
3304 2996 foreach ( $times as $time ) {
3305 2997 if ( ! isset( $diff[ $time ] ) ) {
@@ -3313,13 +3005,8 @@
3313 3005 }
3314 3006
3315 3007 /**
3316 3008 * @since 4.05.01
3317 - *
3318 - * @param string $from
3319 - * @param string $to
3320 - *
3321 - * @return int
3322 3009 */
3323 3010 private static function convert_time( $from, $to ) {
3324 3011 $convert = array(
3325 3012 's' => 1,
@@ -3335,26 +3022,20 @@
3335 3022 }
3336 3023
3337 3024 /**
3338 3025 * @since 4.05.01
3339 - *
3340 - * @param string $unit
3341 - *
3342 - * @return int|string
3343 3026 */
3344 3027 private static function get_unit( $unit ) {
3345 3028 $units = self::get_time_strings();
3346 -
3347 3029 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
3348 3030 return $unit;
3349 3031 }
3350 3032
3351 3033 foreach ( $units as $u => $strings ) {
3352 - if ( in_array( $unit, $strings, true ) ) {
3034 + if ( in_array( $unit, $strings ) ) {
3353 3035 return $u;
3354 3036 }
3355 3037 }
3356 -
3357 3038 return 1;
3358 3039 }
3359 3040
3360 3041 /**
@@ -3361,9 +3042,8 @@
3361 3042 * Get the translatable time strings. The untranslated version is a failsafe
3362 3043 * in case languages are changing for the unit set in the shortcode.
3363 3044 *
3364 3045 * @since 2.0.20
3365 - *
3366 3046 * @return array
3367 3047 */
3368 3048 private static function get_time_strings() {
3369 3049 return array(
@@ -3410,13 +3090,12 @@
3410 3090 /**
3411 3091 * @param int $r_count
3412 3092 * @param int $current_p
3413 3093 * @param int $p_size
3414 - *
3415 3094 * @return int
3416 3095 */
3417 3096 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
3418 - 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 );
3419 3098 }
3420 3099
3421 3100 /**
3422 3101 * @param int $r_count
@@ -3421,13 +3100,11 @@
3421 3100 /**
3422 3101 * @param int $r_count
3423 3102 * @param int $current_p
3424 3103 * @param int $p_size
3425 - *
3426 3104 * @return int
3427 3105 */
3428 3106 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
3429 - // phpcs:ignore Universal.Operators.StrictComparisons
3430 3107 if ( $current_p == 1 ) {
3431 3108 return 1;
3432 3109 }
3433 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
@@ -3433,22 +3110,17 @@
3433 3110 return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1;
3434 3111 }
3435 3112
3436 3113 /**
3437 - * @param array $json_vars
3438 - *
3439 3114 * @return array
3440 3115 */
3441 3116 public static function json_to_array( $json_vars ) {
3442 3117 $vars = array();
3443 -
3444 3118 foreach ( $json_vars as $jv ) {
3445 3119 $jv_name = explode( '[', $jv['name'] );
3446 3120 $last = count( $jv_name ) - 1;
3447 -
3448 3121 foreach ( $jv_name as $p => $n ) {
3449 3122 $name = trim( $n, ']' );
3450 -
3451 3123 if ( ! isset( $l1 ) ) {
3452 3124 $l1 = $name;
3453 3125 }
3454 3126
@@ -3459,9 +3131,9 @@
3459 3131 if ( ! isset( $l3 ) ) {
3460 3132 $l3 = $name;
3461 3133 }
3462 3134
3463 - $this_val = $p === $last ? $jv['value'] : array();
3135 + $this_val = $p == $last ? $jv['value'] : array();
3464 3136
3465 3137 switch ( $p ) {
3466 3138 case 0:
3467 3139 $l1 = $name;
@@ -3494,15 +3166,10 @@
3494 3166
3495 3167 /**
3496 3168 * @param string $name
3497 3169 * @param string $l1
3498 - * @param mixed $val
3499 - * @param array $vars
3500 - *
3501 - * @return void
3502 3170 */
3503 3171 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
3504 - // phpcs:ignore Universal.Operators.StrictComparisons
3505 3172 if ( $name == '' ) {
3506 3173 $vars[] = $val;
3507 3174 } elseif ( ! isset( $vars[ $l1 ] ) ) {
3508 3175 $vars[ $l1 ] = $val;
@@ -3508,26 +3175,19 @@
3508 3175 $vars[ $l1 ] = $val;
3509 3176 }
3510 3177 }
3511 3178
3512 - /**
3513 - * @param string $name
3514 - * @param string $class
3515 - * @param string $form_name
3516 - *
3517 - * @return void
3518 - */
3519 3179 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
3520 3180 $tooltips = array(
3521 3181 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
3522 - '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' ),
3523 3183 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3524 3184 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
3525 - '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' ),
3526 3186 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
3527 3187 /* translators: %1$s: Form name, %2$s: Date */
3528 - '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
3529 - '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' ),
3530 3190 );
3531 3191
3532 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3533 3193 return;
@@ -3532,9 +3192,9 @@
3532 3192 if ( ! isset( $tooltips[ $name ] ) ) {
3533 3193 return;
3534 3194 }
3535 3195
3536 - if ( 'open' === $class ) {
3196 + if ( 'open' == $class ) {
3537 3197 echo ' frm_help"';
3538 3198 } else {
3539 3199 echo ' class="frm_help"';
3540 3200 }
@@ -3540,9 +3200,9 @@
3540 3200 }
3541 3201
3542 3202 echo ' title="' . esc_attr( $tooltips[ $name ] );
3543 3203
3544 - if ( 'open' !== $class ) {
3204 + if ( 'open' != $class ) {
3545 3205 echo '"';
3546 3206 }
3547 3207 }
3548 3208
@@ -3547,28 +3207,20 @@
3547 3207 }
3548 3208
3549 3209 /**
3550 3210 * Add the current_page class to that page in the form nav
3551 - *
3552 - * @param int|string $page
3553 - * @param int|string $current_page
3554 - * @param array $action
3555 - *
3556 - * @return void
3557 3211 */
3558 3212 public static function select_current_page( $page, $current_page, $action = array() ) {
3559 - // phpcs:ignore Universal.Operators.StrictComparisons
3560 3213 if ( $current_page != $page ) {
3561 3214 return;
3562 3215 }
3563 3216
3564 3217 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
3565 -
3566 3218 if ( 'lite-reports' === $frm_action ) {
3567 3219 $frm_action = 'reports';
3568 3220 }
3569 3221
3570 - if ( ! $action || ( $frm_action && in_array( $frm_action, $action, true ) ) ) {
3222 + if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
3571 3223 echo ' class="current_page"';
3572 3224 }
3573 3225 }
3574 3226
@@ -3598,19 +3250,14 @@
3598 3250
3599 3251 // Add extra slashes for \r\n since WP strips them.
3600 3252 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
3601 3253
3602 - // Allow for &quot
3603 - return str_replace( '&quot;', '\\"', $post_content );
3254 + // allow for &quot
3255 + $post_content = str_replace( '&quot;', '\\"', $post_content );
3256 +
3257 + return $post_content;
3604 3258 }
3605 3259
3606 - /**
3607 - * @param array|string $val
3608 - * @param int|string $key
3609 - * @param array $post_content
3610 - *
3611 - * @return void
3612 - */
3613 3260 private static function prepare_action_slashes( $val, $key, &$post_content ) {
3614 3261 if ( ! isset( $post_content[ $key ] ) || is_numeric( $val ) ) {
3615 3262 return;
3616 3263 }
@@ -3619,17 +3266,15 @@
3619 3266 foreach ( $val as $k1 => $v1 ) {
3620 3267 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
3621 3268 unset( $k1, $v1 );
3622 3269 }
3270 + } else {
3271 + // Strip all slashes so everything is the same, no matter where the value is coming from
3272 + $val = stripslashes( $val );
3623 3273
3624 - return;
3274 + // Add backslashes before double quotes and forward slashes only
3275 + $post_content[ $key ] = addcslashes( $val, '"\\/' );
3625 3276 }
3626 -
3627 - // Strip all slashes so everything is the same, no matter where the value is coming from
3628 - $val = stripslashes( $val );
3629 -
3630 - // Add backslashes before double quotes and forward slashes only
3631 - $post_content[ $key ] = addcslashes( $val, '"\\/' );
3632 3277 }
3633 3278
3634 3279 /**
3635 3280 * Check for either json or serialized data. This is temporary while transitioning
@@ -3637,9 +3282,8 @@
3637 3282 *
3638 3283 * @since 4.02.03
3639 3284 *
3640 3285 * @param array|string $value
3641 - *
3642 3286 * @return void
3643 3287 */
3644 3288 public static function unserialize_or_decode( &$value ) {
3645 3289 if ( is_array( $value ) ) {
@@ -3645,9 +3289,13 @@
3645 3289 if ( is_array( $value ) ) {
3646 3290 return;
3647 3291 }
3648 3292
3649 - $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 + }
3650 3298 }
3651 3299
3652 3300 /**
3653 3301 * Safely unserialize an array if necessary.
@@ -3655,9 +3303,8 @@
3655 3303 *
3656 3304 * @since 6.2
3657 3305 *
3658 3306 * @param mixed $value
3659 - *
3660 3307 * @return mixed
3661 3308 */
3662 3309 public static function maybe_unserialize_array( $value ) {
3663 3310 if ( ! is_string( $value ) ) {
@@ -3664,15 +3311,18 @@
3664 3311 return $value;
3665 3312 }
3666 3313
3667 3314 // Since we only expect an array, skip anything that doesn't start with a:.
3668 - if ( ! is_serialized( $value ) || ! str_starts_with( $value, 'a:' ) ) {
3315 + if ( ! is_serialized( $value ) || 'a:' !== substr( $value, 0, 2 ) ) {
3669 3316 return $value;
3670 3317 }
3671 3318
3672 3319 $parsed = FrmSerializedStringParserHelper::get()->parse( $value );
3320 + if ( is_array( $parsed ) ) {
3321 + $value = $parsed;
3322 + }
3673 3323
3674 - return is_array( $parsed ) ? $parsed : $value;
3324 + return $value;
3675 3325 }
3676 3326
3677 3327 /**
3678 3328 * Decode a JSON string.
@@ -3677,12 +3327,11 @@
3677 3327 /**
3678 3328 * Decode a JSON string.
3679 3329 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
3680 3330 *
3681 - * @param array|string|null $string
3682 - * @param bool $single_to_array
3683 - *
3684 - * @return array|string|null
3331 + * @param mixed $string
3332 + * @param bool $single_to_array
3333 + * @return mixed
3685 3334 */
3686 3335 public static function maybe_json_decode( $string, $single_to_array = true ) {
3687 3336 if ( is_array( $string ) || is_null( $string ) ) {
3688 3337 return $string;
@@ -3687,19 +3336,20 @@
3687 3336 if ( is_array( $string ) || is_null( $string ) ) {
3688 3337 return $string;
3689 3338 }
3690 3339
3691 - $new_string = json_decode( $string, true );
3692 - $single_value = false;
3693 -
3694 - if ( ! $single_to_array ) {
3695 - $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 + }
3696 3350 }
3697 3351
3698 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
3699 - return $new_string;
3700 - }
3701 -
3702 3352 return $string;
3703 3353 }
3704 3354
3705 3355 /**
@@ -3705,9 +3355,8 @@
3705 3355 /**
3706 3356 * @since 6.2.3
3707 3357 *
3708 3358 * @param string $value
3709 - *
3710 3359 * @return string
3711 3360 */
3712 3361 public static function maybe_utf8_encode( $value ) {
3713 3362 $from_format = 'ISO-8859-1';
@@ -3716,15 +3365,13 @@
3716 3365 if ( function_exists( 'mb_check_encoding' ) && function_exists( 'mb_convert_encoding' ) ) {
3717 3366 if ( mb_check_encoding( $value, $from_format ) ) {
3718 3367 return mb_convert_encoding( $value, $to_format, $from_format );
3719 3368 }
3720 -
3721 3369 return $value;
3722 3370 }
3723 3371
3724 3372 if ( function_exists( 'iconv' ) ) {
3725 3373 $converted = iconv( $from_format, $to_format, $value );
3726 -
3727 3374 // Value is false if $value is not ISO-8859-1.
3728 3375 if ( false !== $converted ) {
3729 3376 return $converted;
3730 3377 }
@@ -3736,12 +3383,8 @@
3736 3383 /**
3737 3384 * Reformat the json serialized array in name => value array.
3738 3385 *
3739 3386 * @since 4.02.03
3740 - *
3741 - * @param array $form
3742 - *
3743 - * @return void
3744 3387 */
3745 3388 public static function format_form_data( &$form ) {
3746 3389 $formatted = array();
3747 3390
@@ -3748,21 +3391,18 @@
3748 3391 foreach ( $form as $input ) {
3749 3392 if ( ! isset( $input['name'] ) ) {
3750 3393 continue;
3751 3394 }
3752 -
3753 3395 $key = $input['name'];
3754 -
3755 - 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 {
3756 3403 $formatted[ $key ] = $input['value'];
3757 - continue;
3758 3404 }
3759 -
3760 - if ( is_array( $formatted[ $key ] ) ) {
3761 - $formatted[ $key ][] = $input['value'];
3762 - } else {
3763 - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
3764 - }
3765 3405 }
3766 3406
3767 3407 parse_str( http_build_query( $formatted ), $form );
3768 3408 }
@@ -3770,13 +3410,15 @@
3770 3410 /**
3771 3411 * @since 4.02.03
3772 3412 *
3773 3413 * @param array|string $value
3774 - *
3775 3414 * @return string
3776 3415 */
3777 3416 public static function maybe_json_encode( $value ) {
3778 - return is_array( $value ) ? wp_json_encode( $value ) : $value;
3417 + if ( is_array( $value ) ) {
3418 + $value = wp_json_encode( $value );
3419 + }
3420 + return $value;
3779 3421 }
3780 3422
3781 3423 /**
3782 3424 * Echo The javascript to open and highlight the Formidable menu
@@ -3783,19 +3425,18 @@
3783 3425 *
3784 3426 * @since 1.07.10
3785 3427 *
3786 3428 * @param string $post_type The name of the post type that may need to be highlighted.
3787 - *
3788 3429 * @return void
3789 3430 */
3790 3431 public static function maybe_highlight_menu( $post_type ) {
3791 3432 global $post;
3792 3433
3793 - if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] !== $post_type ) {
3434 + if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
3794 3435 return;
3795 3436 }
3796 3437
3797 - if ( is_object( $post ) && $post->post_type !== $post_type ) {
3438 + if ( is_object( $post ) && $post->post_type != $post_type ) {
3798 3439 return;
3799 3440 }
3800 3441
3801 3442 self::load_admin_wide_js();
@@ -3807,9 +3448,8 @@
3807 3448 *
3808 3449 * @since 2.0
3809 3450 *
3810 3451 * @param bool $load
3811 - *
3812 3452 * @return void
3813 3453 */
3814 3454 public static function load_admin_wide_js( $load = true ) {
3815 3455 $version = self::plugin_version();
@@ -3820,9 +3460,9 @@
3820 3460 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
3821 3461 'url' => self::plugin_url(),
3822 3462 'app_url' => 'https://formidableforms.com/',
3823 3463 'applicationsUrl' => admin_url( 'admin.php?page=formidable-applications' ),
3824 - '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' ),
3825 3465 'loading' => __( 'Loading&hellip;', 'formidable' ),
3826 3466 'nonce' => wp_create_nonce( 'frm_ajax' ),
3827 3467 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ),
3828 3468 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(),
@@ -3835,9 +3475,8 @@
3835 3475 }
3836 3476
3837 3477 /**
3838 3478 * @since 2.0.9
3839 - *
3840 3479 * @return void
3841 3480 */
3842 3481 public static function load_font_style() {
3843 3482 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
@@ -3844,9 +3483,8 @@
3844 3483 }
3845 3484
3846 3485 /**
3847 3486 * @param string $location
3848 - *
3849 3487 * @return void
3850 3488 */
3851 3489 public static function localize_script( $location ) {
3852 3490 global $wp_scripts, $wp_version;
@@ -3869,9 +3507,8 @@
3869 3507 'include_resend_email' => false,
3870 3508 );
3871 3509
3872 3510 $data = $wp_scripts->get_data( 'formidable', 'data' );
3873 -
3874 3511 if ( ! $data ) {
3875 3512 wp_localize_script( 'formidable', 'frm_js', $script_strings );
3876 3513 }
3877 3514
@@ -3878,9 +3515,9 @@
3878 3515 if ( $location === 'admin' ) {
3879 3516 $admin_script_strings = array(
3880 3517 'desc' => __( '(Click to add description)', 'formidable' ),
3881 3518 'blank' => __( '(Blank)', 'formidable' ),
3882 - 'no_label' => self::get_no_label_text(),
3519 + 'no_label' => __( '(no label)', 'formidable' ),
3883 3520 'ok' => __( 'OK', 'formidable' ),
3884 3521 'cancel' => __( 'Cancel', 'formidable' ),
3885 3522 'default_label' => __( 'Default', 'formidable' ),
3886 3523 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
@@ -3888,9 +3525,9 @@
3888 3525 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
3889 3526 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
3890 3527 'confirm' => __( 'Are you sure?', 'formidable' ),
3891 3528 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
3892 - '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' ),
3893 3530 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
3894 3531 'default_unique' => FrmFieldsHelper::default_unique_msg(),
3895 3532 'default_conf' => __( 'The entered values do not match', 'formidable' ),
3896 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
@@ -3896,9 +3533,9 @@
3896 3533 'enter_email' => __( 'Enter Email', 'formidable' ),
3897 3534 'confirm_email' => __( 'Confirm Email', 'formidable' ),
3898 3535 'conditional_text' => __( 'Conditional content here', 'formidable' ),
3899 3536 'new_option' => __( 'New Option', 'formidable' ),
3900 - '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' ),
3901 3538 'enter_password' => __( 'Enter Password', 'formidable' ),
3902 3539 'confirm_password' => __( 'Confirm Password', 'formidable' ),
3903 3540 'import_complete' => __( 'Import Complete', 'formidable' ),
3904 3541 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
@@ -3914,11 +3551,11 @@
3914 3551 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ),
3915 3552 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ),
3916 3553 'unsafe_params' => FrmFormsHelper::reserved_words(),
3917 3554 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
3918 - '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' ), '****' ),
3919 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. */
3920 - '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' ), '****' ),
3921 3558 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
3922 3559 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
3923 3560 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
3924 3561 'install' => __( 'Install', 'formidable' ),
@@ -3939,9 +3576,9 @@
3939 3576 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ),
3940 3577 'noTitleText' => FrmFormsHelper::get_no_title_text(),
3941 3578
3942 3579 // In older versions this event listener causes the section to immediately close again
3943 - // 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+.
3944 3581 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ),
3945 3582 );
3946 3583 /**
3947 3584 * @param array $admin_script_strings
@@ -3948,9 +3585,8 @@
3948 3585 */
3949 3586 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
3950 3587
3951 3588 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
3952 -
3953 3589 if ( ! $data ) {
3954 3590 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
3955 3591 }
3956 3592 }//end if
@@ -3956,19 +3592,8 @@
3956 3592 }//end if
3957 3593 }
3958 3594
3959 3595 /**
3960 - * Get the no label text.
3961 - *
3962 - * @since 6.25.1
3963 - *
3964 - * @return string
3965 - */
3966 - public static function get_no_label_text() {
3967 - return __( '(no label)', 'formidable' );
3968 - }
3969 -
3970 - /**
3971 3596 * @since 6.5
3972 3597 *
3973 3598 * @return string
3974 3599 */
@@ -4010,9 +3635,8 @@
4010 3635 *
4011 3636 * @since 1.07.10
4012 3637 *
4013 3638 * @param float $min_version The version the add-on requires.
4014 - *
4015 3639 * @return void
4016 3640 */
4017 3641 public static function min_version_notice( $min_version ) {
4018 3642 $frm_version = self::plugin_version();
@@ -4022,11 +3646,11 @@
4022 3646 return;
4023 3647 }
4024 3648
4025 3649 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
4026 - 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
4027 - esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
4028 - '</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>';
4029 3653 }
4030 3654
4031 3655 /**
4032 3656 * If Pro is far outdated, show a message.
@@ -4032,10 +3656,8 @@
4032 3656 * If Pro is far outdated, show a message.
4033 3657 *
4034 3658 * @since 4.0.01
4035 3659 *
4036 - * @param string $min_version
4037 - *
4038 3660 * @return void
4039 3661 */
4040 3662 public static function min_pro_version_notice( $min_version ) {
4041 3663 if ( ! self::is_formidable_admin() ) {
@@ -4045,14 +3667,25 @@
4045 3667
4046 3668 self::php_version_notice();
4047 3669
4048 3670 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
4049 -
4050 3671 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
4051 3672 return;
4052 3673 }
4053 3674
4054 - 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
4055 3688 }
4056 3689
4057 3690 /**
4058 3691 * If Pro is installed, check the version number.
@@ -4059,9 +3692,8 @@
4059 3692 *
4060 3693 * @since 4.0.01
4061 3694 *
4062 3695 * @param string $min_version
4063 - *
4064 3696 * @return bool
4065 3697 */
4066 3698 public static function meets_min_pro_version( $min_version ) {
4067 3699 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
@@ -4070,19 +3702,16 @@
4070 3702 /**
4071 3703 * Show a message if the PHP version is below the recommendations.
4072 3704 *
4073 3705 * @since 4.0.02
4074 - *
4075 3706 * @return void
4076 3707 */
4077 3708 private static function php_version_notice() {
4078 3709 $message = array();
4079 -
4080 3710 if ( version_compare( phpversion(), '7.0', '<' ) ) {
4081 - $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' );
4082 3712 }
4083 3713
4084 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4085 3714 foreach ( $message as $m ) {
4086 3715 ?>
4087 3716 <div class="frm-banner-alert frm_error_style frm_previous_install">
4088 3717 <?php echo esc_html( $m ); ?>
@@ -4088,14 +3717,12 @@
4088 3717 <?php echo esc_html( $m ); ?>
4089 3718 </div>
4090 3719 <?php
4091 3720 }
4092 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4093 3721 }
4094 3722
4095 3723 /**
4096 3724 * @param string $type
4097 - *
4098 3725 * @return array<string,string>
4099 3726 */
4100 3727 public static function locales( $type = 'date' ) {
4101 3728 $locales = array(
@@ -4189,12 +3816,12 @@
4189 3816 'zu' => __( 'Zulu', 'formidable' ),
4190 3817 );
4191 3818
4192 3819 if ( $type === 'captcha' ) {
4193 - // Remove the languages unavailable for the captcha
3820 + // remove the languages unavailable for the captcha
4194 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' );
4195 3822 } else {
4196 - // Remove the languages unavailable for the datepicker
3823 + // remove the languages unavailable for the datepicker
4197 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' );
4198 3825 }
4199 3826
4200 3827 $locales = array_diff_key( $locales, array_flip( $unset ) );
@@ -4205,13 +3832,14 @@
4205 3832 * @since 5.4.5 Added $args parameter with type.
4206 3833 *
4207 3834 * @param array<string,string> $locales
4208 3835 * @param array $args {
4209 - *
4210 3836 * @type string $type
4211 3837 * }
4212 3838 */
4213 - return apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3839 + $locales = apply_filters( 'frm_locales', $locales, compact( 'type' ) );
3840 +
3841 + return $locales;
4214 3842 }
4215 3843
4216 3844 /**
4217 3845 * @return string
@@ -4218,14 +3846,12 @@
4218 3846 */
4219 3847 public static function get_menu_icon_class() {
4220 3848 if ( is_callable( 'FrmProAppHelper::get_settings' ) ) {
4221 3849 $settings = FrmProAppHelper::get_settings();
4222 -
4223 3850 if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) {
4224 3851 return $settings->menu_icon;
4225 3852 }
4226 3853 }
4227 -
4228 3854 return 'frmfont frm_logo_icon';
4229 3855 }
4230 3856
4231 3857 /**
@@ -4243,9 +3869,10 @@
4243 3869 * @type array $input_attrs Attributes of value input.
4244 3870 * }
4245 3871 */
4246 3872 public static function images_dropdown( $args ) {
4247 - $args = self::fill_default_images_dropdown_args( $args );
3873 + $args = self::fill_default_images_dropdown_args( $args );
3874 +
4248 3875 $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
4249 3876 ob_start();
4250 3877 include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
4251 3878 $output = ob_get_clean();
@@ -4266,9 +3893,8 @@
4266 3893 *
4267 3894 * @since 5.0.04
4268 3895 *
4269 3896 * @param array $args The arguments.
4270 - *
4271 3897 * @return array
4272 3898 */
4273 3899 private static function fill_default_images_dropdown_args( $args ) {
4274 3900 $defaults = array(
@@ -4281,8 +3907,14 @@
4281 3907
4282 3908 $new_args['options'] = (array) $new_args['options'];
4283 3909 $new_args['input_attrs'] = (array) $new_args['input_attrs'];
4284 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 +
4285 3917 /**
4286 3918 * Allows modifying the arguments of images_dropdown() method.
4287 3919 *
4288 3920 * @since 5.0.04
@@ -4298,9 +3930,8 @@
4298 3930 *
4299 3931 * @since 5.0.04
4300 3932 *
4301 3933 * @param array $args The arguments.
4302 - *
4303 3934 * @return string
4304 3935 */
4305 3936 private static function get_images_dropdown_input_attrs( $args ) {
4306 3937 $input_attrs = $args['input_attrs'];
@@ -4307,9 +3938,8 @@
4307 3938 $input_attrs['type'] = 'radio';
4308 3939 $input_attrs['name'] = $args['name'];
4309 3940
4310 3941 $input_attrs_str = '';
4311 -
4312 3942 foreach ( $input_attrs as $key => $input_attr ) {
4313 3943 $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
4314 3944 }
4315 3945
@@ -4325,13 +3955,8 @@
4325 3955 }
4326 3956
4327 3957 /**
4328 3958 * @since 6.7.1
4329 - *
4330 - * @param array $option Option data.
4331 - * @param array $args The arguments of images_dropdown() method.
4332 - *
4333 - * @return array
4334 3959 */
4335 3960 public static function get_images_dropdown_atts( $option, $args ) {
4336 3961 $image = self::get_images_dropdown_option_image( $option, $args );
4337 3962 $classes = self::get_images_dropdown_option_classes( $option, $args );
@@ -4345,9 +3970,8 @@
4345 3970 * @since 5.0.04
4346 3971 *
4347 3972 * @param array $option Option data.
4348 3973 * @param array $args The arguments of images_dropdown() method.
4349 - *
4350 3974 * @return string
4351 3975 */
4352 3976 private static function get_images_dropdown_option_image( $option, $args ) {
4353 3977 $image = self::icon_by_class(
@@ -4376,9 +4000,8 @@
4376 4000 * @since 5.0.04
4377 4001 *
4378 4002 * @param array $option Option data.
4379 4003 * @param array $args The arguments of images_dropdown() method.
4380 - *
4381 4004 * @return string
4382 4005 */
4383 4006 private static function get_images_dropdown_option_classes( $option, $args ) {
4384 4007 $classes = '';
@@ -4406,19 +4029,17 @@
4406 4029 * @since 5.0.04
4407 4030 *
4408 4031 * @param array $option Option data.
4409 4032 * @param array $args The arguments of images_dropdown() method.
4410 - *
4411 4033 * @return string
4412 4034 */
4413 4035 private static function get_images_dropdown_option_html_attrs( $option, $args ) {
4414 4036 $html_attrs = '';
4415 -
4416 4037 if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
4417 4038 $html_attrs_arr = array();
4418 4039
4419 4040 foreach ( $option['custom_attrs'] as $key => $value ) {
4420 - if ( in_array( $key, array( 'type', 'class', 'data-value' ), true ) ) {
4041 + if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
4421 4042 continue;
4422 4043 }
4423 4044
4424 4045 $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
@@ -4476,9 +4097,8 @@
4476 4097 * @since 5.0.07
4477 4098 *
4478 4099 * @param array $values
4479 4100 * @param array $keys
4480 - *
4481 4101 * @return array
4482 4102 */
4483 4103 public static function maybe_filter_array( $values, $keys ) {
4484 4104 $allow_unfiltered_html = self::allow_unfiltered_html();
@@ -4503,14 +4123,13 @@
4503 4123 * @since 5.0.13
4504 4124 *
4505 4125 * @param string $value
4506 4126 * @param array|string $allowed 'all' for everything included as defaults.
4507 - *
4508 4127 * @return string
4509 4128 */
4510 4129 public static function maybe_kses( $value, $allowed = 'all' ) {
4511 4130 if ( self::should_never_allow_unfiltered_html() ) {
4512 - return self::kses( $value, $allowed );
4131 + $value = self::kses( $value, $allowed );
4513 4132 }
4514 4133 return $value;
4515 4134 }
4516 4135
@@ -4520,18 +4139,17 @@
4520 4139 * @since 6.11.2
4521 4140 *
4522 4141 * @param string $key
4523 4142 * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed.
4524 - *
4525 4143 * @return bool
4526 4144 */
4527 4145 public static function input_key_is_safe( $key, $context = 'display' ) {
4528 4146 if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) {
4529 4147 $safe = true;
4530 - } elseif ( str_starts_with( $key, 'data-' ) ) {
4148 + } elseif ( 0 === strpos( $key, 'data-' ) ) {
4531 4149 // Allow all data attributes.
4532 4150 $safe = true;
4533 - } elseif ( str_starts_with( $key, 'aria-' ) ) {
4151 + } elseif ( 0 === strpos( $key, 'aria-' ) ) {
4534 4152 // Allow all aria attributes.
4535 4153 $safe = true;
4536 4154 } else {
4537 4155 $safe_keys = array(
@@ -4573,9 +4191,16 @@
4573 4191
4574 4192 /**
4575 4193 * @since 5.0.16
4576 4194 *
4577 - * @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
4578 4203 *
4579 4204 * @return array
4580 4205 */
4581 4206 public static function get_landing_page_upgrade_data_params( $medium = 'landing' ) {
@@ -4583,9 +4208,8 @@
4583 4208 'medium' => $medium,
4584 4209 'upgrade' => __( 'Form Landing Pages', 'formidable' ),
4585 4210 'message' => __( 'Easily manage a landing page for your form. Upgrade to get form landing pages.', 'formidable' ),
4586 4211 'screenshot' => 'landing.png',
4587 - 'learn-more' => self::get_doc_url( 'landing-page-forms', 'form-landing-page-settings', false ),
4588 4212 );
4589 4213 return self::get_upgrade_data_params( 'landing', $params );
4590 4214 }
4591 4215
@@ -4592,35 +4216,24 @@
4592 4216 /**
4593 4217 * @since 5.0.17
4594 4218 *
4595 4219 * @param string $feature
4596 - *
4597 4220 * @return bool
4598 4221 */
4599 4222 public static function show_new_feature( $feature ) {
4600 4223 $link = FrmAddonsController::install_link( $feature );
4601 -
4602 - if ( array_key_exists( 'status', $link ) || array_key_exists( 'class', $link ) ) {
4603 - return true;
4604 - }
4605 -
4606 - return 'coupons' === $feature && class_exists( 'FrmCouponsAppController' );
4224 + return array_key_exists( 'status', $link ) || array_key_exists( 'class', $link );
4607 4225 }
4608 4226
4609 4227 /**
4610 - * Enhances upgrade data parameters with installation link and plan requirement information.
4611 - *
4612 4228 * @since 5.0.17
4613 4229 *
4614 - * @param string $plugin The plugin slug to get installation data for.
4615 - * @param array $params Initial parameters for the upgrade data.
4616 - * @param bool $detailed Whether to include detailed information.
4617 - *
4618 - * @return array Modified parameters with installation data.
4230 + * @param string $plugin
4231 + * @param array $params
4232 + * @return array
4619 4233 */
4620 - public static function get_upgrade_data_params( $plugin, $params, $detailed = false ) {
4234 + public static function get_upgrade_data_params( $plugin, $params ) {
4621 4235 $link = FrmAddonsController::install_link( $plugin );
4622 -
4623 4236 if ( ! $link ) {
4624 4237 return $params;
4625 4238 }
4626 4239
@@ -4626,20 +4239,15 @@
4626 4239
4627 4240 if ( ! empty( $link['url'] ) && self::pro_is_installed() ) {
4628 4241 $params['oneclick'] = json_encode( $link );
4629 4242 unset( $params['message'] );
4630 -
4631 4243 if ( ! isset( $params['medium'] ) ) {
4632 4244 $params['medium'] = $plugin;
4633 4245 }
4634 4246 } else {
4635 - $params['requires'] = $params['requires'] ?? FrmFormsHelper::get_plan_required( $link );
4247 + $params['requires'] = FrmFormsHelper::get_plan_required( $link );
4636 4248 }
4637 4249
4638 - if ( $detailed ) {
4639 - $params['plugin-status'] = $link['status'] ?? '';
4640 - }
4641 -
4642 4250 return $params;
4643 4251 }
4644 4252
4645 4253 /**
@@ -4648,9 +4256,8 @@
4648 4256 *
4649 4257 * @since 5.0.17
4650 4258 *
4651 4259 * @param string $text
4652 - *
4653 4260 * @return bool
4654 4261 */
4655 4262 public static function ctype_xdigit( $text ) {
4656 4263 if ( function_exists( 'ctype_xdigit' ) ) {
@@ -4665,14 +4272,12 @@
4665 4272 * @since 5.2.01
4666 4273 */
4667 4274 public static function set_current_screen_and_hook_suffix() {
4668 4275 global $hook_suffix;
4669 -
4670 4276 if ( is_null( $hook_suffix ) ) {
4671 4277 // $hook_suffix gets used in substr so make sure it's not null. PHP 8.1 deprecates null in substr.
4672 4278 $hook_suffix = ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
4673 4279 }
4674 -
4675 4280 set_current_screen();
4676 4281 }
4677 4282
4678 4283 /**
@@ -4679,9 +4284,9 @@
4679 4284 * Shows pill text.
4680 4285 *
4681 4286 * @since 5.2.02
4682 4287 *
4683 - * @param string|null $text Text in the pill. Default is NEW.
4288 + * @param string $text Text in the pill. Default is NEW.
4684 4289 */
4685 4290 public static function show_pill_text( $text = null ) {
4686 4291 if ( null === $text ) {
4687 4292 $text = __( 'NEW', 'formidable' );
@@ -4694,9 +4299,8 @@
4694 4299 *
4695 4300 * @since 5.2.07
4696 4301 *
4697 4302 * @param mixed $num Number.
4698 - *
4699 4303 * @return false|int Returns `false` if the passed parameter is not number.
4700 4304 */
4701 4305 public static function count_decimals( $num ) {
4702 4306 if ( ! is_numeric( $num ) ) {
@@ -4704,9 +4308,8 @@
4704 4308 }
4705 4309
4706 4310 $num = (string) $num;
4707 4311 $parts = explode( '.', $num );
4708 -
4709 4312 if ( 1 === count( $parts ) ) {
4710 4313 return 0;
4711 4314 }
4712 4315
@@ -4788,20 +4391,17 @@
4788 4391 * @since 5.5.5
4789 4392 *
4790 4393 * @param string $url
4791 4394 * @param string $expected_extension
4792 - *
4793 4395 * @return bool
4794 4396 */
4795 4397 public static function validate_url_is_in_s3_bucket( $url, $expected_extension ) {
4796 - $file_is_in_expected_s3_bucket = str_starts_with( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4797 -
4398 + $file_is_in_expected_s3_bucket = 0 === strpos( $url, 'https://s3.amazonaws.com/fp.strategy11.com' );
4798 4399 if ( ! $file_is_in_expected_s3_bucket ) {
4799 4400 return false;
4800 4401 }
4801 4402
4802 4403 $parsed = parse_url( $url );
4803 -
4804 4404 if ( ! is_array( $parsed ) ) {
4805 4405 // URL is malformed.
4806 4406 return false;
4807 4407 }
@@ -4807,10 +4407,14 @@
4807 4407 }
4808 4408
4809 4409 $path = $parsed['path'];
4810 4410 $ext = pathinfo( $path, PATHINFO_EXTENSION );
4811 - // The URL isn't to an XML file.
4812 - 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;
4813 4417 }
4814 4418
4815 4419 /**
4816 4420 * Display a dismissable warning message and save its dismissal state.
@@ -4818,9 +4422,8 @@
4818 4422 * @since 6.3
4819 4423 *
4820 4424 * @param string $message The warning message to display.
4821 4425 * @param string $option The unique identifier for the dismissal state of the message and the WP Ajax action.
4822 - *
4823 4426 * @return void
4824 4427 */
4825 4428 public static function add_dismissable_warning_message( $message = '', $option = '' ) {
4826 4429 if ( ! $message || ! $option ) {
@@ -4863,9 +4466,8 @@
4863 4466 *
4864 4467 * @since 6.3
4865 4468 *
4866 4469 * @param string $option The unique identifier for the dismissal state of the message.
4867 - *
4868 4470 * @return void
4869 4471 */
4870 4472 public static function dismiss_warning_message( $option = '' ) {
4871 4473 self::permission_check( 'frm_change_settings' );
@@ -4871,9 +4473,9 @@
4871 4473 self::permission_check( 'frm_change_settings' );
4872 4474 check_ajax_referer( 'frm_ajax', 'nonce' );
4873 4475
4874 4476 if ( $option ) {
4875 - update_option( $option, true, false );
4477 + update_option( $option, true, 'no' );
4876 4478 }
4877 4479
4878 4480 wp_send_json_success();
4879 4481 }
@@ -4887,8 +4489,17 @@
4887 4489 * @return string
4888 4490 */
4889 4491 public static function copy_for_lite_license() {
4890 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 +
4891 4502 return apply_filters( 'frm_license_type_text', $message );
4892 4503 }
4893 4504
4894 4505 /**
@@ -4894,9 +4505,8 @@
4894 4505 /**
4895 4506 * Removes scripts that are unnecessarily loaded across the pages!
4896 4507 *
4897 4508 * @since 6.9
4898 - *
4899 4509 * @return void
4900 4510 */
4901 4511 public static function dequeue_extra_global_scripts() {
4902 4512 wp_dequeue_script( 'frm-surveys-admin' );
@@ -4914,21 +4524,18 @@
4914 4524 * @return void
4915 4525 */
4916 4526 public static function tooltip_icon( $tooltip_text, $atts = array() ) {
4917 4527 $atts['title'] = $tooltip_text;
4918 -
4919 4528 if ( isset( $atts['class'] ) ) {
4920 4529 $atts['class'] .= ' frm_help';
4921 4530 } else {
4922 4531 $atts['class'] = 'frm_help';
4923 4532 }
4924 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4925 4533 ?>
4926 4534 <span <?php self::array_to_html_params( $atts, true ); ?>>
4927 4535 <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?>
4928 4536 </span>
4929 4537 <?php
4930 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4931 4538 }
4932 4539
4933 4540 /**
4934 4541 * Prints errors for settings in onboarding wizard or template settings.
@@ -4949,10 +4556,8 @@
4949 4556 )
4950 4557 );
4951 4558
4952 4559 $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden';
4953 -
4954 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
4955 4560 ?>
4956 4561 <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>">
4957 4562 <?php
4958 4563 if ( is_array( $args['errors'] ) ) {
@@ -4966,9 +4571,8 @@
4966 4571 }
4967 4572 ?>
4968 4573 </span>
4969 4574 <?php
4970 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
4971 4575 }
4972 4576
4973 4577 /**
4974 4578 * Check if GDPR is enabled.
@@ -4991,57 +4595,6 @@
4991 4595 */
4992 4596 public static function no_gdpr_cookies() {
4993 4597 $frm_settings = self::get_settings();
4994 4598 return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies;
4995 - }
4996 -
4997 - /**
4998 - * Check if a string is valid UTF-8.
4999 - *
5000 - * @since 6.24
5001 - *
5002 - * @param string $string The string to check.
5003 - *
5004 - * @return bool
5005 - */
5006 - public static function is_valid_utf8( $string ) {
5007 - // wp_is_valid_utf8 is added in WP 6.9.
5008 - if ( function_exists( 'wp_is_valid_utf8' ) ) {
5009 - return wp_is_valid_utf8( $string );
5010 - }
5011 -
5012 - // As of WP 6.9, seems_utf8 is deprecated.
5013 - return function_exists( 'seems_utf8' ) ? seems_utf8( $string ) : false;
5014 - }
5015 -
5016 - /**
5017 - * Get a documentation URL with UTM parameters and affiliate tracking.
5018 - *
5019 - * @since 6.26
5020 - *
5021 - * @param string $path The relative path to append to the base URL.
5022 - * @param string $campaign The campaign to use for UTM parameters.
5023 - * @param bool $add_kb_base Whether to prepend 'knowledgebase/' to the path. Default true.
5024 - *
5025 - * @return string The processed URL with UTM parameters and affiliate tracking.
5026 - */
5027 - public static function get_doc_url( $path, $campaign, $add_kb_base = true ) {
5028 - $path = trim( $path, '/' );
5029 -
5030 - if ( $add_kb_base ) {
5031 - $path = 'knowledgebase/' . $path;
5032 - }
5033 -
5034 - return self::maybe_add_missing_utm( 'https://formidableforms.com/' . $path, array( 'campaign' => $campaign ) );
5035 - }
5036 -
5037 - /**
5038 - * @since 5.0.16
5039 - * @deprecated 6.26
5040 - *
5041 - * @return bool
5042 - */
5043 - public static function show_landing_pages() {
5044 - _deprecated_function( __METHOD__, '6.26' );
5045 - return true;
5046 4599 }
5047 4600 }