PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 2.05.09
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v2.05.09
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / helpers / FrmAppHelper.php

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

1,927 lines 61.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 = 47; //version of the database we are moving to
8 public static $pro_db_version = 37; //deprecated
9
10 /**
11 * @since 2.0
12 */
13 public static $plug_version = '2.05.09';
14
15 /**
16 * @since 1.07.02
17 *
18 * @param none
19 * @return string The version of this plugin
20 */
21 public static function plugin_version() {
22 return self::$plug_version;
23 }
24
25 public static function plugin_folder() {
26 return basename(self::plugin_path());
27 }
28
29 public static function plugin_path() {
30 return dirname(dirname(dirname(__FILE__)));
31 }
32
33 public static function plugin_url() {
34 //prevously FRM_URL constant
35 return plugins_url( '', self::plugin_path() . '/formidable.php' );
36 }
37
38 public static function relative_plugin_url() {
39 return str_replace( array( 'https:', 'http:' ), '', self::plugin_url() );
40 }
41
42 /**
43 * @return string Site URL
44 */
45 public static function site_url() {
46 return site_url();
47 }
48
49 /**
50 * Get the name of this site
51 * Used for [sitename] shortcode
52 *
53 * @since 2.0
54 * @return string
55 */
56 public static function site_name() {
57 return get_option('blogname');
58 }
59
60 public static function make_affiliate_url( $url ) {
61 $affiliate_id = self::get_affiliate();
62 if ( ! empty( $affiliate_id ) ) {
63 $url = str_replace( array( 'http://', 'https://' ), '', $url );
64 $url = 'http://www.shareasale.com/r.cfm?u=' . absint( $affiliate_id ) . '&b=841990&m=64739&afftrack=plugin&urllink=' . urlencode( $url );
65 }
66 return $url;
67 }
68
69 public static function get_affiliate() {
70 return absint( apply_filters( 'frm_affiliate_id', 0 ) );
71 }
72
73 /**
74 * Get the Formidable settings
75 *
76 * @since 2.0
77 *
78 * @param None
79 * @return FrmSettings $frm_setings
80 */
81 public static function get_settings() {
82 global $frm_settings;
83 if ( empty($frm_settings) ) {
84 $frm_settings = new FrmSettings();
85 }
86 return $frm_settings;
87 }
88
89 public static function get_menu_name() {
90 $frm_settings = FrmAppHelper::get_settings();
91 return $frm_settings->menu;
92 }
93
94 /**
95 * @since 2.02.04
96 */
97 public static function ips_saved() {
98 $frm_settings = self::get_settings();
99 return ! $frm_settings->no_ips;
100 }
101
102 /**
103 * Show a message in place of pro features
104 *
105 * @since 2.0
106 */
107 public static function update_message() {
108 _deprecated_function( __FUNCTION__, '2.0.19' );
109 }
110
111 public static function pro_is_installed() {
112 return apply_filters('frm_pro_installed', false);
113 }
114
115 /**
116 * Check for certain page in Formidable settings
117 *
118 * @since 2.0
119 *
120 * @param string $page The name of the page to check
121 * @return boolean
122 */
123 public static function is_admin_page( $page = 'formidable' ) {
124 global $pagenow;
125 $get_page = self::simple_get( 'page', 'sanitize_title' );
126 if ( $pagenow ) {
127 return $pagenow == 'admin.php' && $get_page == $page;
128 }
129
130 return is_admin() && $get_page == $page;
131 }
132
133 /**
134 * Check for the form preview page
135 *
136 * @since 2.0
137 *
138 * @param None
139 * @return boolean
140 */
141 public static function is_preview_page() {
142 global $pagenow;
143 $action = FrmAppHelper::simple_get( 'action', 'sanitize_title' );
144 return $pagenow && $pagenow == 'admin-ajax.php' && $action == 'frm_forms_preview';
145 }
146
147 /**
148 * Check for ajax except the form preview page
149 *
150 * @since 2.0
151 *
152 * @param None
153 * @return boolean
154 */
155 public static function doing_ajax() {
156 return self::wp_doing_ajax() && ! self::is_preview_page();
157 }
158
159 /**
160 * Use the WP 4.7 wp_doing_ajax function
161 * @sine 2.05.07
162 */
163 public static function wp_doing_ajax() {
164 if ( function_exists( 'wp_doing_ajax' ) ) {
165 $doing_ajax = wp_doing_ajax();
166 } else {
167 $doing_ajax = defined('DOING_AJAX') && DOING_AJAX;
168 }
169 return $doing_ajax;
170 }
171
172 /**
173 * @since 2.0.8
174 */
175 public static function prevent_caching() {
176 global $frm_vars;
177 return isset( $frm_vars['prevent_caching'] ) && $frm_vars['prevent_caching'];
178 }
179
180 /**
181 * Check if on an admin page
182 *
183 * @since 2.0
184 *
185 * @param None
186 * @return boolean
187 */
188 public static function is_admin() {
189 return is_admin() && ! self::wp_doing_ajax();
190 }
191
192 /**
193 * Check if value contains blank value or empty array
194 *
195 * @since 2.0
196 * @param mixed $value - value to check
197 * @param string
198 * @return boolean
199 */
200 public static function is_empty_value( $value, $empty = '' ) {
201 return ( is_array( $value ) && empty( $value ) ) || $value == $empty;
202 }
203
204 public static function is_not_empty_value( $value, $empty = '' ) {
205 return ! self::is_empty_value( $value, $empty );
206 }
207
208 /**
209 * Get any value from the $_SERVER
210 *
211 * @since 2.0
212 * @param string $value
213 * @return string
214 */
215 public static function get_server_value( $value ) {
216 return isset( $_SERVER[ $value ] ) ? wp_strip_all_tags( $_SERVER[ $value ] ) : '';
217 }
218
219 /**
220 * Check for the IP address in several places
221 * Used by [ip] shortcode
222 *
223 * @return string The IP address of the current user
224 */
225 public static function get_ip_address() {
226 $ip = '';
227 foreach ( array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR' ) as $key ) {
228 if ( ! isset( $_SERVER[ $key ] ) ) {
229 continue;
230 }
231
232 foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) {
233 $ip = trim($ip); // just to be safe
234
235 if ( filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false ) {
236 return sanitize_text_field( $ip );
237 }
238 }
239 }
240
241 return sanitize_text_field( $ip );
242 }
243
244 public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
245 if ( strpos($param, '[') ) {
246 $params = explode('[', $param);
247 $param = $params[0];
248 }
249
250 if ( $src == 'get' ) {
251 $value = isset( $_POST[ $param ] ) ? stripslashes_deep( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? stripslashes_deep( $_GET[ $param ] ) : $default );
252 if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) {
253 $value = stripslashes_deep( htmlspecialchars_decode( $_GET[ $param ] ) );
254 }
255 self::sanitize_value( $sanitize, $value );
256 } else {
257 $value = self::get_simple_request( array(
258 'type' => $src,
259 'param' => $param,
260 'default' => $default,
261 'sanitize' => $sanitize,
262 ) );
263 }
264
265 if ( isset( $params ) && is_array( $value ) && ! empty( $value ) ) {
266 foreach ( $params as $k => $p ) {
267 if ( ! $k || ! is_array($value) ) {
268 continue;
269 }
270
271 $p = trim($p, ']');
272 $value = isset( $value[ $p ] ) ? $value[ $p ] : $default;
273 }
274 }
275
276 return $value;
277 }
278
279 public static function get_post_param( $param, $default = '', $sanitize = '' ) {
280 return self::get_simple_request( array(
281 'type' => 'post',
282 'param' => $param,
283 'default' => $default,
284 'sanitize' => $sanitize,
285 ) );
286 }
287
288 /**
289 * @since 2.0
290 *
291 * @param string $param
292 * @param string $sanitize
293 * @param string $default
294 * @return string|array
295 */
296 public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) {
297 return self::get_simple_request( array(
298 'type' => 'get',
299 'param' => $param,
300 'default' => $default,
301 'sanitize' => $sanitize,
302 ) );
303 }
304
305 /**
306 * Get a GET/POST/REQUEST value and sanitize it
307 *
308 * @since 2.0.6
309 * @param array $args
310 * @return string|array
311 */
312 public static function get_simple_request( $args ) {
313 $defaults = array(
314 'param' => '',
315 'default' => '',
316 'type' => 'get',
317 'sanitize' => 'sanitize_text_field',
318 );
319 $args = wp_parse_args( $args, $defaults );
320
321 $value = $args['default'];
322 if ( $args['type'] == 'get' ) {
323 if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
324 $value = $_GET[ $args['param'] ];
325 }
326 } else if ( $args['type'] == 'post' ) {
327 if ( isset( $_POST[ $args['param'] ] ) ) {
328 $value = stripslashes_deep( maybe_unserialize( $_POST[ $args['param'] ] ) );
329 }
330 } else {
331 if ( isset( $_REQUEST[ $args['param'] ] ) ) {
332 $value = $_REQUEST[ $args['param'] ];
333 }
334 }
335
336 self::sanitize_value( $args['sanitize'], $value );
337 return $value;
338 }
339
340 /**
341 * Preserve backslashes in a value, but make sure value doesn't get compounding slashes
342 *
343 * @since 2.0.8
344 * @param string $value
345 * @return string $value
346 */
347 public static function preserve_backslashes( $value ) {
348 // If backslashes have already been added, don't add them again
349 if ( strpos( $value, '\\\\' ) === false ) {
350 $value = addslashes( $value );
351 }
352 return $value;
353 }
354
355 public static function sanitize_value( $sanitize, &$value ) {
356 if ( ! empty( $sanitize ) ) {
357 if ( is_array( $value ) ) {
358 $temp_values = $value;
359 foreach ( $temp_values as $k => $v ) {
360 FrmAppHelper::sanitize_value( $sanitize, $value[ $k ] );
361 }
362 } else {
363 $value = call_user_func( $sanitize, $value );
364 }
365 }
366 }
367
368 public static function sanitize_request( $sanitize_method, &$values ) {
369 $temp_values = $values;
370 foreach ( $temp_values as $k => $val ) {
371 if ( isset( $sanitize_method[ $k ] ) ) {
372 $values[ $k ] = call_user_func( $sanitize_method[ $k ], $val );
373 }
374 }
375 }
376
377 public static function sanitize_array( &$values ) {
378 $temp_values = $values;
379 foreach ( $temp_values as $k => $val ) {
380 $values[ $k ] = wp_kses_post( $val );
381 }
382 }
383
384 /**
385 * Sanitize the value, and allow some HTML
386 * @since 2.0
387 * @param string $value
388 * @param array|string $allowed 'all' for everything included as defaults
389 * @return string
390 */
391 public static function kses( $value, $allowed = array() ) {
392 $allowed_html = self::allowed_html( $allowed );
393
394 return wp_kses( $value, $allowed_html );
395 }
396
397 /**
398 * @since 2.05.03
399 */
400 private static function allowed_html( $allowed ) {
401 $html = self::safe_html();
402 $allowed_html = array();
403 if ( $allowed == 'all' ) {
404 $allowed_html = $html;
405 } elseif ( ! empty( $allowed ) ) {
406 foreach ( (array) $allowed as $a ) {
407 $allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
408 }
409 }
410
411 return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
412 }
413
414 /**
415 * @since 2.05.03
416 */
417 private static function safe_html() {
418 return array(
419 'a' => array(
420 'class' => array(),
421 'href' => array(),
422 'id' => array(),
423 'rel' => array(),
424 'title' => array(),
425 ),
426 'abbr' => array(
427 'title' => array(),
428 ),
429 'b' => array(),
430 'blockquote' => array(
431 'cite' => array(),
432 ),
433 'br' => array(),
434 'cite' => array(
435 'title' => array(),
436 ),
437 'code' => array(),
438 'del' => array(
439 'datetime' => array(),
440 'title' => array(),
441 ),
442 'dd' => array(),
443 'div' => array(
444 'class' => array(),
445 'id' => array(),
446 'title' => array(),
447 'style' => array(),
448 ),
449 'dl' => array(),
450 'dt' => array(),
451 'em' => array(),
452 'h1' => array(),
453 'h2' => array(),
454 'h3' => array(),
455 'h4' => array(),
456 'h5' => array(),
457 'h6' => array(),
458 'i' => array(),
459 'img' => array(
460 'alt' => array(),
461 'class' => array(),
462 'height' => array(),
463 'id' => array(),
464 'src' => array(),
465 'width' => array(),
466 ),
467 'li' => array(
468 'class' => array(),
469 'id' => array(),
470 ),
471 'ol' => array(
472 'class' => array(),
473 'id' => array(),
474 ),
475 'p' => array(
476 'class' => array(),
477 'id' => array(),
478 ),
479 'pre' => array(),
480 'q' => array(
481 'cite' => array(),
482 'title' => array(),
483 ),
484 'span' => array(
485 'class' => array(),
486 'id' => array(),
487 'title' => array(),
488 'style' => array(),
489 ),
490 'strike' => array(),
491 'strong' => array(),
492 'ul' => array(
493 'class' => array(),
494 'id' => array(),
495 ),
496 );
497 }
498
499 /**
500 * Used when switching the action for a bulk action
501 * @since 2.0
502 */
503 public static function remove_get_action() {
504 if ( ! isset($_GET) ) {
505 return;
506 }
507
508 $new_action = isset( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : ( isset( $_GET['action2'] ) ? sanitize_text_field( $_GET['action2'] ) : '' );
509 if ( ! empty( $new_action ) ) {
510 $_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', FrmAppHelper::get_server_value( 'REQUEST_URI' ) );
511 }
512 }
513
514 /**
515 * Check the WP query for a parameter
516 *
517 * @since 2.0
518 * @return string|array
519 */
520 public static function get_query_var( $value, $param ) {
521 if ( $value != '' ) {
522 return $value;
523 }
524
525 global $wp_query;
526 if ( isset( $wp_query->query_vars[ $param ] ) ) {
527 $value = $wp_query->query_vars[ $param ];
528 }
529
530 return $value;
531 }
532
533 /**
534 * @param string $type
535 */
536 public static function trigger_hook_load( $type, $object = null ) {
537 // only load the form hooks once
538 $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
539 if ( ! $hooks_loaded ) {
540 do_action( 'frm_load_' . $type . '_hooks' );
541 }
542 }
543
544 /**
545 * Check a value from a shortcode to see if true or false.
546 * True when value is 1, true, 'true', 'yes'
547 *
548 * @since 1.07.10
549 *
550 * @param string $value The value to compare
551 * @return boolean True or False
552 */
553 public static function is_true( $value ) {
554 return ( true === $value || 1 == $value || 'true' == $value || 'yes' == $value );
555 }
556
557 /**
558 * Used to filter shortcode in text widgets
559 */
560 public static function widget_text_filter_callback( $matches ) {
561 _deprecated_function( __METHOD__, '2.5.4' );
562 return do_shortcode( $matches[0] );
563 }
564
565 public static function get_pages() {
566 return get_posts( array(
567 'post_type' => 'page',
568 'post_status' => array( 'publish', 'private' ),
569 'numberposts' => -1,
570 'orderby' => 'title',
571 'order' => 'ASC',
572 ) );
573 }
574
575 public static function wp_pages_dropdown( $field_name, $page_id, $truncate = false ) {
576 $pages = self::get_pages();
577 $selected = self::get_post_param( $field_name, $page_id, 'absint' );
578 ?>
579 <select name="<?php echo esc_attr($field_name); ?>" id="<?php echo esc_attr($field_name); ?>" class="frm-pages-dropdown">
580 <option value=""> </option>
581 <?php foreach ( $pages as $page ) { ?>
582 <option value="<?php echo esc_attr($page->ID); ?>" <?php selected( $selected, $page->ID ) ?>>
583 <?php echo esc_html( $truncate ? self::truncate( $page->post_title, $truncate ) : $page->post_title ); ?>
584 </option>
585 <?php } ?>
586 </select>
587 <?php
588 }
589
590 public static function post_edit_link( $post_id ) {
591 $post = get_post($post_id);
592 if ( $post ) {
593 $post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
594 return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
595 }
596 return '';
597 }
598
599 public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
600 ?>
601 <select name="<?php echo esc_attr($field_name); ?>" id="<?php echo esc_attr($field_name); ?>" <?php echo ( 'multiple' === $multiple ) ? 'multiple="multiple"' : ''; ?> class="frm_multiselect">
602 <?php self::roles_options( $capability ); ?>
603 </select>
604 <?php
605 }
606
607 public static function roles_options( $capability ) {
608 global $frm_vars;
609 if ( isset($frm_vars['editable_roles']) ) {
610 $editable_roles = $frm_vars['editable_roles'];
611 } else {
612 $editable_roles = get_editable_roles();
613 $frm_vars['editable_roles'] = $editable_roles;
614 }
615
616 foreach ( $editable_roles as $role => $details ) {
617 $name = translate_user_role( $details['name'] );
618 ?>
619 <option value="<?php echo esc_attr($role) ?>" <?php echo in_array($role, (array) $capability) ? ' selected="selected"' : ''; ?>><?php echo esc_attr($name) ?> </option>
620 <?php
621 unset($role, $details);
622 }
623 }
624
625 public static function frm_capabilities( $type = 'auto' ) {
626 $cap = array(
627 'frm_view_forms' => __( 'View Forms and Templates', 'formidable' ),
628 'frm_edit_forms' => __( 'Add/Edit Forms and Templates', 'formidable' ),
629 'frm_delete_forms' => __( 'Delete Forms and Templates', 'formidable' ),
630 'frm_change_settings' => __( 'Access this Settings Page', 'formidable' ),
631 'frm_view_entries' => __( 'View Entries from Admin Area', 'formidable' ),
632 'frm_delete_entries' => __( 'Delete Entries from Admin Area', 'formidable' ),
633 );
634
635 if ( ! self::pro_is_installed() && 'pro' != $type ) {
636 return $cap;
637 }
638
639 $cap['frm_create_entries'] = __( 'Add Entries from Admin Area', 'formidable' );
640 $cap['frm_edit_entries'] = __( 'Edit Entries from Admin Area', 'formidable' );
641 $cap['frm_view_reports'] = __( 'View Reports', 'formidable' );
642 $cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
643
644 return $cap;
645 }
646
647 public static function user_has_permission( $needed_role ) {
648 if ( $needed_role == '-1' ) {
649 return false;
650 }
651
652 // $needed_role will be equal to blank if "Logged-in users" is selected
653 if ( ( $needed_role == '' && is_user_logged_in() ) || current_user_can( $needed_role ) ) {
654 return true;
655 }
656
657 $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
658 foreach ( $roles as $role ) {
659 if ( current_user_can( $role ) ) {
660 return true;
661 }
662 if ( $role == $needed_role ) {
663 break;
664 }
665 }
666 return false;
667 }
668
669 /**
670 * Make sure administrators can see Formidable menu
671 *
672 * @since 2.0
673 */
674 public static function maybe_add_permissions() {
675 self::force_capability( 'frm_view_entries' );
676
677 if ( ! current_user_can('administrator') || current_user_can('frm_view_forms') ) {
678 return;
679 }
680
681 $user_id = get_current_user_id();
682 $user = new WP_User( $user_id );
683 $frm_roles = self::frm_capabilities();
684 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
685 $user->add_cap( $frm_role );
686 unset($frm_role, $frm_role_description);
687 }
688 }
689
690 /**
691 * Make sure admins have permission to see the menu items
692 * @since 2.0.6
693 */
694 public static function force_capability( $cap = 'frm_change_settings' ) {
695 if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
696 $role = get_role( 'administrator' );
697 $frm_roles = self::frm_capabilities();
698 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
699 $role->add_cap( $frm_role );
700 }
701 }
702 }
703
704 /**
705 * Check if the user has permision for action.
706 * Return permission message and stop the action if no permission
707 * @since 2.0
708 * @param string $permission
709 */
710 public static function permission_check( $permission, $show_message = 'show' ) {
711 $permission_error = self::permission_nonce_error($permission);
712 if ( $permission_error !== false ) {
713 if ( 'hide' == $show_message ) {
714 $permission_error = '';
715 }
716 wp_die($permission_error);
717 }
718 }
719
720 /**
721 * Check user permission and nonce
722 * @since 2.0
723 * @param string $permission
724 * @return false|string The permission message or false if allowed
725 */
726 public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
727 if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
728 $frm_settings = self::get_settings();
729 return $frm_settings->admin_permission;
730 }
731
732 $error = false;
733 if ( empty($nonce_name) ) {
734 return $error;
735 }
736
737 if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $_REQUEST[ $nonce_name ], $nonce ) ) ) {
738 $frm_settings = self::get_settings();
739 $error = $frm_settings->admin_permission;
740 }
741
742 return $error;
743 }
744
745 public static function checked( $values, $current ) {
746 if ( self::check_selected( $values, $current ) ) {
747 echo ' checked="checked"';
748 }
749 }
750
751 public static function check_selected( $values, $current ) {
752 $values = self::recursive_function_map( $values, 'trim' );
753 $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
754 $current = htmlspecialchars_decode( trim( $current ) );
755
756 return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
757 }
758
759 /**
760 * Check if current field option is an "other" option
761 *
762 * @since 2.0
763 *
764 * @param string $opt_key
765 * @return boolean Returns true if current field option is an "Other" option
766 */
767 public static function is_other_opt( $opt_key ) {
768 _deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::is_other_opt' );
769 return FrmFieldsHelper::is_other_opt( $opt_key );
770 }
771
772 /**
773 * Get value that belongs in "Other" text box
774 *
775 * @since 2.0
776 *
777 * @param string $opt_key
778 * @param array $field
779 * @return string $other_val
780 */
781 public static function get_other_val( $opt_key, $field, $parent = false, $pointer = false ) {
782 _deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::get_other_val' );
783 return FrmFieldsHelper::get_other_val( compact( 'opt_key', 'field', 'parent', 'pointer' ) );
784 }
785
786 /**
787 * Check if there is a saved value for the "Other" text field. If so, set it as the $other_val.
788 * Intended for front-end use
789 *
790 * @since 2.0
791 *
792 * @param array $field
793 * @param boolean $other_opt
794 * @param string $checked
795 * @param array $args should include opt_key and field name
796 * @return string $other_val
797 */
798 public static function prepare_other_input( $field, &$other_opt, &$checked, $args = array() ) {
799 _deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::prepare_other_input' );
800 $args['field'] = $field;
801 return FrmFieldsHelper::prepare_other_input( $args, $other_opt, $checked );
802 }
803
804 public static function recursive_function_map( $value, $function ) {
805 if ( is_array( $value ) ) {
806 $original_function = $function;
807 if ( count( $value ) ) {
808 $function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
809 } else {
810 $function = array( $function );
811 }
812 if ( ! self::is_assoc( $value ) ) {
813 $value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
814 } else {
815 foreach ( $value as $k => $v ) {
816 if ( ! is_array( $v ) ) {
817 $value[ $k ] = call_user_func( $original_function, $v );
818 }
819 }
820 }
821 } else {
822 $value = call_user_func( $function, $value );
823 }
824
825 return $value;
826 }
827
828 public static function is_assoc( $array ) {
829 return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
830 }
831
832 /**
833 * Flatten a multi-dimensional array
834 */
835 public static function array_flatten( $array, $keys = 'keep' ) {
836 $return = array();
837 foreach ( $array as $key => $value ) {
838 if ( is_array($value) ) {
839 $return = array_merge( $return, self::array_flatten( $value, $keys ) );
840 } else {
841 if ( $keys == 'keep' ) {
842 $return[ $key ] = $value;
843 } else {
844 $return[] = $value;
845 }
846 }
847 }
848 return $return;
849 }
850
851 public static function esc_textarea( $text, $is_rich_text = false ) {
852 $safe_text = str_replace( '&quot;', '"', $text );
853 if ( ! $is_rich_text ) {
854 $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
855 }
856 $safe_text = str_replace( '&amp;', '&', $safe_text );
857 return apply_filters( 'esc_textarea', $safe_text, $text );
858 }
859
860 /**
861 * Add auto paragraphs to text areas
862 * @since 2.0
863 */
864 public static function use_wpautop( $content ) {
865 if ( apply_filters('frm_use_wpautop', true) ) {
866 $content = wpautop(str_replace( '<br>', '<br />', $content));
867 }
868 return $content;
869 }
870
871 public static function replace_quotes( $val ) {
872 //Replace double quotes
873 $val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
874 //Replace single quotes
875 $val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
876 return $val;
877 }
878
879 /**
880 * @since 2.0
881 * @return string The base Google APIS url for the current version of jQuery UI
882 */
883 public static function jquery_ui_base_url() {
884 $url = 'http' . ( is_ssl() ? 's' : '' ) . '://ajax.googleapis.com/ajax/libs/jqueryui/' . self::script_version( 'jquery-ui-core', '1.11.4' );
885 $url = apply_filters('frm_jquery_ui_base_url', $url);
886 return $url;
887 }
888
889 /**
890 * @param string $handle
891 */
892 public static function script_version( $handle, $default = 0 ) {
893 global $wp_scripts;
894 if ( ! $wp_scripts ) {
895 return $default;
896 }
897
898 $ver = $default;
899 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
900 return $ver;
901 }
902
903 $query = $wp_scripts->registered[ $handle ];
904 if ( is_object( $query ) && ! empty( $query->ver ) ) {
905 $ver = $query->ver;
906 }
907
908 return $ver;
909 }
910
911 public static function js_redirect( $url ) {
912 return '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>';
913 }
914
915 public static function get_user_id_param( $user_id ) {
916 if ( ! $user_id || empty($user_id) || is_numeric($user_id) ) {
917 return $user_id;
918 }
919
920 $user_id = sanitize_text_field( $user_id );
921 if ( $user_id == 'current' ) {
922 $user_id = get_current_user_id();
923 } else {
924 if ( is_email($user_id) ) {
925 $user = get_user_by('email', $user_id);
926 } else {
927 $user = get_user_by('login', $user_id);
928 }
929
930 if ( $user ) {
931 $user_id = $user->ID;
932 }
933 unset($user);
934 }
935
936 return $user_id;
937 }
938
939 public static function get_file_contents( $filename, $atts = array() ) {
940 if ( ! is_file($filename) ) {
941 return false;
942 }
943
944 extract($atts);
945 ob_start();
946 include($filename);
947 $contents = ob_get_contents();
948 ob_end_clean();
949 return $contents;
950 }
951
952 /**
953 * @param string $table_name
954 * @param string $column
955 * @param int $id
956 * @param int $num_chars
957 */
958 public static function get_unique_key( $name = '', $table_name, $column, $id = 0, $num_chars = 5 ) {
959 $key = '';
960
961 if ( ! empty( $name ) ) {
962 $key = sanitize_key($name);
963 }
964
965 if ( empty( $key ) ) {
966 $max_slug_value = pow(36, $num_chars);
967 $min_slug_value = 37; // we want to have at least 2 characters in the slug
968 $key = base_convert( rand($min_slug_value, $max_slug_value), 10, 36 );
969 }
970
971 if ( is_numeric($key) || in_array( $key, array( 'id', 'key', 'created-at', 'detaillink', 'editlink', 'siteurl', 'evenodd' ) ) ) {
972 $key = $key . 'a';
973 }
974
975 $key_check = FrmDb::get_var( $table_name, array(
976 $column => $key,
977 'ID !' => $id,
978 ), $column );
979
980 if ( $key_check || is_numeric($key_check) ) {
981 $suffix = 2;
982 do {
983 $alt_post_name = substr( $key, 0, 200 - ( strlen( $suffix ) + 1 ) ) . $suffix;
984 $key_check = FrmDb::get_var( $table_name, array(
985 $column => $alt_post_name,
986 'ID !' => $id,
987 ), $column );
988 $suffix++;
989 } while ( $key_check || is_numeric( $key_check ) );
990 $key = $alt_post_name;
991 }
992 return $key;
993 }
994
995 /**
996 * Editing a Form or Entry
997 * @param string $table
998 * @return bool|array
999 */
1000 public static function setup_edit_vars( $record, $table, $fields = '', $default = false, $post_values = array(), $args = array() ) {
1001 if ( ! $record ) {
1002 return false;
1003 }
1004
1005 if ( empty($post_values) ) {
1006 $post_values = stripslashes_deep($_POST);
1007 }
1008
1009 $values = array(
1010 'id' => $record->id,
1011 'fields' => array(),
1012 );
1013
1014 foreach ( array( 'name', 'description' ) as $var ) {
1015 $default_val = isset($record->{$var}) ? $record->{$var} : '';
1016 $values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
1017 unset($var, $default_val);
1018 }
1019
1020 $values['description'] = self::use_wpautop($values['description']);
1021 $frm_settings = self::get_settings();
1022 $is_form_builder = self::is_admin_page('formidable' );
1023
1024 foreach ( (array) $fields as $field ) {
1025 // Make sure to filter default values (for placeholder text), but not on the form builder page
1026 if ( ! $is_form_builder ) {
1027 $field->default_value = apply_filters('frm_get_default_value', $field->default_value, $field, true );
1028 }
1029 $parent_form_id = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
1030 self::fill_field_defaults($field, $record, $values, compact('default', 'post_values', 'frm_settings', 'parent_form_id' ) );
1031 }
1032
1033 self::fill_form_opts($record, $table, $post_values, $values);
1034
1035 if ( $table == 'entries' ) {
1036 $values = FrmEntriesHelper::setup_edit_vars( $values, $record );
1037 } else if ( $table == 'forms' ) {
1038 $values = FrmFormsHelper::setup_edit_vars( $values, $record, $post_values );
1039 }
1040
1041 return $values;
1042 }
1043
1044 private static function fill_field_defaults( $field, $record, array &$values, $args ) {
1045 $post_values = $args['post_values'];
1046
1047 if ( $args['default'] ) {
1048 $meta_value = $field->default_value;
1049 } else {
1050 if ( $record->post_id && self::pro_is_installed() && isset($field->field_options['post_field']) && $field->field_options['post_field'] ) {
1051 if ( ! isset($field->field_options['custom_field']) ) {
1052 $field->field_options['custom_field'] = '';
1053 }
1054 $meta_value = FrmProEntryMetaHelper::get_post_value( $record->post_id, $field->field_options['post_field'], $field->field_options['custom_field'], array(
1055 'truncate' => false,
1056 'type' => $field->type,
1057 'form_id' => $field->form_id,
1058 'field' => $field,
1059 ) );
1060 } else {
1061 $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
1062 }
1063 }
1064
1065 $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
1066 $new_value = isset( $post_values['item_meta'][ $field->id ] ) ? maybe_unserialize( $post_values['item_meta'][ $field->id ] ) : $meta_value;
1067
1068 $field_array = array(
1069 'id' => $field->id,
1070 'value' => $new_value,
1071 'default_value' => $field->default_value,
1072 'name' => $field->name,
1073 'description' => $field->description,
1074 'type' => apply_filters('frm_field_type', $field_type, $field, $new_value),
1075 'options' => $field->options,
1076 'required' => $field->required,
1077 'field_key' => $field->field_key,
1078 'field_order' => $field->field_order,
1079 'form_id' => $field->form_id,
1080 'parent_form_id' => $args['parent_form_id'],
1081 );
1082
1083 $args['field_type'] = $field_type;
1084 self::fill_field_opts($field, $field_array, $args);
1085 // Track the original field's type
1086 $field_array['original_type'] = isset( $field->field_options['original_type'] ) ? $field->field_options['original_type'] : $field->type;
1087
1088 $field_array = apply_filters( 'frm_setup_edit_fields_vars', $field_array, $field, $values['id'], array() );
1089
1090 if ( ! isset($field_array['unique']) || ! $field_array['unique'] ) {
1091 $field_array['unique_msg'] = '';
1092 }
1093
1094 $field_array = array_merge( $field->field_options, $field_array );
1095
1096 $values['fields'][ $field->id ] = $field_array;
1097 }
1098
1099 private static function fill_field_opts( $field, array &$field_array, $args ) {
1100 $post_values = $args['post_values'];
1101 $opt_defaults = FrmFieldsHelper::get_default_field_opts($field_array['type'], $field, true);
1102
1103 foreach ( $opt_defaults as $opt => $default_opt ) {
1104 $field_array[ $opt ] = ( $post_values && isset( $post_values['field_options'][ $opt . '_' . $field->id ] ) ) ? maybe_unserialize( $post_values['field_options'][ $opt . '_' . $field->id ] ) : ( isset( $field->field_options[ $opt ] ) ? $field->field_options[ $opt ] : $default_opt );
1105 if ( $opt == 'blank' && $field_array[ $opt ] == '' ) {
1106 $field_array[ $opt ] = $args['frm_settings']->blank_msg;
1107 } else if ( $opt == 'invalid' && $field_array[ $opt ] == '' ) {
1108 if ( $args['field_type'] == 'captcha' ) {
1109 $field_array[ $opt ] = $args['frm_settings']->re_msg;
1110 } else {
1111 $field_array[ $opt ] = sprintf( __( '%s is invalid', 'formidable' ), $field_array['name'] );
1112 }
1113 }
1114 }
1115
1116 if ( $field_array['custom_html'] == '' ) {
1117 $field_array['custom_html'] = FrmFieldsHelper::get_default_html($args['field_type']);
1118 }
1119 }
1120
1121 /**
1122 * @param string $table
1123 */
1124 private static function fill_form_opts( $record, $table, $post_values, array &$values ) {
1125 if ( $table == 'entries' ) {
1126 $form = $record->form_id;
1127 FrmForm::maybe_get_form( $form );
1128 } else {
1129 $form = $record;
1130 }
1131
1132 if ( ! $form ) {
1133 return;
1134 }
1135
1136 $values['form_name'] = isset($record->form_id) ? $form->name : '';
1137 $values['parent_form_id'] = isset( $record->form_id ) ? $form->parent_form_id : 0;
1138
1139 if ( ! is_array($form->options) ) {
1140 return;
1141 }
1142
1143 foreach ( $form->options as $opt => $value ) {
1144 $values[ $opt ] = isset( $post_values[ $opt ] ) ? maybe_unserialize( $post_values[ $opt ] ) : $value;
1145 }
1146
1147 self::fill_form_defaults($post_values, $values);
1148 }
1149
1150 /**
1151 * Set to POST value or default
1152 */
1153 private static function fill_form_defaults( $post_values, array &$values ) {
1154 $form_defaults = FrmFormsHelper::get_default_opts();
1155
1156 foreach ( $form_defaults as $opt => $default ) {
1157 if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
1158 $values[ $opt ] = ( $post_values && isset( $post_values['options'][ $opt ] ) ) ? $post_values['options'][ $opt ] : $default;
1159 }
1160
1161 unset($opt, $defaut);
1162 }
1163
1164 if ( ! isset( $values['custom_style'] ) ) {
1165 $values['custom_style'] = self::custom_style_value( $post_values );
1166 }
1167
1168 foreach ( array( 'before', 'after', 'submit' ) as $h ) {
1169 if ( ! isset( $values[ $h . '_html' ] ) ) {
1170 $values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
1171 }
1172 unset($h);
1173 }
1174 }
1175
1176 /**
1177 * @since 2.2.10
1178 * @param array $post_values
1179 * @return boolean|int
1180 */
1181 public static function custom_style_value( $post_values ) {
1182 if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
1183 $custom_style = absint( $post_values['options']['custom_style'] );
1184 } else {
1185 $frm_settings = FrmAppHelper::get_settings();
1186 $custom_style = ( $frm_settings->load_style != 'none' );
1187 }
1188 return $custom_style;
1189 }
1190
1191 public static function get_meta_value( $field_id, $entry ) {
1192 _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryMeta::get_meta_value' );
1193 return FrmEntryMeta::get_meta_value( $entry, $field_id );
1194 }
1195
1196 public static function insert_opt_html( $args ) {
1197 $class = '';
1198 if ( in_array( $args['type'], array( 'email', 'user_id', 'hidden', 'select', 'radio', 'checkbox', 'phone', 'text' ) ) ) {
1199 $class .= 'show_frm_not_email_to';
1200 }
1201 ?>
1202 <li>
1203 <a href="javascript:void(0)" class="frmids frm_insert_code alignright <?php echo esc_attr($class) ?>" data-code="<?php echo esc_attr($args['id']) ?>" >[<?php echo esc_attr( $args['id'] ) ?>]</a>
1204 <a href="javascript:void(0)" class="frmkeys frm_insert_code alignright <?php echo esc_attr($class) ?>" data-code="<?php echo esc_attr($args['key']) ?>" >[<?php echo esc_attr( self::truncate($args['key'], 10) ) ?>]</a>
1205 <a href="javascript:void(0)" class="frm_insert_code <?php echo esc_attr( $class ) ?>" data-code="<?php echo esc_attr($args['id']) ?>" ><?php echo esc_attr( self::truncate($args['name'], 60) ) ?></a>
1206 </li>
1207 <?php
1208 }
1209
1210 public static function truncate( $str, $length, $minword = 3, $continue = '...' ) {
1211 if ( is_array( $str ) ) {
1212 return '';
1213 }
1214
1215 $length = (int) $length;
1216 $str = wp_strip_all_tags( $str );
1217 $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
1218
1219 if ( $length == 0 ) {
1220 return '';
1221 } else if ( $length <= 10 ) {
1222 $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
1223 return $sub . ( ( $length < $original_len ) ? $continue : '' );
1224 }
1225
1226 $sub = '';
1227 $len = 0;
1228
1229 $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
1230
1231 foreach ( $words as $word ) {
1232 $part = ( ( $sub != '' ) ? ' ' : '' ) . $word;
1233 $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
1234 if ( $total_len > $length && str_word_count($sub) ) {
1235 break;
1236 }
1237
1238 $sub .= $part;
1239 $len += self::mb_function( array( 'mb_strlen', 'strlen' ), array( $part ) );
1240
1241 if ( str_word_count($sub) > $minword && $total_len >= $length ) {
1242 break;
1243 }
1244
1245 unset($total_len, $word);
1246 }
1247
1248 return $sub . ( ( $len < $original_len ) ? $continue : '' );
1249 }
1250
1251 public static function mb_function( $function_names, $args ) {
1252 $mb_function_name = $function_names[0];
1253 $function_name = $function_names[1];
1254 if ( function_exists( $mb_function_name ) ) {
1255 $function_name = $mb_function_name;
1256 }
1257 return call_user_func_array( $function_name, $args );
1258 }
1259
1260 public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
1261 if ( empty($date) ) {
1262 return $date;
1263 }
1264
1265 if ( empty($date_format) ) {
1266 $date_format = get_option('date_format');
1267 }
1268
1269 if ( preg_match('/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date) && self::pro_is_installed() ) {
1270 $frmpro_settings = new FrmProSettings();
1271 $date = FrmProAppHelper::convert_date($date, $frmpro_settings->date_format, 'Y-m-d');
1272 }
1273
1274 $formatted = self::get_localized_date( $date_format, $date );
1275
1276 $do_time = ( date( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
1277 if ( $do_time ) {
1278 $formatted .= self::add_time_to_date( $time_format, $date );
1279 }
1280
1281 return $formatted;
1282 }
1283
1284 private static function add_time_to_date( $time_format, $date ) {
1285 if ( empty( $time_format ) ) {
1286 $time_format = get_option('time_format');
1287 }
1288
1289 $trimmed_format = trim( $time_format );
1290 $time = '';
1291 if ( $time_format && ! empty( $trimmed_format ) ) {
1292 $time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
1293 }
1294
1295 return $time;
1296 }
1297
1298 /**
1299 * @since 2.0.8
1300 */
1301 public static function get_localized_date( $date_format, $date ) {
1302 $date = get_date_from_gmt( $date );
1303 return date_i18n( $date_format, strtotime( $date ) );
1304 }
1305
1306 /**
1307 * Gets the time ago in words
1308 *
1309 * @param int $from in seconds
1310 * @param int|string $to in seconds
1311 * @return string $time_ago
1312 */
1313 public static function human_time_diff( $from, $to = '', $levels = 1 ) {
1314 if ( empty( $to ) ) {
1315 $now = new DateTime;
1316 } else {
1317 $now = new DateTime( '@' . $to );
1318 }
1319 $ago = new DateTime( '@' . $from );
1320
1321 // Get the time difference
1322 $diff_object = $now->diff( $ago );
1323 $diff = get_object_vars( $diff_object );
1324
1325 // Add week amount and update day amount
1326 $diff['w'] = floor( $diff['d'] / 7 );
1327 $diff['d'] -= $diff['w'] * 7;
1328
1329 $time_strings = self::get_time_strings();
1330
1331 foreach ( $time_strings as $k => $v ) {
1332 if ( $diff[ $k ] ) {
1333 $time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
1334 } else {
1335 unset( $time_strings[ $k ] );
1336 }
1337 }
1338
1339 $levels_deep = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
1340 $time_strings = array_slice( $time_strings, 0, $levels_deep );
1341 $time_ago_string = $time_strings ? implode( ' ', $time_strings ) : '0 ' . __( 'seconds', 'formidable' );
1342
1343 return $time_ago_string;
1344 }
1345
1346 /**
1347 * Get the translatable time strings
1348 *
1349 * @since 2.0.20
1350 * @return array
1351 */
1352 private static function get_time_strings() {
1353 return array(
1354 'y' => array( __( 'year', 'formidable' ), __( 'years', 'formidable' ) ),
1355 'm' => array( __( 'month', 'formidable' ), __( 'months', 'formidable' ) ),
1356 'w' => array( __( 'week', 'formidable' ), __( 'weeks', 'formidable' ) ),
1357 'd' => array( __( 'day', 'formidable' ), __( 'days', 'formidable' ) ),
1358 'h' => array( __( 'hour', 'formidable' ), __( 'hours', 'formidable' ) ),
1359 'i' => array( __( 'minute', 'formidable' ), __( 'minutes', 'formidable' ) ),
1360 's' => array( __( 'second', 'formidable' ), __( 'seconds', 'formidable' ) ),
1361 );
1362 }
1363
1364 // Pagination Methods
1365
1366 /**
1367 * @param integer $current_p
1368 */
1369 public static function get_last_record_num( $r_count, $current_p, $p_size ) {
1370 return ( ( $r_count < ( $current_p * $p_size ) ) ? $r_count : ( $current_p * $p_size ) );
1371 }
1372
1373 /**
1374 * @param integer $current_p
1375 */
1376 public static function get_first_record_num( $r_count, $current_p, $p_size ) {
1377 if ( $current_p == 1 ) {
1378 return 1;
1379 } else {
1380 return ( self::get_last_record_num( $r_count, ( $current_p - 1 ), $p_size ) + 1 );
1381 }
1382 }
1383
1384 /**
1385 * @return array
1386 */
1387 public static function json_to_array( $json_vars ) {
1388 $vars = array();
1389 foreach ( $json_vars as $jv ) {
1390 $jv_name = explode('[', $jv['name']);
1391 $last = count($jv_name) - 1;
1392 foreach ( $jv_name as $p => $n ) {
1393 $name = trim($n, ']');
1394 if ( ! isset($l1) ) {
1395 $l1 = $name;
1396 }
1397
1398 if ( ! isset($l2) ) {
1399 $l2 = $name;
1400 }
1401
1402 if ( ! isset($l3) ) {
1403 $l3 = $name;
1404 }
1405
1406 $this_val = ( $p == $last ) ? $jv['value'] : array();
1407
1408 switch ( $p ) {
1409 case 0:
1410 $l1 = $name;
1411 self::add_value_to_array( $name, $l1, $this_val, $vars );
1412 break;
1413
1414 case 1:
1415 $l2 = $name;
1416 self::add_value_to_array( $name, $l2, $this_val, $vars[ $l1 ] );
1417 break;
1418
1419 case 2:
1420 $l3 = $name;
1421 self::add_value_to_array( $name, $l3, $this_val, $vars[ $l1 ][ $l2 ] );
1422 break;
1423
1424 case 3:
1425 $l4 = $name;
1426 self::add_value_to_array( $name, $l4, $this_val, $vars[ $l1 ][ $l2 ][ $l3 ] );
1427 }
1428
1429 unset($this_val, $n);
1430 }
1431
1432 unset($last, $jv);
1433 }
1434
1435 return $vars;
1436 }
1437
1438 /**
1439 * @param string $name
1440 * @param string $l1
1441 */
1442 public static function add_value_to_array( $name, $l1, $val, &$vars ) {
1443 if ( $name == '' ) {
1444 $vars[] = $val;
1445 } else if ( ! isset( $vars[ $l1 ] ) ) {
1446 $vars[ $l1 ] = $val;
1447 }
1448 }
1449
1450 public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
1451 $tooltips = array(
1452 'action_title' => __( 'Give this action a label for easy reference.', 'formidable' ),
1453 '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' ),
1454 'cc' => __( 'Add CC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
1455 'bcc' => __( 'Add BCC addresses separated by a ",". FORMAT: Name <name@email.com> or name@email.com.', 'formidable' ),
1456 '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' ),
1457 'from' => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <john@example.com> or john@example.com.', 'formidable' ),
1458 '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() ) ),
1459 );
1460
1461 if ( ! isset( $tooltips[ $name ] ) ) {
1462 return;
1463 }
1464
1465 if ( 'open' == $class ) {
1466 echo ' frm_help"';
1467 } else {
1468 echo ' class="frm_help"';
1469 }
1470
1471 echo ' title="' . esc_attr( $tooltips[ $name ] );
1472
1473 if ( 'open' != $class ) {
1474 echo '"';
1475 }
1476 }
1477
1478 /**
1479 * Add the current_page class to that page in the form nav
1480 */
1481 public static function select_current_page( $page, $current_page, $action = array() ) {
1482 if ( $current_page != $page ) {
1483 return;
1484 }
1485
1486 $frm_action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
1487 if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
1488 echo ' class="current_page"';
1489 }
1490 }
1491
1492 /**
1493 * Prepare and json_encode post content
1494 *
1495 * @since 2.0
1496 *
1497 * @param array $post_content
1498 * @return string $post_content ( json encoded array )
1499 */
1500 public static function prepare_and_encode( $post_content ) {
1501 //Loop through array to strip slashes and add only the needed ones
1502 foreach ( $post_content as $key => $val ) {
1503 // Replace problematic characters (like &quot;)
1504 $val = str_replace( '&quot;', '"', $val );
1505
1506 self::prepare_action_slashes( $val, $key, $post_content );
1507 unset( $key, $val );
1508 }
1509
1510 // json_encode the array
1511 $post_content = json_encode( $post_content );
1512
1513 // add extra slashes for \r\n since WP strips them
1514 $post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
1515
1516 // allow for &quot
1517 $post_content = str_replace( '&quot;', '\\"', $post_content );
1518
1519 return $post_content;
1520 }
1521
1522 private static function prepare_action_slashes( $val, $key, &$post_content ) {
1523 if ( ! isset( $post_content[ $key ] ) ) {
1524 return;
1525 }
1526
1527 if ( is_array( $val ) ) {
1528 foreach ( $val as $k1 => $v1 ) {
1529 self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
1530 unset( $k1, $v1 );
1531 }
1532 } else {
1533 // Strip all slashes so everything is the same, no matter where the value is coming from
1534 $val = stripslashes( $val );
1535
1536 // Add backslashes before double quotes and forward slashes only
1537 $post_content[ $key ] = addcslashes( $val, '"\\/' );
1538 }
1539 }
1540
1541 public static function maybe_json_decode( $string ) {
1542 if ( is_array($string) ) {
1543 return $string;
1544 }
1545
1546 $new_string = json_decode($string, true);
1547 if ( function_exists('json_last_error') ) {
1548 // php 5.3+
1549 if ( json_last_error() == JSON_ERROR_NONE ) {
1550 $string = $new_string;
1551 }
1552 } else if ( isset($new_string) ) {
1553 // php < 5.3 fallback
1554 $string = $new_string;
1555 }
1556 return $string;
1557 }
1558
1559 /**
1560 * @since 1.07.10
1561 *
1562 * @param string $post_type The name of the post type that may need to be highlighted
1563 * echo The javascript to open and highlight the Formidable menu
1564 */
1565 public static function maybe_highlight_menu( $post_type ) {
1566 global $post;
1567
1568 if ( isset($_REQUEST['post_type']) && $_REQUEST['post_type'] != $post_type ) {
1569 return;
1570 }
1571
1572 if ( is_object($post) && $post->post_type != $post_type ) {
1573 return;
1574 }
1575
1576 self::load_admin_wide_js();
1577 echo '<script type="text/javascript">jQuery(document).ready(function(){frmSelectSubnav();});</script>';
1578 }
1579
1580 /**
1581 * Load the JS file on non-Formidable pages in the admin area
1582 * @since 2.0
1583 */
1584 public static function load_admin_wide_js( $load = true ) {
1585 $version = FrmAppHelper::plugin_version();
1586 wp_register_script( 'formidable_admin_global', FrmAppHelper::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
1587
1588 wp_localize_script( 'formidable_admin_global', 'frmGlobal', array(
1589 'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
1590 'deauthorize' => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
1591 'url' => FrmAppHelper::plugin_url(),
1592 'loading' => __( 'Loading&hellip;' ),
1593 'nonce' => wp_create_nonce( 'frm_ajax' ),
1594 ) );
1595
1596 if ( $load ) {
1597 wp_enqueue_script( 'formidable_admin_global' );
1598 }
1599 }
1600
1601 /**
1602 * @since 2.0.9
1603 */
1604 public static function load_font_style() {
1605 wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
1606 }
1607
1608 /**
1609 * @param string $location
1610 */
1611 public static function localize_script( $location ) {
1612 $ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
1613 $ajax_url = apply_filters( 'frm_ajax_url', $ajax_url );
1614
1615 wp_localize_script( 'formidable', 'frm_js', array(
1616 'ajax_url' => $ajax_url,
1617 'images_url' => self::plugin_url() . '/images',
1618 'loading' => __( 'Loading&hellip;' ),
1619 'remove' => __( 'Remove', 'formidable' ),
1620 'offset' => apply_filters( 'frm_scroll_offset', 4 ),
1621 'nonce' => wp_create_nonce( 'frm_ajax' ),
1622 'id' => __( 'ID', 'formidable' ),
1623 'no_results' => __( 'No results match', 'formidable' ),
1624 'file_spam' => __( 'That file looks like Spam.', 'formidable' ),
1625 'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ),
1626 ) );
1627
1628 if ( $location == 'admin' ) {
1629 $frm_settings = self::get_settings();
1630 wp_localize_script( 'formidable_admin', 'frm_admin_js', array(
1631 'confirm_uninstall' => __( 'Are you sure you want to do this? Clicking OK will delete all forms, form data, and all other Formidable data. There is no Undo.', 'formidable' ),
1632 'desc' => __( '(Click to add description)', 'formidable' ),
1633 'blank' => __( '(Blank)', 'formidable' ),
1634 'no_label' => __( '(no label)', 'formidable' ),
1635 'saving' => esc_attr( __( 'Saving', 'formidable' ) ),
1636 'saved' => esc_attr( __( 'Saved', 'formidable' ) ),
1637 'ok' => __( 'OK' ),
1638 'cancel' => __( 'Cancel', 'formidable' ),
1639 'default' => __( 'Default', 'formidable' ),
1640 'clear_default' => __( 'Clear default value when typing', 'formidable' ),
1641 'no_clear_default' => __( 'Do not clear default value when typing', 'formidable' ),
1642 'valid_default' => __( 'Default value will pass form validation', 'formidable' ),
1643 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ),
1644 'confirm' => __( 'Are you sure?', 'formidable' ),
1645 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
1646 'conf_delete_sec' => __( 'WARNING: This will delete all fields inside of the section as well.', 'formidable' ),
1647 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
1648 'default_unique' => $frm_settings->unique_msg,
1649 'default_conf' => __( 'The entered values do not match', 'formidable' ),
1650 'enter_email' => __( 'Enter Email', 'formidable' ),
1651 'confirm_email' => __( 'Confirm Email', 'formidable' ),
1652 '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' ),
1653 'enter_password' => __( 'Enter Password', 'formidable' ),
1654 'confirm_password' => __( 'Confirm Password', 'formidable' ),
1655 'import_complete' => __( 'Import Complete', 'formidable' ),
1656 'updating' => __( 'Please wait while your site updates.', 'formidable' ),
1657 'no_save_warning' => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
1658 'private' => __( 'Private' ),
1659 'jquery_ui_url' => self::jquery_ui_base_url(),
1660 'no_licenses' => __( 'No new licenses were found', 'formidable' ),
1661 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
1662 ) );
1663 }
1664 }
1665
1666 /**
1667 * echo the message on the plugins listing page
1668 * @since 1.07.10
1669 *
1670 * @param float $min_version The version the add-on requires
1671 */
1672 public static function min_version_notice( $min_version ) {
1673 $frm_version = self::plugin_version();
1674
1675 // check if Formidable meets minimum requirements
1676 if ( version_compare($frm_version, $min_version, '>=') ) {
1677 return;
1678 }
1679
1680 $wp_list_table = _get_list_table('WP_Plugins_List_Table');
1681 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">' .
1682 __( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
1683 '</div></td></tr>';
1684 }
1685
1686 public static function locales( $type = 'date' ) {
1687 $locales = array(
1688 'en' => __( 'English', 'formidable' ),
1689 '' => __( 'English/Western', 'formidable' ),
1690 'af' => __( 'Afrikaans', 'formidable' ),
1691 'sq' => __( 'Albanian', 'formidable' ),
1692 'ar' => __( 'Arabic', 'formidable' ),
1693 'hy' => __( 'Armenian', 'formidable' ),
1694 'az' => __( 'Azerbaijani', 'formidable' ),
1695 'eu' => __( 'Basque', 'formidable' ),
1696 'bs' => __( 'Bosnian', 'formidable' ),
1697 'bg' => __( 'Bulgarian', 'formidable' ),
1698 'ca' => __( 'Catalan', 'formidable' ),
1699 'zh-HK' => __( 'Chinese Hong Kong', 'formidable' ),
1700 'zh-CN' => __( 'Chinese Simplified', 'formidable' ),
1701 'zh-TW' => __( 'Chinese Traditional', 'formidable' ),
1702 'hr' => __( 'Croatian', 'formidable' ),
1703 'cs' => __( 'Czech', 'formidable' ),
1704 'da' => __( 'Danish', 'formidable' ),
1705 'nl' => __( 'Dutch', 'formidable' ),
1706 'en-GB' => __( 'English/UK', 'formidable' ),
1707 'eo' => __( 'Esperanto', 'formidable' ),
1708 'et' => __( 'Estonian', 'formidable' ),
1709 'fo' => __( 'Faroese', 'formidable' ),
1710 'fa' => __( 'Farsi/Persian', 'formidable' ),
1711 'fil' => __( 'Filipino', 'formidable' ),
1712 'fi' => __( 'Finnish', 'formidable' ),
1713 'fr' => __( 'French', 'formidable' ),
1714 'fr-CA' => __( 'French/Canadian', 'formidable' ),
1715 'fr-CH' => __( 'French/Swiss', 'formidable' ),
1716 'de' => __( 'German', 'formidable' ),
1717 'de-AT' => __( 'German/Austria', 'formidable' ),
1718 'de-CH' => __( 'German/Switzerland', 'formidable' ),
1719 'el' => __( 'Greek', 'formidable' ),
1720 'he' => __( 'Hebrew', 'formidable' ),
1721 'iw' => __( 'Hebrew', 'formidable' ),
1722 'hi' => __( 'Hindi', 'formidable' ),
1723 'hu' => __( 'Hungarian', 'formidable' ),
1724 'is' => __( 'Icelandic', 'formidable' ),
1725 'id' => __( 'Indonesian', 'formidable' ),
1726 'it' => __( 'Italian', 'formidable' ),
1727 'ja' => __( 'Japanese', 'formidable' ),
1728 'ko' => __( 'Korean', 'formidable' ),
1729 'lv' => __( 'Latvian', 'formidable' ),
1730 'lt' => __( 'Lithuanian', 'formidable' ),
1731 'ms' => __( 'Malaysian', 'formidable' ),
1732 'no' => __( 'Norwegian', 'formidable' ),
1733 'pl' => __( 'Polish', 'formidable' ),
1734 'pt' => __( 'Portuguese', 'formidable' ),
1735 'pt-BR' => __( 'Portuguese/Brazilian', 'formidable' ),
1736 'pt-PT' => __( 'Portuguese/Portugal', 'formidable' ),
1737 'ro' => __( 'Romanian', 'formidable' ),
1738 'ru' => __( 'Russian', 'formidable' ),
1739 'sr' => __( 'Serbian', 'formidable' ),
1740 'sr-SR' => __( 'Serbian', 'formidable' ),
1741 'sk' => __( 'Slovak', 'formidable' ),
1742 'sl' => __( 'Slovenian', 'formidable' ),
1743 'es' => __( 'Spanish', 'formidable' ),
1744 'es-419' => __( 'Spanish/Latin America', 'formidable' ),
1745 'sv' => __( 'Swedish', 'formidable' ),
1746 'ta' => __( 'Tamil', 'formidable' ),
1747 'th' => __( 'Thai', 'formidable' ),
1748 'tu' => __( 'Turkish', 'formidable' ),
1749 'tr' => __( 'Turkish', 'formidable' ),
1750 'uk' => __( 'Ukranian', 'formidable' ),
1751 'vi' => __( 'Vietnamese', 'formidable' ),
1752 );
1753
1754 if ( $type === 'captcha' ) {
1755 // remove the languages unavailable for the captcha
1756 $unset = array( '', 'af', 'sq', 'hy', 'az', 'eu', 'bs', 'zh-HK', 'eo', 'et', 'fo', 'fr-CH', 'he', 'is', 'ms', 'sr-SR', 'ta', 'tu' );
1757 } else {
1758 // remove the languages unavailable for the datepicker
1759 $unset = array( 'en', 'fil', 'fr-CA', 'de-AT', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419', 'tr' );
1760 }
1761
1762 $locales = array_diff_key($locales, array_flip($unset));
1763 $locales = apply_filters('frm_locales', $locales);
1764
1765 return $locales;
1766 }
1767
1768 /**
1769 * Prepare and save settings in styles and actions
1770 *
1771 * @param array $settings
1772 * @param string $group
1773 *
1774 * @since 2.0.6
1775 * @deprecated 2.05.06
1776 */
1777 public static function save_settings( $settings, $group ) {
1778 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1779 return FrmDb::save_settings( $settings, $group );
1780 }
1781
1782 /**
1783 * Since actions are JSON encoded, we don't want any filters messing with it.
1784 * Remove the filters and then add them back in case any posts or views are
1785 * also being imported.
1786 *
1787 * Used when saving form actions and styles
1788 *
1789 * @since 2.0.4
1790 * @deprecated 2.05.06
1791 */
1792 public static function save_json_post( $settings ) {
1793 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1794 return FrmDb::save_json_post( $settings );
1795 }
1796
1797 /**
1798 * Check cache before fetching values and saving to cache
1799 *
1800 * @since 2.0
1801 * @deprecated 2.05.06
1802 *
1803 * @param string $cache_key The unique name for this cache
1804 * @param string $group The name of the cache group
1805 * @param string $query If blank, don't run a db call
1806 * @param string $type The wpdb function to use with this query
1807 * @return mixed $results The cache or query results
1808 */
1809 public static function check_cache( $cache_key, $group = '', $query = '', $type = 'get_var', $time = 300 ) {
1810 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1811 return FrmDb::check_cache( $cache_key, $group, $query, $type, $time );
1812 }
1813
1814 /**
1815 * @deprecated 2.05.06
1816 */
1817 public static function set_cache( $cache_key, $results, $group = '', $time = 300 ) {
1818 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1819 FrmDb::set_cache( $cache_key, $results, $group, $time );
1820 }
1821
1822 /**
1823 * Keep track of the keys cached in each group so they can be deleted
1824 * in Redis and Memcache
1825 * @deprecated 2.05.06
1826 */
1827 public static function add_key_to_group_cache( $key, $group ) {
1828 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1829 FrmDb::add_key_to_group_cache( $key, $group );
1830 }
1831
1832 public static function get_group_cached_keys( $group ) {
1833 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1834 return FrmDb::get_group_cached_keys( $group );
1835 }
1836
1837 /**
1838 * @since 2.0
1839 * @deprecated 2.05.06
1840 * @return mixed The cached value or false
1841 */
1842 public static function check_cache_and_transient( $cache_key ) {
1843 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1844 return FrmDb::check_cache( $cache_key );
1845 }
1846
1847 /**
1848 * @since 2.0
1849 * @deprecated 2.05.06
1850 * @param string $cache_key
1851 */
1852 public static function delete_cache_and_transient( $cache_key, $group = 'default' ) {
1853 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1854 FrmDb::delete_cache_and_transient( $cache_key, $group );
1855 }
1856
1857 /**
1858 * @since 2.0
1859 * @deprecated 2.05.06
1860 *
1861 * @param string $group The name of the cache group
1862 */
1863 public static function cache_delete_group( $group ) {
1864 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1865 FrmDb::cache_delete_group( $group );
1866 }
1867
1868 /**
1869 * Added for < WP 4.0 compatability
1870 *
1871 * @since 1.07.10
1872 * @deprecated 2.05.06
1873 *
1874 * @param string $term The value to escape
1875 * @return string The escaped value
1876 */
1877 public static function esc_like( $term ) {
1878 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1879 return FrmDb::esc_like( $term );
1880 }
1881
1882 /**
1883 * @param string $order_query
1884 * @deprecated 2.05.06
1885 */
1886 public static function esc_order( $order_query ) {
1887 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1888 return FrmDb::esc_order( $order_query );
1889 }
1890
1891 /**
1892 * Make sure this is ordering by either ASC or DESC
1893 * @deprecated 2.05.06
1894 */
1895 public static function esc_order_by( &$order_by ) {
1896 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1897 FrmDb::esc_order_by( $order_by );
1898 }
1899
1900 /**
1901 * @param string $limit
1902 * @deprecated 2.05.06
1903 */
1904 public static function esc_limit( $limit ) {
1905 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1906 return FrmDb::esc_limit( $limit );
1907 }
1908
1909 /**
1910 * Get an array of values ready to go through $wpdb->prepare
1911 * @since 2.0
1912 * @deprecated 2.05.06
1913 */
1914 public static function prepare_array_values( $array, $type = '%s' ) {
1915 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1916 return FrmDb::prepare_array_values( $array, $type );
1917 }
1918
1919 /**
1920 * @deprecated 2.05.06
1921 */
1922 public static function prepend_and_or_where( $starts_with = ' WHERE ', $where = '' ) {
1923 _deprecated_function( __METHOD__, '2.05.06', 'FrmDb::' . __FUNCTION__ );
1924 return FrmDb::prepend_and_or_where( $starts_with, $where );
1925 }
1926 }
1927