PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.10.03
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.10.03
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
formidable / classes / helpers / FrmAppHelper.php

FrmAppHelper.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 4.10.03, at classes/helpers/FrmAppHelper.php

2,926 lines 80.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmAppHelper {
7 public static $db_version = 97; //version of the database we are moving to
8 public static $pro_db_version = 37; //deprecated
9 public static $font_version = 7;
10
11 /**
12 * @since 2.0
13 */
14 public static $plug_version = '4.10.03';
15
16 /**
17 * @since 1.07.02
18 *
19 * @param none
20 *
21 * @return string The version of this plugin
22 */
23 public static function plugin_version() {
24 return self::$plug_version;
25 }
26
27 public static function plugin_folder() {
28 return basename( self::plugin_path() );
29 }
30
31 public static function plugin_path() {
32 return dirname( dirname( dirname( __FILE__ ) ) );
33 }
34
35 public static function plugin_url() {
36 // Prevously FRM_URL constant.
37 return plugins_url( '', self::plugin_path() . '/formidable.php' );
38 }
39
40 public static function relative_plugin_url() {
41 return str_replace( array( 'https:', 'http:' ), '', self::plugin_url() );
42 }
43
44 /**
45 * @return string Site URL
46 */
47 public static function site_url() {
48 return site_url();
49 }
50
51 /**
52 * Get the name of this site
53 * Used for [sitename] shortcode
54 *
55 * @since 2.0
56 * @return string
57 */
58 public static function site_name() {
59 return get_option( 'blogname' );
60 }
61
62 public static function make_affiliate_url( $url ) {
63 $affiliate_id = self::get_affiliate();
64 if ( ! empty( $affiliate_id ) ) {
65 $url = str_replace( array( 'http://', 'https://' ), '', $url );
66 $url = 'http://www.shareasale.com/r.cfm?u=' . absint( $affiliate_id ) . '&b=841990&m=64739&afftrack=plugin&urllink=' . urlencode( $url );
67 }
68
69 return $url;
70 }
71
72 public static function get_affiliate() {
73 return absint( apply_filters( 'frm_affiliate_id', 0 ) );
74 }
75
76 /**
77 * @since 3.04.02
78 * @param array|string $args
79 * @param string $page
80 */
81 public static function admin_upgrade_link( $args, $page = '' ) {
82 if ( empty( $page ) ) {
83 $page = 'https://formidableforms.com/lite-upgrade/';
84 } else {
85 $page = str_replace( 'https://formidableforms.com/', '', $page );
86 $page = 'https://formidableforms.com/' . $page;
87 }
88
89 $anchor = '';
90 if ( is_array( $args ) ) {
91 $medium = $args['medium'];
92 $content = $args['content'];
93 if ( isset( $args['anchor'] ) ) {
94 $anchor = '#' . $args['anchor'];
95 }
96 } else {
97 $medium = $args;
98 }
99
100 $query_args = array(
101 'utm_source' => 'WordPress',
102 'utm_medium' => $medium,
103 'utm_campaign' => 'liteplugin',
104 );
105
106 if ( isset( $content ) ) {
107 $query_args['utm_content'] = $content;
108 }
109
110 if ( is_array( $args ) && isset( $args['param'] ) ) {
111 $query_args['f'] = $args['param'];
112 }
113
114 $link = add_query_arg( $query_args, $page ) . $anchor;
115 return self::make_affiliate_url( $link );
116 }
117
118 /**
119 * Get the Formidable settings
120 *
121 * @since 2.0
122 *
123 * @param array $args - May include the form id when values need translation.
124 * @return FrmSettings $frm_setings
125 */
126 public static function get_settings( $args = array() ) {
127 global $frm_settings;
128 if ( empty( $frm_settings ) ) {
129 $frm_settings = new FrmSettings( $args );
130 } elseif ( isset( $args['current_form'] ) ) {
131 // If the global has already been set, allow strings to be filtered.
132 $frm_settings->maybe_filter_for_form( $args );
133 }
134
135 return $frm_settings;
136 }
137
138 public static function get_menu_name() {
139 $frm_settings = self::get_settings();
140
141 return $frm_settings->menu;
142 }
143
144 /**
145 * @since 3.05
146 */
147 public static function svg_logo( $atts = array() ) {
148 $defaults = array(
149 'height' => 18,
150 'width' => 18,
151 'fill' => '#4d4d4d',
152 'orange' => '#f05a24',
153 );
154 $atts = array_merge( $defaults, $atts );
155
156 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'] ) . '">
157 <path fill="' . esc_attr( $atts['orange'] ) . '" d="M289.6 384h140v76h-140z"/>
158 <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"/>
159 </svg>';
160 }
161
162 /**
163 * @since 4.0
164 */
165 public static function show_logo( $atts = array() ) {
166 echo self::kses( self::svg_logo( $atts ), 'all' ); // WPCS: XSS ok.
167 }
168
169 /**
170 * @since 4.03.02
171 */
172 public static function show_header_logo() {
173 $icon = self::svg_logo(
174 array(
175 'height' => 35,
176 'width' => 35,
177 )
178 );
179
180 $new_icon = apply_filters( 'frm_icon', $icon, true );
181 if ( $new_icon !== $icon ) {
182 if ( strpos( $new_icon, '<svg' ) === 0 ) {
183 $icon = str_replace( 'viewBox="0 0 20', 'width="30" height="35" style="color:#929699" viewBox="0 0 20', $new_icon );
184 } else {
185 // Show nothing if it isn't an SVG.
186 $icon = '<div style="height:39px"></div>';
187 }
188 }
189 echo self::kses( $icon, 'all' ); // WPCS: XSS ok.
190 }
191
192 /**
193 * @since 2.02.04
194 */
195 public static function ips_saved() {
196 $frm_settings = self::get_settings();
197
198 return ! $frm_settings->no_ips;
199 }
200
201 public static function pro_is_installed() {
202 return apply_filters( 'frm_pro_installed', false );
203 }
204
205 /**
206 * @since 4.06.02
207 */
208 public static function pro_is_connected() {
209 global $frm_vars;
210 return self::pro_is_installed() && $frm_vars['pro_is_authorized'];
211 }
212
213 /**
214 * @since 4.06
215 */
216 public static function is_form_builder_page() {
217 $action = self::simple_get( 'frm_action', 'sanitize_title' );
218 return self::is_admin_page( 'formidable' ) && ( $action === 'edit' || $action === 'settings' || $action === 'duplicate' );
219 }
220
221 public static function is_formidable_admin() {
222 $page = self::simple_get( 'page', 'sanitize_title' );
223 $is_formidable = strpos( $page, 'formidable' ) !== false;
224 if ( empty( $page ) ) {
225 $is_formidable = self::is_view_builder_page();
226 }
227
228 return $is_formidable;
229 }
230
231 /**
232 * Check for certain page in Formidable settings
233 *
234 * @since 2.0
235 *
236 * @param string $page The name of the page to check
237 *
238 * @return boolean
239 */
240 public static function is_admin_page( $page = 'formidable' ) {
241 global $pagenow;
242 $get_page = self::simple_get( 'page', 'sanitize_title' );
243 if ( $pagenow ) {
244 // allow this to be true during ajax load i.e. ajax form builder loading
245 $is_page = ( $pagenow == 'admin.php' || $pagenow == 'admin-ajax.php' ) && $get_page == $page;
246 if ( $is_page ) {
247 return true;
248 }
249 }
250
251 return is_admin() && $get_page == $page;
252 }
253
254 /**
255 * If the current page is for editing or creating a view.
256 * Returns false for the views listing page.
257 *
258 * @since 4.0
259 */
260 public static function is_view_builder_page() {
261 global $pagenow;
262
263 if ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' && $pagenow !== 'edit.php' ) {
264 return false;
265 }
266
267 $post_type = self::simple_get( 'post_type', 'sanitize_title' );
268
269 if ( empty( $post_type ) ) {
270 $post_id = self::simple_get( 'post', 'absint' );
271 $post = get_post( $post_id );
272 $post_type = $post ? $post->post_type : '';
273 }
274
275 return $post_type === 'frm_display';
276 }
277
278 /**
279 * Check for the form preview page
280 *
281 * @since 2.0
282 *
283 * @param None
284 *
285 * @return boolean
286 */
287 public static function is_preview_page() {
288 global $pagenow;
289 $action = self::simple_get( 'action', 'sanitize_title' );
290
291 return $pagenow && $pagenow == 'admin-ajax.php' && $action == 'frm_forms_preview';
292 }
293
294 /**
295 * Check for ajax except the form preview page
296 *
297 * @since 2.0
298 *
299 * @param None
300 *
301 * @return boolean
302 */
303 public static function doing_ajax() {
304 return wp_doing_ajax() && ! self::is_preview_page();
305 }
306
307 public static function js_suffix() {
308 return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
309 }
310
311 /**
312 * @since 2.0.8
313 */
314 public static function prevent_caching() {
315 global $frm_vars;
316
317 return isset( $frm_vars['prevent_caching'] ) && $frm_vars['prevent_caching'];
318 }
319
320 /**
321 * Check if on an admin page
322 *
323 * @since 2.0
324 *
325 * @param None
326 *
327 * @return boolean
328 */
329 public static function is_admin() {
330 return is_admin() && ! wp_doing_ajax();
331 }
332
333 /**
334 * Check if value contains blank value or empty array
335 *
336 * @since 2.0
337 *
338 * @param mixed $value - value to check
339 * @param string
340 *
341 * @return boolean
342 */
343 public static function is_empty_value( $value, $empty = '' ) {
344 return ( is_array( $value ) && empty( $value ) ) || $value === $empty;
345 }
346
347 public static function is_not_empty_value( $value, $empty = '' ) {
348 return ! self::is_empty_value( $value, $empty );
349 }
350
351 /**
352 * Get any value from the $_SERVER
353 *
354 * @since 2.0
355 *
356 * @param string $value
357 *
358 * @return string
359 */
360 public static function get_server_value( $value ) {
361 return isset( $_SERVER[ $value ] ) ? wp_strip_all_tags( wp_unslash( $_SERVER[ $value ] ) ) : '';
362 }
363
364 /**
365 * Check for the IP address in several places
366 * Used by [ip] shortcode
367 *
368 * @return string The IP address of the current user
369 */
370 public static function get_ip_address() {
371 $ip_options = array(
372 'HTTP_CLIENT_IP',
373 'HTTP_CF_CONNECTING_IP',
374 'HTTP_X_FORWARDED_FOR',
375 'HTTP_X_FORWARDED',
376 'HTTP_X_CLUSTER_CLIENT_IP',
377 'HTTP_X_REAL_IP',
378 'HTTP_FORWARDED_FOR',
379 'HTTP_FORWARDED',
380 'REMOTE_ADDR',
381 );
382 $ip = '';
383 foreach ( $ip_options as $key ) {
384 if ( ! isset( $_SERVER[ $key ] ) ) {
385 continue;
386 }
387
388 $key = self::get_server_value( $key );
389 foreach ( explode( ',', $key ) as $ip ) {
390 $ip = trim( $ip ); // just to be safe.
391
392 if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) {
393 return sanitize_text_field( $ip );
394 }
395 }
396 }
397
398 return sanitize_text_field( $ip );
399 }
400
401 public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
402 if ( strpos( $param, '[' ) ) {
403 $params = explode( '[', $param );
404 $param = $params[0];
405 }
406
407 if ( $src == 'get' ) {
408 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
409 $value = isset( $_POST[ $param ] ) ? wp_unslash( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? wp_unslash( $_GET[ $param ] ) : $default );
410 if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) {
411 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
412 $value = htmlspecialchars_decode( wp_unslash( $_GET[ $param ] ) );
413 }
414 self::sanitize_value( $sanitize, $value );
415 } else {
416 $value = self::get_simple_request(
417 array(
418 'type' => $src,
419 'param' => $param,
420 'default' => $default,
421 'sanitize' => $sanitize,
422 )
423 );
424 }
425
426 if ( isset( $params ) && is_array( $value ) && ! empty( $value ) ) {
427 foreach ( $params as $k => $p ) {
428 if ( ! $k || ! is_array( $value ) ) {
429 continue;
430 }
431
432 $p = trim( $p, ']' );
433 $value = isset( $value[ $p ] ) ? $value[ $p ] : $default;
434 }
435 }
436
437 return $value;
438 }
439
440 public static function get_post_param( $param, $default = '', $sanitize = '', $serialized = false ) {
441 return self::get_simple_request(
442 array(
443 'type' => 'post',
444 'param' => $param,
445 'default' => $default,
446 'sanitize' => $sanitize,
447 'serialized' => $serialized,
448 )
449 );
450 }
451
452 /**
453 * @since 2.0
454 *
455 * @param string $param
456 * @param string $sanitize
457 * @param string $default
458 *
459 * @return string|array
460 */
461 public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) {
462 return self::get_simple_request(
463 array(
464 'type' => 'get',
465 'param' => $param,
466 'default' => $default,
467 'sanitize' => $sanitize,
468 )
469 );
470 }
471
472 /**
473 * Get a GET/POST/REQUEST value and sanitize it
474 *
475 * @since 2.0.6
476 *
477 * @param array $args
478 *
479 * @return string|array
480 */
481 public static function get_simple_request( $args ) {
482 $defaults = array(
483 'param' => '',
484 'default' => '',
485 'type' => 'get',
486 'sanitize' => 'sanitize_text_field',
487 'serialized' => false,
488 );
489 $args = wp_parse_args( $args, $defaults );
490
491 $value = $args['default'];
492 if ( $args['type'] == 'get' ) {
493 if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
494 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
495 $value = wp_unslash( $_GET[ $args['param'] ] );
496 }
497 } elseif ( $args['type'] == 'post' ) {
498 if ( isset( $_POST[ $args['param'] ] ) ) {
499 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
500 $value = wp_unslash( $_POST[ $args['param'] ] );
501 if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) {
502 self::unserialize_or_decode( $value );
503 }
504 }
505 } else {
506 if ( isset( $_REQUEST[ $args['param'] ] ) ) {
507 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
508 $value = wp_unslash( $_REQUEST[ $args['param'] ] );
509 }
510 }
511
512 self::sanitize_value( $args['sanitize'], $value );
513
514 return $value;
515 }
516
517 /**
518 * Preserve backslashes in a value, but make sure value doesn't get compounding slashes
519 *
520 * @since 2.0.8
521 *
522 * @param string $value
523 *
524 * @return string $value
525 */
526 public static function preserve_backslashes( $value ) {
527 // If backslashes have already been added, don't add them again
528 if ( strpos( $value, '\\\\' ) === false ) {
529 $value = addslashes( $value );
530 }
531
532 return $value;
533 }
534
535 public static function sanitize_value( $sanitize, &$value ) {
536 if ( ! empty( $sanitize ) ) {
537 if ( is_array( $value ) ) {
538 $temp_values = $value;
539 foreach ( $temp_values as $k => $v ) {
540 self::sanitize_value( $sanitize, $value[ $k ] );
541 }
542 } else {
543 $value = call_user_func( $sanitize, $value );
544 }
545 }
546 }
547
548 public static function sanitize_request( $sanitize_method, &$values ) {
549 $temp_values = $values;
550 foreach ( $temp_values as $k => $val ) {
551 if ( isset( $sanitize_method[ $k ] ) ) {
552 $values[ $k ] = call_user_func( $sanitize_method[ $k ], $val );
553 }
554 }
555 }
556
557 /**
558 * @since 4.0.04
559 */
560 public static function sanitize_with_html( &$value ) {
561 self::sanitize_value( 'wp_kses_post', $value );
562 self::decode_specialchars( $value );
563 }
564
565 /**
566 * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&amp;'
567 * this MUST be done, else we'll be back to the '& entity' problem.
568 *
569 * @since 4.0.04
570 */
571 public static function decode_specialchars( &$value ) {
572 if ( is_array( $value ) ) {
573 $temp_values = $value;
574 foreach ( $temp_values as $k => $v ) {
575 self::decode_specialchars( $value[ $k ] );
576 }
577 } else {
578 self::decode_amp( $value );
579 }
580 }
581
582 /**
583 * The wp_specialchars_decode function changes too much.
584 * This will leave HTML as is, but still convert &.
585 * Adapted from wp_specialchars_decode().
586 *
587 * @since 4.03.01
588 *
589 * @param string $string The string to prep.
590 */
591 private static function decode_amp( &$string ) {
592 // Don't bother if there are no entities - saves a lot of processing
593 if ( empty( $string ) || strpos( $string, '&' ) === false ) {
594 return;
595 }
596
597 $translation = array(
598 '&quot;' => '"',
599 '&#034;' => '"',
600 '&#x22;' => '"',
601 '&lt; ' => '< ', // The space preserves the HTML.
602 '&#060; ' => '< ', // The space preserves the HTML.
603 '&gt;' => '>',
604 '&#062;' => '>',
605 '&amp;' => '&',
606 '&#038;' => '&',
607 '&#x26;' => '&',
608 );
609
610 $translation_preg = array(
611 '/&#0*34;/' => '&#034;',
612 '/&#x0*22;/i' => '&#x22;',
613 '/&#0*60;/' => '&#060;',
614 '/&#0*62;/' => '&#062;',
615 '/&#0*38;/' => '&#038;',
616 '/&#x0*26;/i' => '&#x26;',
617 );
618
619 // Remove zero padding on numeric entities
620 $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string );
621
622 // Replace characters according to translation table
623 $string = strtr( $string, $translation );
624 }
625
626 /**
627 * Sanitize the value, and allow some HTML
628 *
629 * @since 2.0
630 *
631 * @param string $value
632 * @param array|string $allowed 'all' for everything included as defaults
633 *
634 * @return string
635 */
636 public static function kses( $value, $allowed = array() ) {
637 $allowed_html = self::allowed_html( $allowed );
638
639 return wp_kses( $value, $allowed_html );
640 }
641
642 /**
643 * @since 2.05.03
644 */
645 private static function allowed_html( $allowed ) {
646 $html = self::safe_html();
647 $allowed_html = array();
648 if ( $allowed == 'all' ) {
649 $allowed_html = $html;
650 } elseif ( ! empty( $allowed ) ) {
651 foreach ( (array) $allowed as $a ) {
652 $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
653 }
654 }
655
656 return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
657 }
658
659 /**
660 * @since 2.05.03
661 */
662 private static function safe_html() {
663 $allow_class = array(
664 'class' => true,
665 'id' => true,
666 );
667
668 return array(
669 'a' => array(
670 'class' => true,
671 'href' => true,
672 'id' => true,
673 'rel' => true,
674 'target' => true,
675 'title' => true,
676 ),
677 'abbr' => array(
678 'title' => true,
679 ),
680 'aside' => $allow_class,
681 'b' => array(),
682 'blockquote' => array(
683 'cite' => true,
684 ),
685 'br' => array(),
686 'cite' => array(
687 'title' => true,
688 ),
689 'code' => array(),
690 'defs' => array(),
691 'del' => array(
692 'datetime' => true,
693 'title' => true,
694 ),
695 'dd' => array(),
696 'div' => array(
697 'class' => true,
698 'id' => true,
699 'title' => true,
700 'style' => true,
701 ),
702 'dl' => array(),
703 'dt' => array(),
704 'em' => array(),
705 'h1' => $allow_class,
706 'h2' => $allow_class,
707 'h3' => $allow_class,
708 'h4' => $allow_class,
709 'h5' => $allow_class,
710 'h6' => $allow_class,
711 'i' => array(
712 'class' => true,
713 'id' => true,
714 'icon' => true,
715 'style' => true,
716 ),
717 'img' => array(
718 'alt' => true,
719 'class' => true,
720 'height' => true,
721 'id' => true,
722 'src' => true,
723 'width' => true,
724 ),
725 'li' => $allow_class,
726 'ol' => $allow_class,
727 'p' => $allow_class,
728 'path' => array(
729 'd' => true,
730 'fill' => true,
731 ),
732 'pre' => array(),
733 'q' => array(
734 'cite' => true,
735 'title' => true,
736 ),
737 'rect' => array(
738 'class' => true,
739 'fill' => true,
740 'height' => true,
741 'width' => true,
742 'x' => true,
743 'y' => true,
744 'rx' => true,
745 'stroke' => true,
746 'stroke-opacity' => true,
747 'stroke-width' => true,
748 ),
749 'section' => $allow_class,
750 'span' => array(
751 'class' => true,
752 'id' => true,
753 'title' => true,
754 'style' => true,
755 ),
756 'strike' => array(),
757 'strong' => array(),
758 'symbol' => array(
759 'class' => true,
760 'id' => true,
761 'viewbox' => true,
762 ),
763 'svg' => array(
764 'class' => true,
765 'id' => true,
766 'xmlns' => true,
767 'viewbox' => true,
768 'width' => true,
769 'height' => true,
770 'style' => true,
771 'fill' => true,
772 ),
773 'use' => array(
774 'href' => true,
775 'xlink:href' => true,
776 ),
777 'ul' => $allow_class,
778 );
779 }
780
781 /**
782 * Used when switching the action for a bulk action
783 *
784 * @since 2.0
785 */
786 public static function remove_get_action() {
787 if ( ! isset( $_GET ) ) {
788 return;
789 }
790
791 $action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' );
792 if ( empty( $action_name ) ) {
793 return;
794 }
795
796 $new_action = self::get_param( $action_name, '', 'get', 'sanitize_text_field' );
797 if ( ! empty( $new_action ) ) {
798 $_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', self::get_server_value( 'REQUEST_URI' ) );
799 }
800 }
801
802 /**
803 * Check the WP query for a parameter
804 *
805 * @since 2.0
806 * @return string|array
807 */
808 public static function get_query_var( $value, $param ) {
809 if ( $value != '' ) {
810 return $value;
811 }
812
813 global $wp_query;
814 if ( isset( $wp_query->query_vars[ $param ] ) ) {
815 $value = $wp_query->query_vars[ $param ];
816 }
817
818 return $value;
819 }
820
821 /**
822 * Try to show the SVG if possible. Otherwise, use the font icon.
823 *
824 * @since 4.0.02
825 * @param string $class
826 * @param array $atts
827 */
828 public static function icon_by_class( $class, $atts = array() ) {
829 $echo = ! isset( $atts['echo'] ) || $atts['echo'];
830 if ( isset( $atts['echo'] ) ) {
831 unset( $atts['echo'] );
832 }
833
834 $html_atts = self::array_to_html_params( $atts );
835
836 $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
837 if ( $icon === $class ) {
838 $icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
839 } else {
840 $class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
841 if ( strpos( $icon, ' ' ) ) {
842 $icon = explode( ' ', $icon );
843 $icon = reset( $icon );
844 }
845 $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '>
846 <use xlink:href="#' . esc_attr( $icon ) . '" />
847 </svg>';
848 }
849
850 if ( $echo ) {
851 echo $icon; // WPCS: XSS ok.
852 } else {
853 return $icon;
854 }
855 }
856
857 /**
858 * Include svg images.
859 *
860 * @since 4.0.02
861 */
862 public static function include_svg() {
863 include_once( self::plugin_path() . '/images/icons.svg' );
864 }
865
866 /**
867 * Convert an associative array to HTML values.
868 *
869 * @since 4.0.02
870 * @param array $atts
871 * @return string
872 */
873 public static function array_to_html_params( $atts ) {
874 $html = '';
875 if ( ! empty( $atts ) ) {
876 foreach ( $atts as $key => $value ) {
877 $html .= ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
878 }
879 }
880 return $html;
881 }
882
883 /**
884 * @since 3.0
885 */
886 public static function get_admin_header( $atts ) {
887 $has_nav = ( isset( $atts['form'] ) && ! empty( $atts['form'] ) && ( ! isset( $atts['is_template'] ) || ! $atts['is_template'] ) );
888 if ( ! isset( $atts['close'] ) || empty( $atts['close'] ) ) {
889 $atts['close'] = admin_url( 'admin.php?page=formidable' );
890 }
891 if ( ! isset( $atts['import_link'] ) ) {
892 $atts['import_link'] = false;
893 }
894
895 include( self::plugin_path() . '/classes/views/shared/admin-header.php' );
896 }
897
898 /**
899 * @since 3.0
900 * @param array $atts
901 */
902 public static function add_new_item_link( $atts ) {
903 if ( ! empty( $atts['new_link'] ) ) {
904 ?>
905 <a href="<?php echo esc_url( $atts['new_link'] ); ?>" class="button button-primary frm-button-primary frm-with-plus">
906 <?php self::icon_by_class( 'frmfont frm_plus_icon frm_svg15' ); ?>
907 <?php esc_html_e( 'Add New', 'formidable' ); ?>
908 </a>
909 <?php
910 } elseif ( ! empty( $atts['trigger_new_form_modal'] ) ) {
911 ?>
912 <a href="#" class="button button-primary frm-button-primary frm-with-plus frm-trigger-new-form-modal">
913 <?php
914 self::icon_by_class( 'frmfont frm_plus_icon frm_svg15' );
915 esc_html_e( 'Add New', 'formidable' );
916 ?>
917 </a>
918 <?php
919 } elseif ( isset( $atts['link_hook'] ) ) {
920 do_action( $atts['link_hook']['hook'], $atts['link_hook']['param'] );
921 }
922 }
923
924 /**
925 * @since 3.06
926 */
927 public static function show_search_box( $atts ) {
928 $defaults = array(
929 'placeholder' => '',
930 'tosearch' => '',
931 'text' => __( 'Search', 'formidable' ),
932 'input_id' => '',
933 );
934 $atts = array_merge( $defaults, $atts );
935
936 if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
937 $atts['tosearch'] = 'frm-card';
938 }
939
940 $class = 'frm-search-input';
941 if ( ! empty( $atts['tosearch'] ) ) {
942 $class .= ' frm-auto-search';
943 }
944
945 $input_id = $atts['input_id'] . '-search-input';
946
947 ?>
948 <p class="frm-search">
949 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
950 <?php echo esc_html( $atts['text'] ); ?>:
951 </label>
952 <span class="frmfont frm_search_icon"></span>
953 <input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s"
954 value="<?php _admin_search_query(); ?>" placeholder="<?php echo esc_attr( $atts['placeholder'] ); ?>"
955 class="<?php echo esc_attr( $class ); ?>" data-tosearch="<?php echo esc_attr( $atts['tosearch'] ); ?>"
956 <?php if ( ! empty( $atts['tosearch'] ) ) { ?>
957 autocomplete="off"
958 <?php } ?>
959 />
960 <?php
961 if ( empty( $atts['tosearch'] ) ) {
962 submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
963 }
964 ?>
965 </p>
966 <?php
967 }
968
969 /**
970 * @param string $type
971 */
972 public static function trigger_hook_load( $type, $object = null ) {
973 // Only load the form hooks once.
974 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
975 if ( ! $hooks_loaded ) {
976 do_action( 'frm_load_' . $type . '_hooks' );
977 }
978 }
979
980 /**
981 * Save all front-end js scripts into a single file
982 *
983 * @since 3.0
984 */
985 public static function save_combined_js() {
986 $file_atts = apply_filters(
987 'frm_js_location',
988 array(
989 'file_name' => 'frm.min.js',
990 'new_file_path' => self::plugin_path() . '/js',
991 )
992 );
993 $new_file = new FrmCreateFile( $file_atts );
994
995 $files = array(
996 self::plugin_path() . '/js/jquery/jquery.placeholder.min.js',
997 self::plugin_path() . '/js/formidable.min.js',
998 );
999 $files = apply_filters( 'frm_combined_js_files', $files );
1000 $new_file->combine_files( $files );
1001 }
1002
1003 /**
1004 * Check a value from a shortcode to see if true or false.
1005 * True when value is 1, true, 'true', 'yes'
1006 *
1007 * @since 1.07.10
1008 *
1009 * @param string $value The value to compare
1010 *
1011 * @return boolean True or False
1012 */
1013 public static function is_true( $value ) {
1014 return ( true === $value || 1 == $value || 'true' == $value || 'yes' == $value );
1015 }
1016
1017 /**
1018 * Gets all post from a specific post type.
1019 *
1020 * @since 4.10.01 Add `$post_type` argument.
1021 *
1022 * @param string $post_type Post type to query. Default is `page`.
1023 * @return WP_Post[]
1024 */
1025 public static function get_pages( $post_type = 'page' ) {
1026 $query = array(
1027 'post_type' => $post_type,
1028 'post_status' => array( 'publish', 'private' ),
1029 'numberposts' => - 1,
1030 'orderby' => 'title',
1031 'order' => 'ASC',
1032 );
1033
1034 return get_posts( $query );
1035 }
1036
1037 /**
1038 * Renders an autocomplete page selection or a regular dropdown depending on
1039 * the total page count
1040 *
1041 * @since 4.03.06
1042 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
1043 *
1044 * @param array $args Selection arguments.
1045 */
1046 public static function maybe_autocomplete_pages_options( $args ) {
1047 $args = self::preformat_selection_args( $args );
1048
1049 $pages_count = wp_count_posts( $args['post_type'] );
1050
1051 if ( $pages_count->publish <= 50 ) {
1052 self::wp_pages_dropdown( $args );
1053 return;
1054 }
1055
1056 wp_enqueue_script( 'jquery-ui-autocomplete' );
1057
1058 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
1059 $title = '';
1060
1061 if ( $selected ) {
1062 $title = get_the_title( $selected );
1063 }
1064
1065 ?>
1066 <input type="text" class="frm-page-search"
1067 data-post-type="<?php echo esc_attr( $args['post_type'] ); ?>"
1068 placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>"
1069 value="<?php echo esc_attr( $title ); ?>" />
1070 <input type="hidden" name="<?php echo esc_attr( $args['field_name'] ); ?>"
1071 class="frm_autocomplete_value_input"
1072 value="<?php echo esc_attr( $selected ); ?>" />
1073 <?php
1074 }
1075
1076 /**
1077 * @param array $args
1078 * @param string $page_id Deprecated.
1079 * @param boolean $truncate Deprecated.
1080 */
1081 public static function wp_pages_dropdown( $args = array(), $page_id = '', $truncate = false ) {
1082 self::prep_page_dropdown_params( $page_id, $truncate, $args );
1083
1084 $pages = self::get_pages( $args['post_type'] );
1085 $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
1086
1087 ?>
1088 <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
1089 <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1090 <?php foreach ( $pages as $page ) { ?>
1091 <option value="<?php echo esc_attr( $page->ID ); ?>" <?php selected( $selected, $page->ID ); ?>>
1092 <?php echo esc_html( $args['truncate'] ? self::truncate( $page->post_title, $args['truncate'] ) : $page->post_title ); ?>
1093 </option>
1094 <?php } ?>
1095 </select>
1096 <?php
1097 }
1098
1099 /**
1100 * Fill in missing parameters passed to wp_pages_dropdown().
1101 * This is for reverse compatibility with switching 3 params to 1.
1102 *
1103 * @since 4.03.06
1104 */
1105 private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
1106 if ( ! is_array( $args ) ) {
1107 $args = array(
1108 'field_name' => $args,
1109 'page_id' => $page_id,
1110 'truncate' => $truncate,
1111 );
1112 }
1113
1114 $args = self::preformat_selection_args( $args );
1115 }
1116
1117 /**
1118 * Filter to format args for page dropdown or autocomplete
1119 *
1120 * @since 4.03.06
1121 * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array.
1122 */
1123 private static function preformat_selection_args( $args ) {
1124 $defaults = array(
1125 'truncate' => false,
1126 'placeholder' => ' ',
1127 'field_name' => '',
1128 'page_id' => '',
1129 'post_type' => 'page',
1130 'autocomplete_placeholder' => __( 'Select a Page', 'formidable' ),
1131 );
1132
1133 return array_merge( $defaults, $args );
1134 }
1135
1136 public static function post_edit_link( $post_id ) {
1137 $post = get_post( $post_id );
1138 if ( $post ) {
1139 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1140 $post_url = self::maybe_full_screen_link( $post_url );
1141
1142 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
1143 }
1144
1145 return '';
1146 }
1147
1148 /**
1149 * Hide the WordPress menus on some pages.
1150 *
1151 * @since 4.0
1152 */
1153 public static function is_full_screen() {
1154 $full_builder = self::is_form_builder_page();
1155 $styler = self::is_admin_page( 'formidable-styles' ) || self::is_admin_page( 'formidable-styles2' );
1156 $full_entries = self::simple_get( 'frm-full', 'absint' );
1157
1158 return $full_builder || $full_entries || $styler || self::is_view_builder_page();
1159 }
1160
1161 /**
1162 * @since 4.0
1163 */
1164 public static function maybe_full_screen_link( $link ) {
1165 $is_full = self::simple_get( 'frm-full', 'absint' );
1166 if ( $is_full && ! empty( $link ) && $link !== '#' ) {
1167 $link .= '&frm-full=1';
1168 }
1169 return $link;
1170 }
1171
1172 /**
1173 * @param string $field_name
1174 * @param string|array $capability
1175 * @param string $multiple 'single' and 'multiple'
1176 */
1177 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
1178 ?>
1179 <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
1180 <?php echo ( 'multiple' === $multiple ) ? 'multiple="multiple"' : ''; ?>
1181 class="frm_multiselect">
1182 <?php self::roles_options( $capability ); ?>
1183 </select>
1184 <?php
1185 }
1186
1187 /**
1188 * @since 4.07
1189 * @param array|string $selected
1190 * @param string $current
1191 */
1192 private static function selected( $selected, $current ) {
1193 if ( is_callable( 'FrmProAppHelper::selected' ) ) {
1194 FrmProAppHelper::selected( $selected, $current );
1195 } else {
1196 selected( in_array( $current, (array) $selected, true ) );
1197 }
1198 }
1199
1200 /**
1201 * @param string|array $capability
1202 */
1203 public static function roles_options( $capability ) {
1204 global $frm_vars;
1205 if ( isset( $frm_vars['editable_roles'] ) ) {
1206 $editable_roles = $frm_vars['editable_roles'];
1207 } else {
1208 $editable_roles = get_editable_roles();
1209 $frm_vars['editable_roles'] = $editable_roles;
1210 }
1211
1212 foreach ( $editable_roles as $role => $details ) {
1213 $name = translate_user_role( $details['name'] );
1214 ?>
1215 <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_attr( $name ); ?> </option>
1216 <?php
1217 unset( $role, $details );
1218 }
1219 }
1220
1221 public static function frm_capabilities( $type = 'auto' ) {
1222 $cap = array(
1223 'frm_view_forms' => __( 'View Forms', 'formidable' ),
1224 'frm_edit_forms' => __( 'Add and Edit Forms', 'formidable' ),
1225 'frm_delete_forms' => __( 'Delete Forms', 'formidable' ),
1226 'frm_change_settings' => __( 'Access this Settings Page', 'formidable' ),
1227 'frm_view_entries' => __( 'View Entries from Admin Area', 'formidable' ),
1228 'frm_delete_entries' => __( 'Delete Entries from Admin Area', 'formidable' ),
1229 );
1230
1231 if ( ! self::pro_is_installed() && 'pro' != $type ) {
1232 return $cap;
1233 }
1234
1235 $cap['frm_create_entries'] = __( 'Add Entries from Admin Area', 'formidable' );
1236 $cap['frm_edit_entries'] = __( 'Edit Entries from Admin Area', 'formidable' );
1237 $cap['frm_view_reports'] = __( 'View Reports', 'formidable' );
1238 $cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
1239
1240 return $cap;
1241 }
1242
1243 /**
1244 * Call the WordPress current_user_can but also validate empty strings as true for any logged in user
1245 *
1246 * @since 4.06.03
1247 *
1248 * @param string $role
1249 *
1250 * @return bool
1251 */
1252 public static function current_user_can( $role ) {
1253 if ( $role === '-1' ) {
1254 return false;
1255 }
1256
1257 if ( $role === 'loggedout' ) {
1258 return ! is_user_logged_in();
1259 }
1260
1261 if ( $role === 'loggedin' || ! $role ) {
1262 return is_user_logged_in();
1263 }
1264
1265 if ( $role == 1 ) {
1266 $role = 'administrator';
1267 }
1268
1269 if ( ! is_user_logged_in() ) {
1270 return false;
1271 }
1272
1273 return current_user_can( $role );
1274 }
1275
1276 /**
1277 * @param string|array $needed_role
1278 * @return bool
1279 */
1280 public static function user_has_permission( $needed_role ) {
1281 if ( is_array( $needed_role ) ) {
1282 foreach ( $needed_role as $role ) {
1283 if ( self::current_user_can( $role ) ) {
1284 return true;
1285 }
1286 }
1287
1288 return false;
1289 }
1290
1291 $can = self::current_user_can( $needed_role );
1292
1293 if ( $can || in_array( $needed_role, array( '-1', 'loggedout' ) ) ) {
1294 return $can;
1295 }
1296
1297 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
1298 foreach ( $roles as $role ) {
1299 if ( current_user_can( $role ) ) {
1300 return true;
1301 }
1302 if ( $role == $needed_role ) {
1303 break;
1304 }
1305 }
1306
1307 return false;
1308 }
1309
1310 /**
1311 * Make sure administrators can see Formidable menu
1312 *
1313 * @since 2.0
1314 */
1315 public static function maybe_add_permissions() {
1316 self::force_capability( 'frm_view_entries' );
1317
1318 if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
1319 return;
1320 }
1321
1322 $user_id = get_current_user_id();
1323 $user = new WP_User( $user_id );
1324 $frm_roles = self::frm_capabilities();
1325 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
1326 $user->add_cap( $frm_role );
1327 unset( $frm_role, $frm_role_description );
1328 }
1329 }
1330
1331 /**
1332 * Make sure admins have permission to see the menu items
1333 *
1334 * @since 2.0.6
1335 */
1336 public static function force_capability( $cap = 'frm_change_settings' ) {
1337 if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
1338 $role = get_role( 'administrator' );
1339 $frm_roles = self::frm_capabilities();
1340 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
1341 $role->add_cap( $frm_role );
1342 }
1343 }
1344 }
1345
1346 /**
1347 * Check if the user has permision for action.
1348 * Return permission message and stop the action if no permission
1349 *
1350 * @since 2.0
1351 *
1352 * @param string $permission
1353 */
1354 public static function permission_check( $permission, $show_message = 'show' ) {
1355 $permission_error = self::permission_nonce_error( $permission );
1356 if ( $permission_error !== false ) {
1357 if ( 'hide' == $show_message ) {
1358 $permission_error = '';
1359 }
1360 wp_die( esc_html( $permission_error ) );
1361 }
1362 }
1363
1364 /**
1365 * Check user permission and nonce
1366 *
1367 * @since 2.0
1368 *
1369 * @param string $permission
1370 *
1371 * @return false|string The permission message or false if allowed
1372 */
1373 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
1374 if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
1375 $frm_settings = self::get_settings();
1376
1377 return $frm_settings->admin_permission;
1378 }
1379
1380 $error = false;
1381 if ( empty( $nonce_name ) ) {
1382 return $error;
1383 }
1384
1385 $nonce_value = ( $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
1386 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
1387 $frm_settings = self::get_settings();
1388 $error = $frm_settings->admin_permission;
1389 }
1390
1391 return $error;
1392 }
1393
1394 public static function checked( $values, $current ) {
1395 if ( self::check_selected( $values, $current ) ) {
1396 echo ' checked="checked"';
1397 }
1398 }
1399
1400 public static function check_selected( $values, $current ) {
1401 $values = self::recursive_function_map( $values, 'trim' );
1402 $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
1403 $current = htmlspecialchars_decode( trim( $current ) );
1404
1405 return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
1406 }
1407
1408 public static function recursive_function_map( $value, $function ) {
1409 if ( is_array( $value ) ) {
1410 $original_function = $function;
1411 if ( count( $value ) ) {
1412 $function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
1413 } else {
1414 $function = array( $function );
1415 }
1416 if ( ! self::is_assoc( $value ) ) {
1417 $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
1418 } else {
1419 foreach ( $value as $k => $v ) {
1420 if ( ! is_array( $v ) ) {
1421 $value[ $k ] = call_user_func( $original_function, $v );
1422 }
1423 }
1424 }
1425 } else {
1426 $value = call_user_func( $function, $value );
1427 }
1428
1429 return $value;
1430 }
1431
1432 public static function is_assoc( $array ) {
1433 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
1434 }
1435
1436 /**
1437 * Flatten a multi-dimensional array
1438 */
1439 public static function array_flatten( $array, $keys = 'keep' ) {
1440 $return = array();
1441 foreach ( $array as $key => $value ) {
1442 if ( is_array( $value ) ) {
1443 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
1444 } else {
1445 if ( $keys == 'keep' ) {
1446 $return[ $key ] = $value;
1447 } else {
1448 $return[] = $value;
1449 }
1450 }
1451 }
1452
1453 return $return;
1454 }
1455
1456 public static function esc_textarea( $text, $is_rich_text = false ) {
1457 $safe_text = str_replace( '&quot;', '"', $text );
1458 if ( ! $is_rich_text ) {
1459 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
1460 }
1461 $safe_text = str_replace( '&amp; ', '& ', $safe_text );
1462
1463 return apply_filters( 'esc_textarea', $safe_text, $text );
1464 }
1465
1466 /**
1467 * Add auto paragraphs to text areas
1468 *
1469 * @since 2.0
1470 */
1471 public static function use_wpautop( $content ) {
1472 if ( apply_filters( 'frm_use_wpautop', true ) && ! is_array( $content ) ) {
1473 $content = wpautop( str_replace( '<br>', '<br />', $content ) );
1474 }
1475
1476 return $content;
1477 }
1478
1479 public static function replace_quotes( $val ) {
1480 // Replace double quotes.
1481 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
1482
1483 // Replace single quotes.
1484 $val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
1485
1486 return $val;
1487 }
1488
1489 /**
1490 * @since 2.0
1491 * @return string The base Google APIS url for the current version of jQuery UI
1492 */
1493 public static function jquery_ui_base_url() {
1494 $url = 'http' . ( is_ssl() ? 's' : '' ) . '://ajax.googleapis.com/ajax/libs/jqueryui/' . self::script_version( 'jquery-ui-core', '1.11.4' );
1495 $url = apply_filters( 'frm_jquery_ui_base_url', $url );
1496
1497 return $url;
1498 }
1499
1500 /**
1501 * @param string $handle
1502 */
1503 public static function script_version( $handle, $default = 0 ) {
1504 global $wp_scripts;
1505 if ( ! $wp_scripts ) {
1506 return $default;
1507 }
1508
1509 $ver = $default;
1510 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
1511 return $ver;
1512 }
1513
1514 $query = $wp_scripts->registered[ $handle ];
1515 if ( is_object( $query ) && ! empty( $query->ver ) ) {
1516 $ver = $query->ver;
1517 }
1518
1519 return $ver;
1520 }
1521
1522 public static function js_redirect( $url ) {
1523 return '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>';
1524 }
1525
1526 public static function get_user_id_param( $user_id ) {
1527 if ( ! $user_id || empty( $user_id ) || is_numeric( $user_id ) ) {
1528 return $user_id;
1529 }
1530
1531 $user_id = sanitize_text_field( $user_id );
1532 if ( $user_id == 'current' ) {
1533 $user_id = get_current_user_id();
1534 } else {
1535 if ( is_email( $user_id ) ) {
1536 $user = get_user_by( 'email', $user_id );
1537 } else {
1538 $user = get_user_by( 'login', $user_id );
1539 }
1540
1541 if ( $user ) {
1542 $user_id = $user->ID;
1543 }
1544 unset( $user );
1545 }
1546
1547 return $user_id;
1548 }
1549
1550 public static function get_file_contents( $filename, $atts = array() ) {
1551 if ( ! is_file( $filename ) ) {
1552 return false;
1553 }
1554
1555 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
1556 ob_start();
1557 include( $filename );
1558 $contents = ob_get_contents();
1559 ob_end_clean();
1560
1561 return $contents;
1562 }
1563
1564 /**
1565 * @param string $name
1566 * @param string $table_name
1567 * @param string $column
1568 * @param int $id
1569 * @param int $num_chars
1570 */
1571 public static function get_unique_key( $name, $table_name, $column, $id = 0, $num_chars = 5 ) {
1572 $key = '';
1573 if ( $name ) {
1574 $key = sanitize_key( $name );
1575 $key = self::maybe_clear_long_key( $key, $column );
1576 }
1577
1578 if ( ! $key ) {
1579 $key = self::generate_new_key( $num_chars );
1580 }
1581
1582 $key = self::prevent_numeric_and_reserved_keys( $key );
1583
1584 $key_check = FrmDb::get_var(
1585 $table_name,
1586 array(
1587 $column => $key,
1588 'ID !' => $id,
1589 ),
1590 $column
1591 );
1592
1593 if ( $key_check || is_numeric( $key_check ) ) {
1594 // Create a unique field id if it has already been used.
1595 $key = $key . substr( md5( microtime() . rand() ), 0, 10 );
1596 }
1597
1598 return $key;
1599 }
1600
1601 /**
1602 * Possibly reset a key to avoid conflicts with column size limits.
1603 *
1604 * @param string $key
1605 * @param string $column
1606 * @return string either the original key value, or an empty string if the key was too long.
1607 */
1608 private static function maybe_clear_long_key( $key, $column ) {
1609 if ( 'field_key' === $column && strlen( $key ) >= 70 ) {
1610 $key = '';
1611 }
1612 return $key;
1613 }
1614
1615 /**
1616 * @param int $num_chars
1617 * @return string
1618 */
1619 private static function generate_new_key( $num_chars ) {
1620 $max_slug_value = pow( 36, $num_chars );
1621 $min_slug_value = 37; // we want to have at least 2 characters in the slug
1622 return base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
1623 }
1624
1625 /**
1626 * @param string $key
1627 * @return string
1628 */
1629 private static function prevent_numeric_and_reserved_keys( $key ) {
1630 if ( is_numeric( $key ) ) {
1631 $key .= 'a';
1632 } else {
1633 $not_allowed = array(
1634 'id',
1635 'key',
1636 'created-at',
1637 'detaillink',
1638 'editlink',
1639 'siteurl',
1640 'evenodd',
1641 );
1642 if ( in_array( $key, $not_allowed, true ) ) {
1643 $key .= 'a';
1644 }
1645 }
1646 return $key;
1647 }
1648
1649 /**
1650 * Editing a Form or Entry
1651 *
1652 * @param string $table
1653 *
1654 * @return bool|array
1655 */
1656 public static function setup_edit_vars( $record, $table, $fields = '', $default = false, $post_values = array(), $args = array() ) {
1657 if ( ! $record ) {
1658 return false;
1659 }
1660
1661 if ( empty( $post_values ) ) {
1662 $post_values = wp_unslash( $_POST );
1663 }
1664
1665 $values = array(
1666 'id' => $record->id,
1667 'fields' => array(),
1668 );
1669
1670 foreach ( array( 'name', 'description' ) as $var ) {
1671 $default_val = isset( $record->{$var} ) ? $record->{$var} : '';
1672 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
1673 unset( $var, $default_val );
1674 }
1675
1676 $values['description'] = self::use_wpautop( $values['description'] );
1677
1678 self::fill_form_opts( $record, $table, $post_values, $values );
1679
1680 self::prepare_field_arrays( $fields, $record, $values, array_merge( $args, compact( 'default', 'post_values' ) ) );
1681
1682 if ( $table == 'entries' ) {
1683 $values = FrmEntriesHelper::setup_edit_vars( $values, $record );
1684 } elseif ( $table == 'forms' ) {
1685 $values = FrmFormsHelper::setup_edit_vars( $values, $record, $post_values );
1686 }
1687
1688 return $values;
1689 }
1690
1691 private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
1692 if ( ! empty( $fields ) ) {
1693 foreach ( (array) $fields as $field ) {
1694 if ( ! self::is_admin_page() ) {
1695 // Don't prep default values on the form settings page.
1696 $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
1697 }
1698 $args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
1699 self::fill_field_defaults( $field, $record, $values, $args );
1700 }
1701 }
1702 }
1703
1704 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
1705 $post_values = $args['post_values'];
1706
1707 if ( $args['default'] ) {
1708 $meta_value = $field->default_value;
1709 } else {
1710 if ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) {
1711 if ( ! isset( $field->field_options['custom_field'] ) ) {
1712 $field->field_options['custom_field'] = '';
1713 }
1714 $meta_value = FrmProEntryMetaHelper::get_post_value(
1715 $record->post_id,
1716 $field->field_options['post_field'],
1717 $field->field_options['custom_field'],
1718 array(
1719 'truncate' => false,
1720 'type' => $field->type,
1721 'form_id' => $field->form_id,
1722 'field' => $field,
1723 )
1724 );
1725 } else {
1726 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
1727 }
1728 }
1729
1730 $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
1731 if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
1732 $new_value = $post_values['item_meta'][ $field->id ];
1733 self::unserialize_or_decode( $new_value );
1734 } else {
1735 $new_value = $meta_value;
1736 }
1737
1738 $field_array = self::start_field_array( $field );
1739 $field_array['value'] = $new_value;
1740 $field_array['type'] = apply_filters( 'frm_field_type', $field_type, $field, $new_value );
1741 $field_array['parent_form_id'] = $args['parent_form_id'];
1742
1743 $args['field_type'] = $field_type;
1744
1745 FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
1746
1747 if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
1748 $field_array['unique_msg'] = '';
1749 }
1750
1751 $field_array = array_merge( (array) $field->field_options, $field_array );
1752
1753 $values['fields'][ $field->id ] = $field_array;
1754 }
1755
1756 /**
1757 * @since 3.0
1758 *
1759 * @param object $field
1760 *
1761 * @return array
1762 */
1763 public static function start_field_array( $field ) {
1764 return array(
1765 'id' => $field->id,
1766 'default_value' => $field->default_value,
1767 'name' => $field->name,
1768 'description' => $field->description,
1769 'options' => $field->options,
1770 'required' => $field->required,
1771 'field_key' => $field->field_key,
1772 'field_order' => $field->field_order,
1773 'form_id' => $field->form_id,
1774 );
1775 }
1776
1777 /**
1778 * @param string $table
1779 */
1780 private static function fill_form_opts( $record, $table, $post_values, array &$values ) {
1781 if ( $table == 'entries' ) {
1782 $form = $record->form_id;
1783 FrmForm::maybe_get_form( $form );
1784 } else {
1785 $form = $record;
1786 }
1787
1788 if ( ! $form ) {
1789 return;
1790 }
1791
1792 $values['form_name'] = isset( $record->form_id ) ? $form->name : '';
1793 $values['parent_form_id'] = isset( $record->form_id ) ? $form->parent_form_id : 0;
1794
1795 if ( ! is_array( $form->options ) ) {
1796 return;
1797 }
1798
1799 foreach ( $form->options as $opt => $value ) {
1800 if ( isset( $post_values[ $opt ] ) ) {
1801 $values[ $opt ] = $post_values[ $opt ];
1802 self::unserialize_or_decode( $values[ $opt ] );
1803 } else {
1804 $values[ $opt ] = $value;
1805 }
1806 }
1807
1808 self::fill_form_defaults( $post_values, $values );
1809 }
1810
1811 /**
1812 * Set to POST value or default
1813 */
1814 private static function fill_form_defaults( $post_values, array &$values ) {
1815 $form_defaults = FrmFormsHelper::get_default_opts();
1816
1817 foreach ( $form_defaults as $opt => $default ) {
1818 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
1819 $values[ $opt ] = ( $post_values && isset( $post_values['options'][ $opt ] ) ) ? $post_values['options'][ $opt ] : $default;
1820 }
1821
1822 unset( $opt, $default );
1823 }
1824
1825 if ( ! isset( $values['custom_style'] ) ) {
1826 $values['custom_style'] = self::custom_style_value( $post_values );
1827 }
1828
1829 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
1830 if ( ! isset( $values[ $h . '_html' ] ) ) {
1831 $values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
1832 }
1833 unset( $h );
1834 }
1835 }
1836
1837 /**
1838 * @since 2.2.10
1839 *
1840 * @param array $post_values
1841 *
1842 * @return boolean|int
1843 */
1844 public static function custom_style_value( $post_values ) {
1845 if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
1846 $custom_style = absint( $post_values['options']['custom_style'] );
1847 } else {
1848 $frm_settings = self::get_settings();
1849 $custom_style = ( $frm_settings->load_style != 'none' );
1850 }
1851
1852 return $custom_style;
1853 }
1854
1855 public static function truncate( $str, $length, $minword = 3, $continue = '...' ) {
1856 if ( is_array( $str ) ) {
1857 return '';
1858 }
1859
1860 $length = (int) $length;
1861 $str = wp_strip_all_tags( $str );
1862 $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
1863
1864 if ( $length == 0 ) {
1865 return '';
1866 } elseif ( $length <= 10 ) {
1867 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
1868
1869 return $sub . ( ( $length < $original_len ) ? $continue : '' );
1870 }
1871
1872 $sub = '';
1873 $len = 0;
1874
1875 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
1876
1877 foreach ( $words as $word ) {
1878 $part = ( ( $sub != '' ) ? ' ' : '' ) . $word;
1879 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
1880 if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
1881 break;
1882 }
1883
1884 $sub .= $part;
1885 $len += self::mb_function( array( 'mb_strlen', 'strlen' ), array( $part ) );
1886
1887 if ( substr_count( $sub, ' ' ) > $minword && $total_len >= $length ) {
1888 break;
1889 }
1890
1891 unset( $total_len, $word );
1892 }
1893
1894 return $sub . ( ( $len < $original_len ) ? $continue : '' );
1895 }
1896
1897 public static function mb_function( $function_names, $args ) {
1898 $mb_function_name = $function_names[0];
1899 $function_name = $function_names[1];
1900 if ( function_exists( $mb_function_name ) ) {
1901 $function_name = $mb_function_name;
1902 }
1903
1904 return call_user_func_array( $function_name, $args );
1905 }
1906
1907 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
1908 if ( empty( $date ) ) {
1909 return $date;
1910 }
1911
1912 if ( empty( $date_format ) ) {
1913 $date_format = get_option( 'date_format' );
1914 }
1915
1916 if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
1917 $frmpro_settings = new FrmProSettings();
1918 $date = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
1919 }
1920
1921 $formatted = self::get_localized_date( $date_format, $date );
1922
1923 $do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
1924 if ( $do_time ) {
1925 $formatted .= self::add_time_to_date( $time_format, $date );
1926 }
1927
1928 return $formatted;
1929 }
1930
1931 private static function add_time_to_date( $time_format, $date ) {
1932 if ( empty( $time_format ) ) {
1933 $time_format = get_option( 'time_format' );
1934 }
1935
1936 $trimmed_format = trim( $time_format );
1937 $time = '';
1938 if ( $time_format && ! empty( $trimmed_format ) ) {
1939 $time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
1940 }
1941
1942 return $time;
1943 }
1944
1945 /**
1946 * @since 2.0.8
1947 */
1948 public static function get_localized_date( $date_format, $date ) {
1949 $date = get_date_from_gmt( $date );
1950
1951 return date_i18n( $date_format, strtotime( $date ) );
1952 }
1953
1954 /**
1955 * Gets the time ago in words
1956 *
1957 * @param int $from in seconds
1958 * @param int|string $to in seconds
1959 *
1960 * @return string $time_ago
1961 */
1962 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
1963 if ( empty( $to ) ) {
1964 $now = new DateTime();
1965 } else {
1966 $now = new DateTime( '@' . $to );
1967 }
1968 $ago = new DateTime( '@' . $from );
1969
1970 // Get the time difference
1971 $diff_object = $now->diff( $ago );
1972 $diff = get_object_vars( $diff_object );
1973
1974 // Add week amount and update day amount
1975 $diff['w'] = floor( $diff['d'] / 7 );
1976 $diff['d'] -= $diff['w'] * 7;
1977
1978 $time_strings = self::get_time_strings();
1979
1980 if ( ! is_numeric( $levels ) ) {
1981 // Show time in specified unit.
1982 $levels = self::get_unit( $levels );
1983 if ( isset( $time_strings[ $levels ] ) ) {
1984 $diff = array(
1985 $levels => self::time_format( $levels, $diff ),
1986 );
1987 $time_strings = array(
1988 $levels => $time_strings[ $levels ],
1989 );
1990 }
1991 $levels = 1;
1992 }
1993
1994 foreach ( $time_strings as $k => $v ) {
1995 if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
1996 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
1997 } elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
1998 // Account for 0.
1999 $time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
2000 } else {
2001 unset( $time_strings[ $k ] );
2002 }
2003 }
2004
2005 $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
2006 $time_strings = array_slice( $time_strings, 0, absint( $levels_deep ) );
2007 $time_ago_string = implode( ' ', $time_strings );
2008
2009 return $time_ago_string;
2010 }
2011
2012 /**
2013 * @since 4.05.01
2014 */
2015 private static function time_format( $unit, $diff ) {
2016 $return = array(
2017 'y' => 'y',
2018 'd' => 'days',
2019 );
2020 if ( isset( $return[ $unit ] ) ) {
2021 return $diff[ $return[ $unit ] ];
2022 }
2023
2024 $total = $diff['days'] * self::convert_time( 'd', $unit );
2025
2026 $times = array( 'h', 'i', 's' );
2027
2028 foreach ( $times as $time ) {
2029 if ( ! isset( $diff[ $time ] ) ) {
2030 continue;
2031 }
2032
2033 $total += $diff[ $time ] * self::convert_time( $time, $unit );
2034 }
2035
2036 return floor( $total );
2037 }
2038
2039 /**
2040 * @since 4.05.01
2041 */
2042 private static function convert_time( $from, $to ) {
2043 $convert = array(
2044 's' => 1,
2045 'i' => MINUTE_IN_SECONDS,
2046 'h' => HOUR_IN_SECONDS,
2047 'd' => DAY_IN_SECONDS,
2048 'w' => WEEK_IN_SECONDS,
2049 'm' => DAY_IN_SECONDS * 30.42,
2050 'y' => DAY_IN_SECONDS * 365.25,
2051 );
2052
2053 return $convert[ $from ] / $convert[ $to ];
2054 }
2055
2056 /**
2057 * @since 4.05.01
2058 */
2059 private static function get_unit( $unit ) {
2060 $units = self::get_time_strings();
2061 if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
2062 return $unit;
2063 }
2064
2065 foreach ( $units as $u => $strings ) {
2066 if ( in_array( $unit, $strings ) ) {
2067 return $u;
2068 }
2069 }
2070 return 1;
2071 }
2072
2073 /**
2074 * Get the translatable time strings. The untranslated version is a failsafe
2075 * in case langauges are changing for the unit set in the shortcode.
2076 *
2077 * @since 2.0.20
2078 * @return array
2079 */
2080 private static function get_time_strings() {
2081 return array(
2082 'y' => array(
2083 __( 'year', 'formidable' ),
2084 __( 'years', 'formidable' ),
2085 'year',
2086 ),
2087 'm' => array(
2088 __( 'month', 'formidable' ),
2089 __( 'months', 'formidable' ),
2090 'month',
2091 ),
2092 'w' => array(
2093 __( 'week', 'formidable' ),
2094 __( 'weeks', 'formidable' ),
2095 'week',
2096 ),
2097 'd' => array(
2098 __( 'day', 'formidable' ),
2099 __( 'days', 'formidable' ),
2100 'day',
2101 ),
2102 'h' => array(
2103 __( 'hour', 'formidable' ),
2104 __( 'hours', 'formidable' ),
2105 'hour',
2106 ),
2107 'i' => array(
2108 __( 'minute', 'formidable' ),
2109 __( 'minutes', 'formidable' ),
2110 'minute',
2111 ),
2112 's' => array(
2113 __( 'second', 'formidable' ),
2114 __( 'seconds', 'formidable' ),
2115 'second',
2116 ),
2117 );
2118 }
2119
2120 // Pagination Methods.
2121
2122 /**
2123 * @param integer $current_p
2124 */
2125 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
2126 return ( ( $r_count < ( $current_p * $p_size ) ) ? $r_count : ( $current_p * $p_size ) );
2127 }
2128
2129 /**
2130 * @param integer $current_p
2131 */
2132 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
2133 if ( $current_p == 1 ) {
2134 return 1;
2135 } else {
2136 return ( self::get_last_record_num( $r_count, ( $current_p - 1 ), $p_size ) + 1 );
2137 }
2138 }
2139
2140 /**
2141 * @return array
2142 */
2143 public static function json_to_array( $json_vars ) {
2144 $vars = array();
2145 foreach ( $json_vars as $jv ) {
2146 $jv_name = explode( '[', $jv['name'] );
2147 $last = count( $jv_name ) - 1;
2148 foreach ( $jv_name as $p => $n ) {
2149 $name = trim( $n, ']' );
2150 if ( ! isset( $l1 ) ) {
2151 $l1 = $name;
2152 }
2153
2154 if ( ! isset( $l2 ) ) {
2155 $l2 = $name;
2156 }
2157
2158 if ( ! isset( $l3 ) ) {
2159 $l3 = $name;
2160 }
2161
2162 $this_val = ( $p == $last ) ? $jv['value'] : array();
2163
2164 switch ( $p ) {
2165 case 0:
2166 $l1 = $name;
2167 self::add_value_to_array( $name, $l1, $this_val, $vars );
2168 break;
2169
2170 case 1:
2171 $l2 = $name;
2172 self::add_value_to_array( $name, $l2, $this_val, $vars[ $l1 ] );
2173 break;
2174
2175 case 2:
2176 $l3 = $name;
2177 self::add_value_to_array( $name, $l3, $this_val, $vars[ $l1 ][ $l2 ] );
2178 break;
2179
2180 case 3:
2181 $l4 = $name;
2182 self::add_value_to_array( $name, $l4, $this_val, $vars[ $l1 ][ $l2 ][ $l3 ] );
2183 }
2184
2185 unset( $this_val, $n );
2186 }
2187
2188 unset( $last, $jv );
2189 }
2190
2191 return $vars;
2192 }
2193
2194 /**
2195 * @param string $name
2196 * @param string $l1
2197 */
2198 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
2199 if ( $name == '' ) {
2200 $vars[] = $val;
2201 } elseif ( ! isset( $vars[ $l1 ] ) ) {
2202 $vars[ $l1 ] = $val;
2203 }
2204 }
2205
2206 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
2207 $tooltips = array(
2208 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
2209 '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' ),
2210 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
2211 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
2212 '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' ),
2213 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
2214 /* translators: %1$s: Form name, %2$s: Date */
2215 '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() ) ),
2216 );
2217
2218 if ( ! isset( $tooltips[ $name ] ) ) {
2219 return;
2220 }
2221
2222 if ( 'open' == $class ) {
2223 echo ' frm_help"';
2224 } else {
2225 echo ' class="frm_help"';
2226 }
2227
2228 echo ' title="' . esc_attr( $tooltips[ $name ] );
2229
2230 if ( 'open' != $class ) {
2231 echo '"';
2232 }
2233 }
2234
2235 /**
2236 * Add the current_page class to that page in the form nav
2237 */
2238 public static function select_current_page( $page, $current_page, $action = array() ) {
2239 if ( $current_page != $page ) {
2240 return;
2241 }
2242
2243 $frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
2244 if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
2245 echo ' class="current_page"';
2246 }
2247 }
2248
2249 /**
2250 * Prepare and json_encode post content
2251 *
2252 * @since 2.0
2253 *
2254 * @param array $post_content
2255 *
2256 * @return string $post_content ( json encoded array )
2257 */
2258 public static function prepare_and_encode( $post_content ) {
2259 // Loop through array to strip slashes and add only the needed ones.
2260 foreach ( $post_content as $key => $val ) {
2261 // Replace problematic characters (like &quot;)
2262 if ( is_string( $val ) ) {
2263 $val = str_replace( '&quot;', '"', $val );
2264 }
2265
2266 self::prepare_action_slashes( $val, $key, $post_content );
2267 unset( $key, $val );
2268 }
2269
2270 // json_encode the array.
2271 $post_content = json_encode( $post_content );
2272
2273 // Add extra slashes for \r\n since WP strips them.
2274 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
2275
2276 // allow for &quot
2277 $post_content = str_replace( '&quot;', '\\"', $post_content );
2278
2279 return $post_content;
2280 }
2281
2282 private static function prepare_action_slashes( $val, $key, &$post_content ) {
2283 if ( ! isset( $post_content[ $key ] ) ) {
2284 return;
2285 }
2286
2287 if ( is_array( $val ) ) {
2288 foreach ( $val as $k1 => $v1 ) {
2289 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
2290 unset( $k1, $v1 );
2291 }
2292 } else {
2293 // Strip all slashes so everything is the same, no matter where the value is coming from
2294 $val = stripslashes( $val );
2295
2296 // Add backslashes before double quotes and forward slashes only
2297 $post_content[ $key ] = addcslashes( $val, '"\\/' );
2298 }
2299 }
2300
2301 /**
2302 * Check for either json or serilized data. This is temporary while transitioning
2303 * all data to json.
2304 *
2305 * @since 4.02.03
2306 */
2307 public static function unserialize_or_decode( &$value ) {
2308 if ( is_array( $value ) ) {
2309 return;
2310 }
2311
2312 if ( is_serialized( $value ) ) {
2313 $value = maybe_unserialize( $value );
2314 } else {
2315 $value = self::maybe_json_decode( $value, false );
2316 }
2317 }
2318
2319 /**
2320 * Decode a JSON string.
2321 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
2322 */
2323 public static function maybe_json_decode( $string, $single_to_array = true ) {
2324 if ( is_array( $string ) ) {
2325 return $string;
2326 }
2327
2328 $new_string = json_decode( $string, true );
2329 if ( function_exists( 'json_last_error' ) ) {
2330 // php 5.3+
2331 $single_value = false;
2332 if ( ! $single_to_array ) {
2333 $single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
2334 }
2335 if ( json_last_error() == JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
2336 $string = $new_string;
2337 }
2338 }
2339
2340 return $string;
2341 }
2342
2343 /**
2344 * Reformat the json serialized array in name => value array.
2345 *
2346 * @since 4.02.03
2347 */
2348 public static function format_form_data( &$form ) {
2349 $formatted = array();
2350
2351 foreach ( $form as $input ) {
2352 if ( ! isset( $input['name'] ) ) {
2353 continue;
2354 }
2355 $key = $input['name'];
2356 if ( isset( $formatted[ $key ] ) ) {
2357 if ( is_array( $formatted[ $key ] ) ) {
2358 $formatted[ $key ][] = $input['value'];
2359 } else {
2360 $formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
2361 }
2362 } else {
2363 $formatted[ $key ] = $input['value'];
2364 }
2365 }
2366
2367 parse_str( http_build_query( $formatted ), $form );
2368 }
2369
2370 /**
2371 * @since 4.02.03
2372 */
2373 public static function maybe_json_encode( $value ) {
2374 if ( is_array( $value ) ) {
2375 $value = wp_json_encode( $value );
2376 }
2377 return $value;
2378 }
2379
2380 /**
2381 * @since 1.07.10
2382 *
2383 * @param string $post_type The name of the post type that may need to be highlighted
2384 * echo The javascript to open and highlight the Formidable menu
2385 */
2386 public static function maybe_highlight_menu( $post_type ) {
2387 global $post;
2388
2389 if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
2390 return;
2391 }
2392
2393 if ( is_object( $post ) && $post->post_type != $post_type ) {
2394 return;
2395 }
2396
2397 self::load_admin_wide_js();
2398 echo '<script type="text/javascript">jQuery(document).ready(function(){frmSelectSubnav();});</script>';
2399 }
2400
2401 /**
2402 * Load the JS file on non-Formidable pages in the admin area
2403 *
2404 * @since 2.0
2405 */
2406 public static function load_admin_wide_js( $load = true ) {
2407 $version = self::plugin_version();
2408 wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
2409
2410 $global_strings = array(
2411 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
2412 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
2413 'url' => self::plugin_url(),
2414 'app_url' => 'https://formidableforms.com/',
2415 'loading' => __( 'Loading&hellip;', 'formidable' ),
2416 'nonce' => wp_create_nonce( 'frm_ajax' ),
2417 );
2418 wp_localize_script( 'formidable_admin_global', 'frmGlobal', $global_strings );
2419
2420 if ( $load ) {
2421 wp_enqueue_script( 'formidable_admin_global' );
2422 }
2423 }
2424
2425 /**
2426 * @since 2.0.9
2427 */
2428 public static function load_font_style() {
2429 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
2430 }
2431
2432 /**
2433 * @param string $location
2434 */
2435 public static function localize_script( $location ) {
2436 global $wp_scripts;
2437
2438 $ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
2439 $ajax_url = apply_filters( 'frm_ajax_url', $ajax_url );
2440
2441 $script_strings = array(
2442 'ajax_url' => $ajax_url,
2443 'images_url' => self::plugin_url() . '/images',
2444 'loading' => __( 'Loading&hellip;', 'formidable' ),
2445 'remove' => __( 'Remove', 'formidable' ),
2446 'offset' => apply_filters( 'frm_scroll_offset', 4 ),
2447 'nonce' => wp_create_nonce( 'frm_ajax' ),
2448 'id' => __( 'ID', 'formidable' ),
2449 'no_results' => __( 'No results match', 'formidable' ),
2450 'file_spam' => __( 'That file looks like Spam.', 'formidable' ),
2451 'calc_error' => __( 'There is an error in the calculation in the field with key', 'formidable' ),
2452 'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ),
2453 );
2454
2455 $data = $wp_scripts->get_data( 'formidable', 'data' );
2456 if ( empty( $data ) ) {
2457 wp_localize_script( 'formidable', 'frm_js', $script_strings );
2458 }
2459
2460 if ( $location == 'admin' ) {
2461 $frm_settings = self::get_settings();
2462 $admin_script_strings = array(
2463 'desc' => __( '(Click to add description)', 'formidable' ),
2464 'blank' => __( '(Blank)', 'formidable' ),
2465 'no_label' => __( '(no label)', 'formidable' ),
2466 'saving' => esc_attr( __( 'Saving', 'formidable' ) ),
2467 'saved' => esc_attr( __( 'Saved', 'formidable' ) ),
2468 'ok' => __( 'OK', 'formidable' ),
2469 'cancel' => __( 'Cancel', 'formidable' ),
2470 'default_label' => __( 'Default', 'formidable' ),
2471 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
2472 'no_clear_default' => __( 'Do not clear default value when typing', 'formidable' ),
2473 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
2474 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
2475 'caution' => __( 'Heads up', 'formidable' ),
2476 'confirm' => __( 'Are you sure?', 'formidable' ),
2477 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
2478 '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' ),
2479 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
2480 'default_unique' => $frm_settings->unique_msg,
2481 'default_conf' => __( 'The entered values do not match', 'formidable' ),
2482 'enter_email' => __( 'Enter Email', 'formidable' ),
2483 'confirm_email' => __( 'Confirm Email', 'formidable' ),
2484 'conditional_text' => __( 'Conditional content here', 'formidable' ),
2485 'new_option' => __( 'New Option', 'formidable' ),
2486 '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' ),
2487 'enter_password' => __( 'Enter Password', 'formidable' ),
2488 'confirm_password' => __( 'Confirm Password', 'formidable' ),
2489 'import_complete' => __( 'Import Complete', 'formidable' ),
2490 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
2491 'no_save_warning' => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
2492 'private_label' => __( 'Private', 'formidable' ),
2493 'jquery_ui_url' => self::jquery_ui_base_url(),
2494 'pro_url' => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '',
2495 'no_licenses' => __( 'No new licenses were found', 'formidable' ),
2496 'unmatched_parens' => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ),
2497 'view_shortcodes' => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ),
2498 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
2499 'only_one_action' => __( 'This form action is limited to one per form. Please edit the existing form action.', 'formidable' ),
2500 'unsafe_params' => FrmFormsHelper::reserved_words(),
2501 /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
2502 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
2503 /* 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. */
2504 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
2505 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ),
2506 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
2507 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ),
2508 'install' => __( 'Install', 'formidable' ),
2509 'active' => __( 'Active', 'formidable' ),
2510 'select_a_field' => __( 'Select a Field', 'formidable' ),
2511 'no_items_found' => __( 'No items found.', 'formidable' ),
2512 );
2513 $admin_script_strings = apply_filters( 'frm_admin_script_strings', $admin_script_strings );
2514
2515 $data = $wp_scripts->get_data( 'formidable_admin', 'data' );
2516 if ( empty( $data ) ) {
2517 wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
2518 }
2519 }
2520 }
2521
2522 /**
2523 * Echo the message on the plugins listing page
2524 *
2525 * @since 1.07.10
2526 *
2527 * @param float $min_version The version the add-on requires
2528 */
2529 public static function min_version_notice( $min_version ) {
2530 $frm_version = self::plugin_version();
2531
2532 // Check if Formidable meets minimum requirements.
2533 if ( version_compare( $frm_version, $min_version, '>=' ) ) {
2534 return;
2535 }
2536
2537 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
2538 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">' .
2539 esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
2540 '</div></td></tr>';
2541 }
2542
2543 /**
2544 * If Pro is far outdated, show a message.
2545 *
2546 * @since 4.0.01
2547 */
2548 public static function min_pro_version_notice( $min_version ) {
2549 if ( ! self::is_formidable_admin() ) {
2550 // Don't show admin-wide.
2551 return;
2552 }
2553
2554 self::php_version_notice();
2555
2556 $is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
2557 if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
2558 return;
2559 }
2560
2561 $pro_version = FrmProDb::$plug_version;
2562 $expired = FrmAddonsController::is_license_expired();
2563 ?>
2564 <div class="error frm_previous_install">
2565 <?php
2566 esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
2567 if ( empty( $expired ) ) {
2568 echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
2569 } else {
2570 echo '<br/>Please <a href="https://formidableforms.com/account/downloads/?utm_source=WordPress&utm_medium=outdated">renew now</a> to get the latest version.';
2571 }
2572 ?>
2573 </div>
2574 <?php
2575 }
2576
2577 /**
2578 * If Pro is installed, check the version number.
2579 *
2580 * @since 4.0.01
2581 */
2582 public static function meets_min_pro_version( $min_version ) {
2583 return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
2584 }
2585
2586 /**
2587 * Show a message if the browser or PHP version is below the recommendations.
2588 *
2589 * @since 4.0.02
2590 */
2591 private static function php_version_notice() {
2592 $message = array();
2593 if ( version_compare( phpversion(), '5.6', '<' ) ) {
2594 $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' );
2595 }
2596
2597 $browser = self::get_server_value( 'HTTP_USER_AGENT' );
2598 $is_ie = strpos( $browser, 'MSIE' ) !== false;
2599 if ( $is_ie ) {
2600 $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' );
2601 }
2602
2603 foreach ( $message as $m ) {
2604 ?>
2605 <div class="error frm_previous_install">
2606 <?php echo esc_html( $m ); ?>
2607 </div>
2608 <?php
2609 }
2610 }
2611
2612 public static function locales( $type = 'date' ) {
2613 $locales = array(
2614 'en' => __( 'English', 'formidable' ),
2615 'af' => __( 'Afrikaans', 'formidable' ),
2616 'sq' => __( 'Albanian', 'formidable' ),
2617 'ar' => __( 'Arabic', 'formidable' ),
2618 'hy' => __( 'Armenian', 'formidable' ),
2619 'az' => __( 'Azerbaijani', 'formidable' ),
2620 'eu' => __( 'Basque', 'formidable' ),
2621 'bs' => __( 'Bosnian', 'formidable' ),
2622 'bg' => __( 'Bulgarian', 'formidable' ),
2623 'ca' => __( 'Catalan', 'formidable' ),
2624 'zh-HK' => __( 'Chinese Hong Kong', 'formidable' ),
2625 'zh-CN' => __( 'Chinese Simplified', 'formidable' ),
2626 'zh-TW' => __( 'Chinese Traditional', 'formidable' ),
2627 'hr' => __( 'Croatian', 'formidable' ),
2628 'cs' => __( 'Czech', 'formidable' ),
2629 'da' => __( 'Danish', 'formidable' ),
2630 'nl' => __( 'Dutch', 'formidable' ),
2631 'en-GB' => __( 'English/UK', 'formidable' ),
2632 'eo' => __( 'Esperanto', 'formidable' ),
2633 'et' => __( 'Estonian', 'formidable' ),
2634 'fo' => __( 'Faroese', 'formidable' ),
2635 'fa' => __( 'Farsi/Persian', 'formidable' ),
2636 'fil' => __( 'Filipino', 'formidable' ),
2637 'fi' => __( 'Finnish', 'formidable' ),
2638 'fr' => __( 'French', 'formidable' ),
2639 'fr-CA' => __( 'French/Canadian', 'formidable' ),
2640 'fr-CH' => __( 'French/Swiss', 'formidable' ),
2641 'de' => __( 'German', 'formidable' ),
2642 'de-AT' => __( 'German/Austria', 'formidable' ),
2643 'de-CH' => __( 'German/Switzerland', 'formidable' ),
2644 'el' => __( 'Greek', 'formidable' ),
2645 'he' => __( 'Hebrew', 'formidable' ),
2646 'iw' => __( 'Hebrew', 'formidable' ),
2647 'hi' => __( 'Hindi', 'formidable' ),
2648 'hu' => __( 'Hungarian', 'formidable' ),
2649 'is' => __( 'Icelandic', 'formidable' ),
2650 'id' => __( 'Indonesian', 'formidable' ),
2651 'it' => __( 'Italian', 'formidable' ),
2652 'ja' => __( 'Japanese', 'formidable' ),
2653 'ko' => __( 'Korean', 'formidable' ),
2654 'lv' => __( 'Latvian', 'formidable' ),
2655 'lt' => __( 'Lithuanian', 'formidable' ),
2656 'ms' => __( 'Malaysian', 'formidable' ),
2657 'no' => __( 'Norwegian', 'formidable' ),
2658 'pl' => __( 'Polish', 'formidable' ),
2659 'pt' => __( 'Portuguese', 'formidable' ),
2660 'pt-BR' => __( 'Portuguese/Brazilian', 'formidable' ),
2661 'pt-PT' => __( 'Portuguese/Portugal', 'formidable' ),
2662 'ro' => __( 'Romanian', 'formidable' ),
2663 'ru' => __( 'Russian', 'formidable' ),
2664 'sr' => __( 'Serbian', 'formidable' ),
2665 'sr-SR' => __( 'Serbian', 'formidable' ),
2666 'sk' => __( 'Slovak', 'formidable' ),
2667 'sl' => __( 'Slovenian', 'formidable' ),
2668 'es' => __( 'Spanish', 'formidable' ),
2669 'es-419' => __( 'Spanish/Latin America', 'formidable' ),
2670 'sv' => __( 'Swedish', 'formidable' ),
2671 'ta' => __( 'Tamil', 'formidable' ),
2672 'th' => __( 'Thai', 'formidable' ),
2673 'tr' => __( 'Turkish', 'formidable' ),
2674 'uk' => __( 'Ukranian', 'formidable' ),
2675 'vi' => __( 'Vietnamese', 'formidable' ),
2676 );
2677
2678 if ( $type === 'captcha' ) {
2679 // remove the languages unavailable for the captcha
2680 $unset = array( 'af', 'sq', 'hy', 'az', 'eu', 'bs', 'zh-HK', 'eo', 'et', 'fo', 'fr-CH', 'he', 'is', 'ms', 'sr-SR', 'ta' );
2681 } else {
2682 // remove the languages unavailable for the datepicker
2683 $unset = array( 'fil', 'fr-CA', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419' );
2684 }
2685
2686 $locales = array_diff_key( $locales, array_flip( $unset ) );
2687 $locales = apply_filters( 'frm_locales', $locales );
2688
2689 return $locales;
2690 }
2691
2692 /**
2693 * Output HTML containing reference text for accessibility
2694 */
2695 public static function multiselect_accessibility() {
2696 include_once self::plugin_path() . '/classes/views/frm-forms/multiselect-accessibility.php';
2697 }
2698
2699 /**
2700 * @since 4.07
2701 * @deprecated 4.09.01
2702 */
2703 public static function renewal_message() {
2704 if ( is_callable( 'FrmProAddonsController::renewal_message' ) ) {
2705 FrmProAddonsController::renewal_message();
2706 return;
2707 }
2708
2709 if ( ! FrmAddonsController::is_license_expired() ) {
2710 return;
2711 }
2712
2713 ?>
2714 <div class="frm_error_style" style="text-align:left">
2715 <?php self::icon_by_class( 'frmfont frm_alert_icon' ); ?>
2716 &nbsp;
2717 <?php esc_html_e( 'Your account has expired', 'formidable' ); ?>
2718 <div style="float:right">
2719 <a href="<?php echo esc_url( self::admin_upgrade_link( 'form-expired', 'account/downloads/' ) ); ?>">
2720 <?php esc_html_e( 'Renew Now', 'formidable' ); ?>
2721 </a>
2722 </div>
2723 </div>
2724 <?php
2725 }
2726
2727 /**
2728 * @since 4.08
2729 * @deprecated 4.09.01
2730 */
2731 public static function expiring_message() {
2732 _deprecated_function( __METHOD__, '4.09.01', 'FrmProAddonsController::expiring_message' );
2733 if ( is_callable( 'FrmProAddonsController::expiring_message' ) ) {
2734 FrmProAddonsController::expiring_message();
2735 }
2736 }
2737
2738 /**
2739 * Use the WP 4.7 wp_doing_ajax function
2740 *
2741 * @since 2.05.07
2742 * @deprecated 4.04.04
2743 */
2744 public static function wp_doing_ajax() {
2745 _deprecated_function( __METHOD__, '4.04.04', 'wp_doing_ajax' );
2746 return wp_doing_ajax();
2747 }
2748
2749 /**
2750 * @deprecated 4.0
2751 */
2752 public static function insert_opt_html( $args ) {
2753 _deprecated_function( __METHOD__, '4.0', 'FrmFormsHelper::insert_opt_html' );
2754 FrmFormsHelper::insert_opt_html( $args );
2755 }
2756
2757 /**
2758 * Used to filter shortcode in text widgets
2759 *
2760 * @deprecated 2.5.4
2761 * @codeCoverageIgnore
2762 */
2763 public static function widget_text_filter_callback( $matches ) {
2764 return FrmDeprecated::widget_text_filter_callback( $matches );
2765 }
2766
2767 /**
2768 * @deprecated 3.01
2769 * @codeCoverageIgnore
2770 */
2771 public static function sanitize_array( &$values ) {
2772 FrmDeprecated::sanitize_array( $values );
2773 }
2774
2775 /**
2776 * @param array $settings
2777 * @param string $group
2778 *
2779 * @since 2.0.6
2780 * @deprecated 2.05.06
2781 * @codeCoverageIgnore
2782 */
2783 public static function save_settings( $settings, $group ) {
2784 return FrmDeprecated::save_settings( $settings, $group );
2785 }
2786
2787 /**
2788 * @since 2.0.4
2789 * @deprecated 2.05.06
2790 * @codeCoverageIgnore
2791 */
2792 public static function save_json_post( $settings ) {
2793 return FrmDeprecated::save_json_post( $settings );
2794 }
2795
2796 /**
2797 * @since 2.0
2798 * @deprecated 2.05.06
2799 * @codeCoverageIgnore
2800 *
2801 * @param string $cache_key The unique name for this cache
2802 * @param string $group The name of the cache group
2803 * @param string $query If blank, don't run a db call
2804 * @param string $type The wpdb function to use with this query
2805 *
2806 * @return mixed $results The cache or query results
2807 */
2808 public static function check_cache( $cache_key, $group = '', $query = '', $type = 'get_var', $time = 300 ) {
2809 return FrmDeprecated::check_cache( $cache_key, $group, $query, $type, $time );
2810 }
2811
2812 /**
2813 * @deprecated 2.05.06
2814 * @codeCoverageIgnore
2815 */
2816 public static function set_cache( $cache_key, $results, $group = '', $time = 300 ) {
2817 return FrmDeprecated::set_cache( $cache_key, $results, $group, $time );
2818 }
2819
2820 /**
2821 * @deprecated 2.05.06
2822 * @codeCoverageIgnore
2823 */
2824 public static function add_key_to_group_cache( $key, $group ) {
2825 FrmDeprecated::add_key_to_group_cache( $key, $group );
2826 }
2827
2828 /**
2829 * @deprecated 2.05.06
2830 * @codeCoverageIgnore
2831 */
2832 public static function get_group_cached_keys( $group ) {
2833 return FrmDeprecated::get_group_cached_keys( $group );
2834 }
2835
2836 /**
2837 * @since 2.0
2838 * @deprecated 2.05.06
2839 * @codeCoverageIgnore
2840 * @return mixed The cached value or false
2841 */
2842 public static function check_cache_and_transient( $cache_key ) {
2843 return FrmDeprecated::check_cache( $cache_key );
2844 }
2845
2846 /**
2847 * @since 2.0
2848 * @deprecated 2.05.06
2849 * @codeCoverageIgnore
2850 *
2851 * @param string $cache_key
2852 */
2853 public static function delete_cache_and_transient( $cache_key, $group = 'default' ) {
2854 FrmDeprecated::delete_cache_and_transient( $cache_key, $group );
2855 }
2856
2857 /**
2858 * @since 2.0
2859 * @deprecated 2.05.06
2860 * @codeCoverageIgnore
2861 *
2862 * @param string $group The name of the cache group
2863 */
2864 public static function cache_delete_group( $group ) {
2865 FrmDeprecated::cache_delete_group( $group );
2866 }
2867
2868 /**
2869 * @since 1.07.10
2870 * @deprecated 2.05.06
2871 * @codeCoverageIgnore
2872 *
2873 * @param string $term The value to escape
2874 *
2875 * @return string The escaped value
2876 */
2877 public static function esc_like( $term ) {
2878 return FrmDeprecated::esc_like( $term );
2879 }
2880
2881 /**
2882 * @param string $order_query
2883 *
2884 * @deprecated 2.05.06
2885 * @codeCoverageIgnore
2886 */
2887 public static function esc_order( $order_query ) {
2888 return FrmDeprecated::esc_order( $order_query );
2889 }
2890
2891 /**
2892 * @deprecated 2.05.06
2893 * @codeCoverageIgnore
2894 */
2895 public static function esc_order_by( &$order_by ) {
2896 FrmDeprecated::esc_order_by( $order_by );
2897 }
2898
2899 /**
2900 * @param string $limit
2901 *
2902 * @deprecated 2.05.06
2903 * @codeCoverageIgnore
2904 */
2905 public static function esc_limit( $limit ) {
2906 return FrmDeprecated::esc_limit( $limit );
2907 }
2908
2909 /**
2910 * @since 2.0
2911 * @deprecated 2.05.06
2912 * @codeCoverageIgnore
2913 */
2914 public static function prepare_array_values( $array, $type = '%s' ) {
2915 return FrmDeprecated::prepare_array_values( $array, $type );
2916 }
2917
2918 /**
2919 * @deprecated 2.05.06
2920 * @codeCoverageIgnore
2921 */
2922 public static function prepend_and_or_where( $starts_with = ' WHERE ', $where = '' ) {
2923 return FrmDeprecated::prepend_and_or_where( $starts_with, $where );
2924 }
2925 }
2926