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

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