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