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

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