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

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