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