Completed
Push — master ( f4ae02...8ecdd3 )
by Stephanie
04:18
created

FrmAppHelper::load_scripts()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 6
rs 9.4286
cc 2
eloc 4
nc 2
nop 1
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 = 27; //version of the database we are moving to
8
	public static $pro_db_version = 30;
9
10
	/**
11
	 * @since 2.0
12
	 */
13
	public static $plug_version = '2.0.19b3';
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 affiliate() {
61
		return '';
62
	}
63
64
    /**
65
     * Get the Formidable settings
66
     *
67
     * @since 2.0
68
     *
69
     * @param None
70
     * @return FrmSettings $frm_setings
71
     */
72
    public static function get_settings() {
73
        global $frm_settings;
74
        if ( empty($frm_settings) ) {
75
            $frm_settings = new FrmSettings();
76
        }
77
        return $frm_settings;
78
    }
79
80
    /**
81
     * Show a message in place of pro features
82
     *
83
     * @since 2.0
84
     */
85
	public static function update_message( $features, $class = '' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $features is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $class is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
86
		_deprecated_function( __FUNCTION__, '2.0.19' );
87
    }
88
89
    public static function pro_is_installed() {
90
        return apply_filters('frm_pro_installed', false);
91
    }
92
93
    /**
94
     * Check for certain page in Formidable settings
95
     *
96
     * @since 2.0
97
     *
98
     * @param string $page The name of the page to check
99
     * @return boolean
100
     */
101
	public static function is_admin_page( $page = 'formidable' ) {
102
        global $pagenow;
103
		$get_page = self::simple_get( 'page', 'sanitize_title' );
104
        if ( $pagenow ) {
105
			return $pagenow == 'admin.php' && $get_page == $page;
106
        }
107
108
		return is_admin() && $get_page == $page;
109
    }
110
111
    /**
112
     * Check for the form preview page
113
     *
114
     * @since 2.0
115
     *
116
     * @param None
117
     * @return boolean
118
     */
119
    public static function is_preview_page() {
120
        global $pagenow;
121
		$action = FrmAppHelper::simple_get( 'action', 'sanitize_title' );
122
		return $pagenow && $pagenow == 'admin-ajax.php' && $action == 'frm_forms_preview';
123
    }
124
125
    /**
126
     * Check for ajax except the form preview page
127
     *
128
     * @since 2.0
129
     *
130
     * @param None
131
     * @return boolean
132
     */
133
    public static function doing_ajax() {
134
        return defined('DOING_AJAX') && DOING_AJAX && ! self::is_preview_page();
135
    }
136
137
	/**
138
	 * @since 2.0.8
139
	 */
140
	public static function prevent_caching() {
141
		global $frm_vars;
142
		return isset( $frm_vars['prevent_caching'] ) && $frm_vars['prevent_caching'];
143
	}
144
145
    /**
146
     * Check if on an admin page
147
     *
148
     * @since 2.0
149
     *
150
     * @param None
151
     * @return boolean
152
     */
153
    public static function is_admin() {
154
        return is_admin() && ( ! defined('DOING_AJAX') || ! DOING_AJAX );
155
    }
156
157
    /**
158
     * Check if value contains blank value or empty array
159
     *
160
     * @since 2.0
161
     * @param $value - value to check
162
     * @return boolean
163
     */
164
    public static function is_empty_value( $value, $empty = '' ) {
165
        return ( is_array( $value ) && empty( $value ) ) || $value == $empty;
166
    }
167
168
    public static function is_not_empty_value( $value, $empty = '' ) {
169
        return ! self::is_empty_value( $value, $empty );
170
    }
171
172
    /**
173
     * Get any value from the $_SERVER
174
     *
175
     * @since 2.0
176
     * @param string $value
177
     * @return string
178
     */
179
	public static function get_server_value( $value ) {
180
        return isset( $_SERVER[ $value ] ) ? wp_strip_all_tags( $_SERVER[ $value ] ) : '';
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
181
    }
182
183
    /**
184
     * Check for the IP address in several places
185
     * Used by [ip] shortcode
186
     *
187
     * @return string The IP address of the current user
188
     */
189
    public static function get_ip_address() {
190
		$ip = '';
191
        foreach ( array(
192
            'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP',
193
            'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR',
194
        ) as $key ) {
195
            if ( ! isset( $_SERVER[ $key ] ) ) {
196
                continue;
197
            }
198
199
            foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) {
200
                $ip = trim($ip); // just to be safe
201
202
                if ( filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false ) {
203
                    return $ip;
204
                }
205
            }
206
        }
207
208
		return sanitize_text_field( $ip );
209
    }
210
211
    public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
212
        if ( strpos($param, '[') ) {
213
            $params = explode('[', $param);
214
            $param = $params[0];
215
        }
216
217
		if ( $src == 'get' ) {
218
            $value = isset( $_POST[ $param ] ) ? stripslashes_deep( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? stripslashes_deep( $_GET[ $param ] ) : $default );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
219
            if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) {
220
                $value = stripslashes_deep( htmlspecialchars_decode( urldecode( $_GET[ $param ] ) ) );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
221
            }
222
			self::sanitize_value( $sanitize, $value );
223
		} else {
224
            $value = self::get_simple_request( array( 'type' => $src, 'param' => $param, 'default' => $default, 'sanitize' => $sanitize ) );
225
        }
226
227
		if ( isset( $params ) && is_array( $value ) && ! empty( $value ) ) {
228
            foreach ( $params as $k => $p ) {
229
                if ( ! $k || ! is_array($value) ) {
230
                    continue;
231
                }
232
233
                $p = trim($p, ']');
234
                $value = isset( $value[ $p ] ) ? $value[ $p ] : $default;
235
            }
236
        }
237
238
        return $value;
239
    }
240
241
	/**
242
	 *
243
	 * @param string $param
244
	 * @param mixed $default
245
	 * @param string $sanitize
246
	 */
247
	public static function get_post_param( $param, $default = '', $sanitize = '' ) {
248
		return self::get_simple_request( array( 'type' => 'post', 'param' => $param, 'default' => $default, 'sanitize' => $sanitize ) );
249
	}
250
251
	/**
252
	 * @since 2.0
253
	 *
254
	 * @param string $param
255
	 * @param string $sanitize
256
	 * @param string $default
257
	 */
258
	public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) {
259
		return self::get_simple_request( array( 'type' => 'get', 'param' => $param, 'default' => $default, 'sanitize' => $sanitize ) );
260
    }
261
262
	/**
263
	 * Get a GET/POST/REQUEST value and sanitize it
264
	 *
265
	 * @since 2.0.6
266
	 */
267
	public static function get_simple_request( $args ) {
268
		$defaults = array(
269
			'param' => '', 'default' => '',
270
			'type' => 'get', 'sanitize' => 'sanitize_text_field',
271
		);
272
		$args = wp_parse_args( $args, $defaults );
273
274
		$value = $args['default'];
275
		if ( $args['type'] == 'get' ) {
276
			if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
277
				$value = $_GET[ $args['param'] ];
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
278
			}
279
		} else if ( $args['type'] == 'post' ) {
280
			if ( isset( $_POST[ $args['param'] ] ) ) {
281
				$value = stripslashes_deep( maybe_unserialize( $_POST[ $args['param'] ] ) );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
282
			}
283
		} else {
284
			if ( isset( $_REQUEST[ $args['param'] ] ) ) {
285
				$value = $_REQUEST[ $args['param'] ];
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
286
			}
287
		}
288
289
		self::sanitize_value( $args['sanitize'], $value );
290
		return $value;
291
	}
292
293
	/**
294
	* Preserve backslashes in a value, but make sure value doesn't get compounding slashes
295
	*
296
	* @since 2.0.8
297
	* @param string $value
298
	* @return string $value
299
	*/
300
	public static function preserve_backslashes( $value ) {
301
		// If backslashes have already been added, don't add them again
302
		if ( strpos( $value, '\\\\' ) === false ) {
303
			$value = addslashes( $value );
304
		}
305
		return $value;
306
	}
307
308
	public static function sanitize_value( $sanitize, &$value ) {
309
		if ( ! empty( $sanitize ) ) {
310
			if ( is_array( $value ) ) {
311
				$value = array_map( $sanitize, $value );
312
			} else {
313
				$value = call_user_func( $sanitize, $value );
314
			}
315
		}
316
	}
317
318
    public static function sanitize_request( $sanitize_method, &$values ) {
319
        $temp_values = $values;
320
        foreach ( $temp_values as $k => $val ) {
321
            if ( isset( $sanitize_method[ $k ] ) ) {
322
				$values[ $k ] = call_user_func( $sanitize_method[ $k ], $val );
323
            }
324
        }
325
    }
326
327
	public static function sanitize_array( &$values ) {
328
		$temp_values = $values;
329
		foreach ( $temp_values as $k => $val ) {
330
			$values[ $k ] = wp_kses_post( $val );
331
		}
332
	}
333
334
	/**
335
	 * Sanitize the value, and allow some HTML
336
	 * @since 2.0
337
	 */
338
	public static function kses( $value, $allowed = array() ) {
339
		$html = array(
340
		    'a' => array(
341
				'href'  => array(),
342
				'title' => array(),
343
				'id'    => array(),
344
				'class' => array(),
345
		    ),
346
		);
347
348
		$allowed_html = array();
349
		foreach ( $allowed as $a ) {
350
			$allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
351
		}
352
353
		return wp_kses( $value, $allowed_html );
354
	}
355
356
    /**
357
     * Used when switching the action for a bulk action
358
     * @since 2.0
359
     */
360
    public static function remove_get_action() {
361
        if ( ! isset($_GET) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
362
            return;
363
        }
364
365
        $new_action = isset( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : ( isset( $_GET['action2'] ) ? sanitize_text_field( $_GET['action2'] ) : '' );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
366
        if ( ! empty( $new_action ) ) {
367
			$_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', FrmAppHelper::get_server_value( 'REQUEST_URI' ) );
368
        }
369
    }
370
371
    /**
372
     * Check the WP query for a parameter
373
     *
374
     * @since 2.0
375
     * @return string|array
376
     */
377
    public static function get_query_var( $value, $param ) {
378
        if ( $value != '' ) {
379
            return $value;
380
        }
381
382
        global $wp_query;
383
        if ( isset( $wp_query->query_vars[ $param ] ) ) {
384
            $value = $wp_query->query_vars[ $param ];
385
        }
386
387
        return $value;
388
    }
389
390
    /**
391
     * @param string $type
392
     */
393
    public static function trigger_hook_load( $type, $object = null ) {
394
        // only load the form hooks once
395
        $hooks_loaded = apply_filters('frm_'. $type .'_hooks_loaded', false, $object);
396
        if ( ! $hooks_loaded ) {
397
            do_action('frm_load_'. $type .'_hooks');
398
        }
399
    }
400
401
    /**
402
     * Check cache before fetching values and saving to cache
403
     *
404
     * @since 2.0
405
     *
406
     * @param string $cache_key The unique name for this cache
407
     * @param string $group The name of the cache group
408
     * @param string $query If blank, don't run a db call
409
     * @param string $type The wpdb function to use with this query
410
     * @return mixed $results The cache or query results
411
     */
412
    public static function check_cache( $cache_key, $group = '', $query = '', $type = 'get_var', $time = 300 ) {
413
        $results = wp_cache_get($cache_key, $group);
414
        if ( ! self::is_empty_value( $results, false ) || empty($query) ) {
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
415
            return $results;
416
        }
417
418
        if ( 'get_posts' == $type ) {
419
            $results = get_posts($query);
420
        } else {
421
            global $wpdb;
422
            $results = $wpdb->{$type}($query);
423
        }
424
425
		if ( ! self::prevent_caching() ) {
426
			wp_cache_set( $cache_key, $results, $group, $time );
427
		}
428
429
        return $results;
430
    }
431
432
    /**
433
     * Data that should be stored for a long time can be stored in a transient.
434
     * First check the cache, then check the transient
435
     * @since 2.0
436
     * @return mixed The cached value or false
437
     */
438
	public static function check_cache_and_transient( $cache_key ) {
439
        // check caching layer first
440
        $results = self::check_cache( $cache_key );
441
        if ( $results ) {
442
            return $results;
443
        }
444
445
        // then check the transient
446
        $results = get_transient($cache_key);
447
        if ( $results ) {
448
            wp_cache_set($cache_key, $results);
449
        }
450
451
        return $results;
452
    }
453
454
    /**
455
     * @since 2.0
456
     * @param string $cache_key
457
     */
458
	public static function delete_cache_and_transient( $cache_key ) {
459
        delete_transient($cache_key);
460
        wp_cache_delete($cache_key);
461
    }
462
463
    /**
464
     * Delete all caching in a single group
465
     *
466
     * @since 2.0
467
     *
468
     * @param string $group The name of the cache group
469
     * @return boolean True or False
470
     */
471
	public static function cache_delete_group( $group ) {
472
    	global $wp_object_cache;
473
474
        if ( isset( $wp_object_cache->cache[ $group ] ) ) {
475
            foreach ( $wp_object_cache->cache[ $group ] as $k => $v ) {
476
                wp_cache_delete($k, $group);
477
            }
478
            return true;
479
        }
480
481
    	return false;
482
    }
483
484
    /**
485
     * Check a value from a shortcode to see if true or false.
486
     * True when value is 1, true, 'true', 'yes'
487
     *
488
     * @since 1.07.10
489
     *
490
     * @param string $value The value to compare
491
     * @return boolean True or False
492
     */
493
	public static function is_true( $value ) {
494
        return ( true === $value || 1 == $value || 'true' == $value || 'yes' == $value );
495
    }
496
497
    /**
498
     * Used to filter shortcode in text widgets
499
     */
500
    public static function widget_text_filter_callback( $matches ) {
501
        return do_shortcode( $matches[0] );
502
    }
503
504
	public static function load_scripts( $scripts ) {
505
        _deprecated_function( __FUNCTION__, '2.0', 'wp_enqueue_script' );
506
        foreach ( (array) $scripts as $s ) {
507
            wp_enqueue_script($s);
508
        }
509
    }
510
511
	public static function load_styles( $styles ) {
512
        _deprecated_function( __FUNCTION__, '2.0', 'wp_enqueue_style' );
513
        foreach ( (array) $styles as $s ) {
514
            wp_enqueue_style($s);
515
        }
516
    }
517
518
    public static function get_pages() {
519
		return get_posts( array( 'post_type' => 'page', 'post_status' => array( 'publish', 'private' ), 'numberposts' => -1, 'orderby' => 'title', 'order' => 'ASC' ) );
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set numberposts to -1 ever.
Loading history...
520
    }
521
522
    public static function wp_pages_dropdown( $field_name, $page_id, $truncate = false ) {
523
        $pages = self::get_pages();
524
		$selected = self::get_post_param( $field_name, $page_id, 'absint' );
525
    ?>
526
        <select name="<?php echo esc_attr($field_name); ?>" id="<?php echo esc_attr($field_name); ?>" class="frm-pages-dropdown">
527
            <option value=""> </option>
528
            <?php foreach ( $pages as $page ) { ?>
529
				<option value="<?php echo esc_attr($page->ID); ?>" <?php selected( $selected, $page->ID ) ?>>
530
					<?php echo esc_html( $truncate ? self::truncate( $page->post_title, $truncate ) : $page->post_title ); ?>
531
				</option>
532
            <?php } ?>
533
        </select>
534
    <?php
535
    }
536
537
	public static function post_edit_link( $post_id ) {
538
        $post = get_post($post_id);
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
539
        if ( $post ) {
540
            return '<a href="'. esc_url(admin_url('post.php') .'?post='. $post_id .'&action=edit') .'">'. self::truncate($post->post_title, 50) .'</a>';
541
        }
542
        return '';
543
    }
544
545
	public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
546
    ?>
547
        <select name="<?php echo esc_attr($field_name); ?>" id="<?php echo esc_attr($field_name); ?>" <?php
548
            echo ( 'multiple' == $multiple ) ? 'multiple="multiple"' : '';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
549
            ?> class="frm_multiselect">
550
            <?php self::roles_options($capability); ?>
551
        </select>
552
    <?php
553
    }
554
555
	public static function roles_options( $capability ) {
556
        global $frm_vars;
557
        if ( isset($frm_vars['editable_roles']) ) {
558
            $editable_roles = $frm_vars['editable_roles'];
559
        } else {
560
            $editable_roles = get_editable_roles();
561
            $frm_vars['editable_roles'] = $editable_roles;
562
        }
563
564
        foreach ( $editable_roles as $role => $details ) {
565
            $name = translate_user_role($details['name'] ); ?>
566
        <option value="<?php echo esc_attr($role) ?>" <?php echo in_array($role, (array) $capability) ? ' selected="selected"' : ''; ?>><?php echo esc_attr($name) ?> </option>
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'in_array'
Loading history...
567
<?php
568
            unset($role, $details);
569
        }
570
    }
571
572
	public static function frm_capabilities( $type = 'auto' ) {
573
        $cap = array(
574
            'frm_view_forms'        => __( 'View Forms and Templates', 'formidable' ),
575
            'frm_edit_forms'        => __( 'Add/Edit Forms and Templates', 'formidable' ),
576
            'frm_delete_forms'      => __( 'Delete Forms and Templates', 'formidable' ),
577
            'frm_change_settings'   => __( 'Access this Settings Page', 'formidable' ),
578
            'frm_view_entries'      => __( 'View Entries from Admin Area', 'formidable' ),
579
            'frm_delete_entries'    => __( 'Delete Entries from Admin Area', 'formidable' ),
580
        );
581
582
		if ( ! self::pro_is_installed() && 'pro' != $type ) {
583
            return $cap;
584
        }
585
586
        $cap['frm_create_entries'] = __( 'Add Entries from Admin Area', 'formidable' );
587
        $cap['frm_edit_entries'] = __( 'Edit Entries from Admin Area', 'formidable' );
588
        $cap['frm_view_reports'] = __( 'View Reports', 'formidable' );
589
        $cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' );
590
591
        return $cap;
592
    }
593
594
	public static function user_has_permission( $needed_role ) {
595
        if ( $needed_role == '-1' ) {
596
            return false;
597
		}
598
599
        // $needed_role will be equal to blank if "Logged-in users" is selected
600
        if ( ( $needed_role == '' && is_user_logged_in() ) || current_user_can( $needed_role ) ) {
601
            return true;
602
        }
603
604
        $roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
605
        foreach ( $roles as $role ) {
606
			if ( current_user_can( $role ) ) {
607
        		return true;
608
			}
609
        	if ( $role == $needed_role ) {
610
        		break;
611
			}
612
        }
613
        return false;
614
    }
615
616
    /**
617
     * Make sure administrators can see Formidable menu
618
     *
619
     * @since 2.0
620
     */
621
    public static function maybe_add_permissions() {
622
		self::force_capability( 'frm_view_entries' );
623
624
        if ( ! current_user_can('administrator') || current_user_can('frm_view_forms') ) {
625
            return;
626
        }
627
628
		$user_id = get_current_user_id();
629
		$user = new WP_User( $user_id );
630
        $frm_roles = self::frm_capabilities();
631
        foreach ( $frm_roles as $frm_role => $frm_role_description ) {
632
			$user->add_cap( $frm_role );
633
            unset($frm_role, $frm_role_description);
634
        }
635
    }
636
637
	/**
638
	 * Make sure admins have permission to see the menu items
639
	 * @since 2.0.6
640
	 */
641
	public static function force_capability( $cap = 'frm_change_settings' ) {
642
		if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
643
			$role = get_role( 'administrator' );
644
			$frm_roles = self::frm_capabilities();
645
			foreach ( $frm_roles as $frm_role => $frm_role_description ) {
646
				$role->add_cap( $frm_role );
647
			}
648
		}
649
	}
650
651
    /**
652
     * Check if the user has permision for action.
653
     * Return permission message and stop the action if no permission
654
     * @since 2.0
655
     * @param string $permission
656
     */
657
	public static function permission_check( $permission, $show_message = 'show' ) {
658
        $permission_error = self::permission_nonce_error($permission);
659
        if ( $permission_error !== false ) {
660
            if ( 'hide' == $show_message ) {
661
                $permission_error = '';
662
            }
663
            wp_die($permission_error);
664
        }
665
    }
666
667
    /**
668
     * Check user permission and nonce
669
     * @since 2.0
670
     * @param string $permission
671
     * @return false|string The permission message or false if allowed
672
     */
673
	public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
674
		if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
675
			$frm_settings = self::get_settings();
676
			return $frm_settings->admin_permission;
677
		}
678
679
		$error = false;
680
        if ( empty($nonce_name) ) {
681
            return $error;
682
        }
683
684
        if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $_REQUEST[ $nonce_name ], $nonce ) ) ) {
685
            $frm_settings = self::get_settings();
686
            $error = $frm_settings->admin_permission;
687
        }
688
689
        return $error;
690
    }
691
692
    public static function checked( $values, $current ) {
693
		if ( self::check_selected( $values, $current ) ) {
694
            echo ' checked="checked"';
695
		}
696
    }
697
698
	public static function check_selected( $values, $current ) {
699
        $values = self::recursive_function_map( $values, 'trim' );
700
        $current = trim($current);
701
702
        return ( is_array($values) && in_array($current, $values) ) || ( ! is_array($values) && $values == $current );
703
    }
704
705
    /**
706
    * Check if current field option is an "other" option
707
    *
708
    * @since 2.0
709
    *
710
    * @param string $opt_key
711
    * @return boolean Returns true if current field option is an "Other" option
712
    */
713
    public static function is_other_opt( $opt_key ) {
714
        _deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::is_other_opt' );
715
        return FrmFieldsHelper::is_other_opt( $opt_key );
716
    }
717
718
    /**
719
    * Get value that belongs in "Other" text box
720
    *
721
    * @since 2.0
722
    *
723
    * @param string $opt_key
724
    * @param array $field
725
    * @return string $other_val
726
    */
727
    public static function get_other_val( $opt_key, $field, $parent = false, $pointer = false ) {
728
		_deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::get_other_val' );
729
		return FrmFieldsHelper::get_other_val( compact( 'opt_key', 'field', 'parent', 'pointer' ) );
730
    }
731
732
    /**
733
    * Check if there is a saved value for the "Other" text field. If so, set it as the $other_val.
734
    * Intended for front-end use
735
    *
736
    * @since 2.0
737
    *
738
    * @param array $field
739
    * @param boolean $other_opt
740
    * @param string $checked
741
    * @param array $args should include opt_key and field name
742
    * @return string $other_val
743
    */
744
    public static function prepare_other_input( $field, &$other_opt, &$checked, $args = array() ) {
745
		_deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::prepare_other_input' );
746
		$args['field'] = $field;
747
		return FrmFieldsHelper::prepare_other_input( $args, $other_opt, $checked );
748
    }
749
750
	public static function recursive_function_map( $value, $function ) {
751
		if ( is_array( $value ) ) {
752
			$original_function = $function;
753
			if ( count( $value ) ) {
754
				$function = explode( ', ', self::prepare_array_values( $value, $function ) );
755
			} else {
756
				$function = array( $function );
757
			}
758
			if ( ! self::is_assoc( $value ) ) {
759
				$value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
760
			} else {
761
				foreach ( $value as $k => $v ) {
762
					if ( ! is_array( $v ) ) {
763
						$value[ $k ] = call_user_func( $original_function, $v );
764
					}
765
				}
766
			}
767
		} else {
768
			$value = call_user_func( $function, $value );
769
		}
770
771
		return $value;
772
	}
773
774
	public static function is_assoc( $array ) {
775
		return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
776
	}
777
778
    /**
779
     * Flatten a multi-dimensional array
780
     */
781
	public static function array_flatten( $array, $keys = 'keep' ) {
782
        $return = array();
783
        foreach ( $array as $key => $value ) {
784
            if ( is_array($value) ) {
785
				$return = array_merge( $return, self::array_flatten( $value, $keys ) );
786
            } else {
787
				if ( $keys == 'keep' ) {
788
					$return[ $key ] = $value;
789
				} else {
790
					$return[] = $value;
791
				}
792
            }
793
        }
794
        return $return;
795
    }
796
797
    public static function esc_textarea( $text ) {
798
        $safe_text = str_replace('&quot;', '"', $text);
799
        $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
800
    	return apply_filters( 'esc_textarea', $safe_text, $text );
801
    }
802
803
    /**
804
     * Add auto paragraphs to text areas
805
     * @since 2.0
806
     */
807
	public static function use_wpautop( $content ) {
808
        if ( apply_filters('frm_use_wpautop', true) ) {
809
            $content = wpautop(str_replace( '<br>', '<br />', $content));
810
        }
811
        return $content;
812
    }
813
814
	public static function replace_quotes( $val ) {
815
        //Replace double quotes
816
		$val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
817
        //Replace single quotes
818
        $val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
819
        return $val;
820
    }
821
822
    /**
823
     * @since 2.0
824
     * @return string The base Google APIS url for the current version of jQuery UI
825
     */
826
    public static function jquery_ui_base_url() {
827
        $url = 'http'. ( is_ssl() ? 's' : '' ) .'://ajax.googleapis.com/ajax/libs/jqueryui/'. self::script_version('jquery-ui-core');
828
        $url = apply_filters('frm_jquery_ui_base_url', $url);
829
        return $url;
830
    }
831
832
    /**
833
     * @param string $handle
834
     */
835
	public static function script_version( $handle ) {
836
        global $wp_scripts;
837
    	if ( ! $wp_scripts ) {
838
    	    return false;
839
    	}
840
841
        $ver = 0;
842
843
        if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
844
            return $ver;
845
        }
846
847
        $query = $wp_scripts->registered[ $handle ];
848
    	if ( is_object( $query ) ) {
849
    	    $ver = $query->ver;
850
    	}
851
852
    	return $ver;
853
    }
854
855
	public static function js_redirect( $url ) {
856
		return '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>';
857
    }
858
859
	public static function get_user_id_param( $user_id ) {
860
        if ( ! $user_id || empty($user_id) || is_numeric($user_id) ) {
861
            return $user_id;
862
        }
863
864
		if ( $user_id == 'current' ) {
865
            $user_ID = get_current_user_id();
866
            $user_id = $user_ID;
867
		} else {
868
            if ( is_email($user_id) ) {
869
                $user = get_user_by('email', $user_id);
870
            } else {
871
                $user = get_user_by('login', $user_id);
872
            }
873
874
            if ( $user ) {
875
                $user_id = $user->ID;
876
            }
877
            unset($user);
878
        }
879
880
        return $user_id;
881
    }
882
883
	public static function get_file_contents( $filename, $atts = array() ) {
884
        if ( ! is_file($filename) ) {
885
            return false;
886
        }
887
888
        extract($atts);
0 ignored issues
show
introduced by
extract() usage is highly discouraged, due to the complexity and unintended issues it might cause.
Loading history...
889
        ob_start();
890
        include($filename);
891
        $contents = ob_get_contents();
892
        ob_end_clean();
893
        return $contents;
894
    }
895
896
    /**
897
     * @param string $table_name
898
     * @param string $column
899
     */
900
    public static function get_unique_key( $name = '', $table_name, $column, $id = 0, $num_chars = 6 ) {
901
        global $wpdb;
902
903
        $key = '';
904
905
        if ( ! empty( $name ) ) {
906
            $key = sanitize_key($name);
907
        }
908
909
		if ( empty( $key ) ) {
910
            $max_slug_value = pow(36, $num_chars);
911
            $min_slug_value = 37; // we want to have at least 2 characters in the slug
912
            $key = base_convert( rand($min_slug_value, $max_slug_value), 10, 36 );
913
        }
914
915
		if ( is_numeric($key) || in_array( $key, array( 'id', 'key', 'created-at', 'detaillink', 'editlink', 'siteurl', 'evenodd' ) ) ) {
916
            $key = $key .'a';
917
        }
918
919
		$key_check = FrmDb::get_var( $table_name, array( $column => $key, 'ID !' => $id ), $column );
920
921
        if ( $key_check || is_numeric($key_check) ) {
922
            $suffix = 2;
923
			do {
924
				$alt_post_name = substr( $key, 0, 200 - ( strlen( $suffix ) + 1 ) ) . $suffix;
925
				$key_check = FrmDb::get_var( $table_name, array( $column => $alt_post_name, 'ID !' => $id ), $column );
926
				$suffix++;
927
			} while ($key_check || is_numeric($key_check));
928
			$key = $alt_post_name;
929
        }
930
        return $key;
931
    }
932
933
    /**
934
     * Editing a Form or Entry
935
     * @param string $table
936
     * @return bool|array
937
     */
938
    public static function setup_edit_vars( $record, $table, $fields = '', $default = false, $post_values = array(), $args = array() ) {
939
        if ( ! $record ) {
940
            return false;
941
        }
942
943
        global $frm_vars;
944
945
        if ( empty($post_values) ) {
946
            $post_values = stripslashes_deep($_POST);
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
947
        }
948
949
		$values = array( 'id' => $record->id, 'fields' => array() );
950
951
		foreach ( array( 'name', 'description' ) as $var ) {
952
            $default_val = isset($record->{$var}) ? $record->{$var} : '';
953
            $values[ $var ] = self::get_param( $var, $default_val );
954
            unset($var, $default_val);
955
        }
956
957
        $values['description'] = self::use_wpautop($values['description']);
958
        $frm_settings = self::get_settings();
959
        $is_form_builder = self::is_admin_page('formidable' );
960
961
        foreach ( (array) $fields as $field ) {
962
            // Make sure to filter default values (for placeholder text), but not on the form builder page
963
            if ( ! $is_form_builder ) {
964
                $field->default_value = apply_filters('frm_get_default_value', $field->default_value, $field, true );
965
            }
966
			$parent_form_id = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
967
			self::fill_field_defaults($field, $record, $values, compact('default', 'post_values', 'frm_settings', 'parent_form_id' ) );
968
        }
969
970
        self::fill_form_opts($record, $table, $post_values, $values);
971
972
        if ( $table == 'entries' ) {
973
            $values = FrmEntriesHelper::setup_edit_vars( $values, $record );
974
        } else if ( $table == 'forms' ) {
975
            $values = FrmFormsHelper::setup_edit_vars( $values, $record, $post_values );
976
        }
977
978
        return $values;
979
    }
980
981
	private static function fill_field_defaults( $field, $record, array &$values, $args ) {
982
        $post_values = $args['post_values'];
983
984
        if ( $args['default'] ) {
985
            $meta_value = $field->default_value;
986
        } else {
987
            if ( $record->post_id && self::pro_is_installed() && isset($field->field_options['post_field']) && $field->field_options['post_field'] ) {
988
                if ( ! isset($field->field_options['custom_field']) ) {
989
                    $field->field_options['custom_field'] = '';
990
                }
991
				$meta_value = FrmProEntryMetaHelper::get_post_value( $record->post_id, $field->field_options['post_field'], $field->field_options['custom_field'], array( 'truncate' => false, 'type' => $field->type, 'form_id' => $field->form_id, 'field' => $field ) );
992
            } else {
993
				$meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
994
            }
995
        }
996
997
        $field_type = isset( $post_values['field_options'][ 'type_'. $field->id ] ) ? $post_values['field_options'][ 'type_'. $field->id ] : $field->type;
998
        $new_value = isset( $post_values['item_meta'][ $field->id ] ) ? maybe_unserialize( $post_values['item_meta'][ $field->id ] ) : $meta_value;
999
1000
        $field_array = array(
1001
            'id'            => $field->id,
1002
            'value'         => $new_value,
1003
            'default_value' => $field->default_value,
1004
            'name'          => $field->name,
1005
            'description'   => $field->description,
1006
            'type'          => apply_filters('frm_field_type', $field_type, $field, $new_value),
1007
            'options'       => $field->options,
1008
            'required'      => $field->required,
1009
            'field_key'     => $field->field_key,
1010
            'field_order'   => $field->field_order,
1011
            'form_id'       => $field->form_id,
1012
			'parent_form_id' => $args['parent_form_id'],
1013
        );
1014
1015
        $args['field_type'] = $field_type;
1016
        self::fill_field_opts($field, $field_array, $args);
1017
1018
        $field_array = apply_filters('frm_setup_edit_fields_vars', $field_array, $field, $values['id']);
1019
1020
        if ( ! isset($field_array['unique']) || ! $field_array['unique'] ) {
1021
            $field_array['unique_msg'] = '';
1022
        }
1023
1024
        $field_array = array_merge( $field->field_options, $field_array );
1025
1026
        $values['fields'][ $field->id ] = $field_array;
1027
    }
1028
1029
	private static function fill_field_opts( $field, array &$field_array, $args ) {
1030
        $post_values = $args['post_values'];
1031
        $opt_defaults = FrmFieldsHelper::get_default_field_opts($field_array['type'], $field, true);
1032
1033
        foreach ( $opt_defaults as $opt => $default_opt ) {
1034
            $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 );
1035
            if ( $opt == 'blank' && $field_array[ $opt ] == '' ) {
1036
                $field_array[ $opt ] = $args['frm_settings']->blank_msg;
1037
            } else if ( $opt == 'invalid' && $field_array[ $opt ] == '' ) {
1038
                if ( $args['field_type'] == 'captcha' ) {
1039
                    $field_array[ $opt ] = $args['frm_settings']->re_msg;
1040
                } else {
1041
                    $field_array[ $opt ] = sprintf( __( '%s is invalid', 'formidable' ), $field_array['name'] );
1042
                }
1043
            }
1044
        }
1045
1046
        if ( $field_array['custom_html'] == '' ) {
1047
            $field_array['custom_html'] = FrmFieldsHelper::get_default_html($args['field_type']);
1048
        }
1049
    }
1050
1051
    /**
1052
     * @param string $table
1053
     */
1054
	private static function fill_form_opts( $record, $table, $post_values, array &$values ) {
1055
        if ( $table == 'entries' ) {
1056
            $form = $record->form_id;
1057
			FrmForm::maybe_get_form( $form );
1058
        } else {
1059
            $form = $record;
1060
        }
1061
1062
        if ( ! $form ) {
1063
            return;
1064
        }
1065
1066
        $values['form_name'] = isset($record->form_id) ? $form->name : '';
1067
		$values['parent_form_id'] = isset( $record->form_id ) ? $form->parent_form_id : 0;
1068
1069
        if ( ! is_array($form->options) ) {
1070
            return;
1071
        }
1072
1073
        foreach ( $form->options as $opt => $value ) {
1074
            $values[ $opt ] = isset( $post_values[ $opt ] ) ? maybe_unserialize( $post_values[ $opt ] ) : $value;
1075
        }
1076
1077
        self::fill_form_defaults($post_values, $values);
1078
    }
1079
1080
    /**
1081
     * Set to POST value or default
1082
     */
1083
	private static function fill_form_defaults( $post_values, array &$values ) {
1084
        $form_defaults = FrmFormsHelper::get_default_opts();
1085
1086
        foreach ( $form_defaults as $opt => $default ) {
1087
            if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
1088
				$values[ $opt ] = ( $post_values && isset( $post_values['options'][ $opt ] ) ) ? $post_values['options'][ $opt ] : $default;
1089
            }
1090
1091
            unset($opt, $defaut);
1092
        }
1093
1094 View Code Duplication
        if ( ! isset($values['custom_style']) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1095
            $frm_settings = self::get_settings();
1096
			$values['custom_style'] = ( $post_values && isset( $post_values['options']['custom_style'] ) ) ? absint( $_POST['options']['custom_style'] ) : ( $frm_settings->load_style != 'none' );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
1097
        }
1098
1099
		foreach ( array( 'before', 'after', 'submit' ) as $h ) {
1100
            if ( ! isset( $values[ $h .'_html' ] ) ) {
1101
                $values[ $h .'_html' ] = ( isset( $post_values['options'][ $h .'_html' ] ) ? $post_values['options'][ $h .'_html' ] : FrmFormsHelper::get_default_html( $h ) );
1102
            }
1103
            unset($h);
1104
        }
1105
    }
1106
1107
	public static function get_meta_value( $field_id, $entry ) {
1108
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryMeta::get_meta_value' );
1109
		return FrmEntryMeta::get_meta_value( $entry, $field_id );
1110
	}
1111
1112
	public static function insert_opt_html( $args ) {
1113
        $class = '';
1114
        if ( in_array( $args['type'], array( 'email', 'user_id', 'hidden', 'select', 'radio', 'checkbox', 'phone', 'text' ) ) ) {
1115
            $class .= 'show_frm_not_email_to';
1116
        }
1117
    ?>
1118
<li>
1119
    <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>
1120
    <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>
1121
    <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>
1122
</li>
1123
    <?php
1124
    }
1125
1126
    public static function get_us_states() {
1127
        _deprecated_function( __FUNCTION__, '2.0', 'FrmFieldsHelper::get_us_states' );
1128
        return FrmFieldsHelper::get_us_states();
1129
    }
1130
1131
    public static function get_countries() {
1132
        _deprecated_function( __FUNCTION__, '2.0', 'FrmFieldsHelper::get_countries' );
1133
        return FrmFieldsHelper::get_countries();
1134
    }
1135
1136
	public static function truncate( $str, $length, $minword = 3, $continue = '...' ) {
1137
        if ( is_array( $str ) ) {
1138
            return;
1139
		}
1140
1141
        $length = (int) $length;
1142
		$str = wp_strip_all_tags( $str );
1143
		$original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
1144
1145
		if ( $length == 0 ) {
1146
            return '';
1147
        } else if ( $length <= 10 ) {
1148
			$sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
1149
            return $sub . (($length < $original_len) ? $continue : '');
1150
        }
1151
1152
        $sub = '';
1153
        $len = 0;
1154
1155
		$words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
1156
1157
		foreach ( $words as $word ) {
1158
            $part = (($sub != '') ? ' ' : '') . $word;
1159
			$total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
1160
            if ( $total_len > $length && str_word_count($sub) ) {
1161
                break;
1162
            }
1163
1164
            $sub .= $part;
1165
			$len += self::mb_function( array( 'mb_strlen', 'strlen' ), array( $part ) );
1166
1167
            if ( str_word_count($sub) > $minword && $total_len >= $length ) {
1168
                break;
1169
            }
1170
1171
            unset($total_len, $word);
1172
        }
1173
1174
        return $sub . (($len < $original_len) ? $continue : '');
1175
    }
1176
1177
	public static function mb_function( $function_names, $args ) {
1178
		$mb_function_name = $function_names[0];
1179
		$function_name = $function_names[1];
1180
		if ( function_exists( $mb_function_name ) ) {
1181
			$function_name = $mb_function_name;
1182
		}
1183
		return call_user_func_array( $function_name, $args );
1184
	}
1185
1186
	public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
1187
        if ( empty($date) ) {
1188
            return $date;
1189
        }
1190
1191
        if ( empty($date_format) ) {
1192
            $date_format = get_option('date_format');
1193
        }
1194
1195
        if ( preg_match('/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date) && self::pro_is_installed() ) {
1196
            $frmpro_settings = new FrmProSettings();
1197
            $date = FrmProAppHelper::convert_date($date, $frmpro_settings->date_format, 'Y-m-d');
1198
        }
1199
1200
		$formatted = self::get_localized_date( $date_format, $date );
1201
1202
		$do_time = ( date( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
1203
		if ( $do_time ) {
1204
			$formatted .= self::add_time_to_date( $time_format, $date );
1205
		}
1206
1207
        return $formatted;
1208
    }
1209
1210
	private static function add_time_to_date( $time_format, $date ) {
1211
		if ( empty( $time_format ) ) {
1212
			$time_format = get_option('time_format');
1213
		}
1214
1215
		$trimmed_format = trim( $time_format );
1216
		$time = '';
1217
		if ( $time_format && ! empty( $trimmed_format ) ) {
1218
			$time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not 'self'
Loading history...
1219
		}
1220
1221
		return $time;
1222
	}
1223
1224
	/**
1225
	 * @since 2.0.8
1226
	 */
1227
	public static function get_localized_date( $date_format, $date ) {
1228
		$date = get_date_from_gmt( $date );
1229
		return date_i18n( $date_format, strtotime( $date ) );
1230
	}
1231
1232
    /**
1233
     * @return string The time ago in words
1234
     */
1235
    public static function human_time_diff( $from, $to = '' ) {
1236
    	if ( empty($to) ) {
1237
    	    		$to = time();
1238
    	}
1239
1240
    	// Array of time period chunks
1241
    	$chunks = array(
1242
    		array( 60 * 60 * 24 * 365, __( 'year', 'formidable' ), __( 'years', 'formidable' ) ),
1243
    		array( 60 * 60 * 24 * 30, __( 'month', 'formidable' ), __( 'months', 'formidable' ) ),
1244
    		array( 60 * 60 * 24 * 7, __( 'week', 'formidable' ), __( 'weeks', 'formidable' ) ),
1245
    		array( 60 * 60 * 24, __( 'day', 'formidable' ), __( 'days', 'formidable' ) ),
1246
    		array( 60 * 60, __( 'hour', 'formidable' ), __( 'hours', 'formidable' ) ),
1247
    		array( 60, __( 'minute', 'formidable' ), __( 'minutes', 'formidable' ) ),
1248
    		array( 1, __( 'second', 'formidable' ), __( 'seconds', 'formidable' ) ),
1249
    	);
1250
1251
    	// Difference in seconds
1252
    	$diff = (int) ($to - $from);
1253
1254
    	// Something went wrong with date calculation and we ended up with a negative date.
1255
		if ( $diff < 1 ) {
1256
			return '0 ' . __( 'seconds', 'formidable' );
1257
    	}
1258
1259
    	/**
1260
    	 * We only want to output one chunks of time here, eg:
1261
    	 * x years
1262
    	 * xx months
1263
    	 * so there's only one bit of calculation below:
1264
    	 */
1265
1266
        $count = 0;
1267
1268
    	//Step one: the first chunk
1269
		for ( $i = 0, $j = count( $chunks ); $i < $j; $i++ ) {
1270
    		$seconds = $chunks[ $i ][0];
1271
1272
    		// Finding the biggest chunk (if the chunk fits, break)
1273
    		if ( ( $count = floor($diff / $seconds) ) != 0 ) {
1274
    		    			break;
1275
    		}
1276
    	}
1277
1278
    	// Set output var
1279
    	$output = ( 1 == $count ) ? '1 '. $chunks[ $i ][1] : $count . ' ' . $chunks[ $i ][2];
1280
1281
    	if ( ! (int) trim( $output ) ) {
1282
    		$output = '0 ' . __( 'seconds', 'formidable' );
1283
        }
1284
1285
    	return $output;
1286
    }
1287
1288
    /**
1289
     * Added for < WP 4.0 compatability
1290
     *
1291
     * @since 1.07.10
1292
     *
1293
     * @param string $term The value to escape
1294
     * @return string The escaped value
1295
     */
1296
	public static function esc_like( $term ) {
1297
        global $wpdb;
1298
        if ( method_exists($wpdb, 'esc_like') ) {
1299
			// WP 4.0
1300
            $term = $wpdb->esc_like( $term );
1301
        } else {
1302
            $term = like_escape( $term );
1303
        }
1304
1305
        return $term;
1306
    }
1307
1308
    /**
1309
     * @param string $order_query
1310
     */
1311
	public static function esc_order( $order_query ) {
1312
        if ( empty($order_query) ) {
1313
            return '';
1314
        }
1315
1316
        // remove ORDER BY before santizing
1317
        $order_query = strtolower($order_query);
1318
        if ( strpos($order_query, 'order by') !== false ) {
1319
            $order_query = str_replace('order by', '', $order_query);
1320
        }
1321
1322
        $order_query = explode(' ', trim($order_query));
1323
1324
        $order_fields = array(
1325
            'id', 'form_key', 'name', 'description',
1326
            'parent_form_id', 'logged_in', 'is_template',
1327
            'default_template', 'status', 'created_at',
1328
        );
1329
1330
        $order = trim(trim(reset($order_query), ','));
1331
        if ( ! in_array($order, $order_fields) ) {
1332
            return '';
1333
        }
1334
1335
        $order_by = '';
1336
        if ( count($order_query) > 1 ) {
1337
			$order_by = end( $order_query );
1338
			self::esc_order_by( $order_by );
1339
        }
1340
1341
        return ' ORDER BY '. $order . ' '. $order_by;
1342
    }
1343
1344
	/**
1345
	 * Make sure this is ordering by either ASC or DESC
1346
	 */
1347
	public static function esc_order_by( &$order_by ) {
1348
		$sort_options = array( 'asc', 'desc' );
1349
		if ( ! in_array( strtolower( $order_by ), $sort_options ) ) {
1350
			$order_by = 'asc';
1351
		}
1352
	}
1353
1354
    /**
1355
     * @param string $limit
1356
     */
1357
	public static function esc_limit( $limit ) {
1358
        if ( empty($limit) ) {
1359
            return '';
1360
        }
1361
1362
        $limit = trim(str_replace(' limit', '', strtolower($limit)));
1363
        if ( is_numeric($limit) ) {
1364
            return ' LIMIT '. $limit;
1365
        }
1366
1367
        $limit = explode(',', trim($limit));
1368
        foreach ( $limit as $k => $l ) {
1369
            if ( is_numeric( $l ) ) {
1370
                $limit[ $k ] = $l;
1371
            }
1372
        }
1373
1374
        $limit = implode(',', $limit);
1375
        return ' LIMIT '. $limit;
1376
    }
1377
1378
    /**
1379
     * Get an array of values ready to go through $wpdb->prepare
1380
     * @since 2.0
1381
     */
1382
    public static function prepare_array_values( $array, $type = '%s' ) {
1383
        $placeholders = array_fill(0, count($array), $type);
1384
        return implode(', ', $placeholders);
1385
    }
1386
1387
    public static function prepend_and_or_where( $starts_with = ' WHERE ', $where = '' ) {
1388
        if ( empty($where) ) {
1389
            return '';
1390
        }
1391
1392
		if ( is_array( $where ) ) {
1393
            global $wpdb;
1394
            FrmDb::get_where_clause_and_values( $where, $starts_with );
1395
			$where = $wpdb->prepare( $where['where'], $where['values'] );
1396
		} else {
1397
            $where = $starts_with . $where;
1398
        }
1399
1400
        return $where;
1401
    }
1402
1403
    // Pagination Methods
1404
1405
    /**
1406
     * @param integer $current_p
1407
     */
1408
	public static function get_last_record_num( $r_count, $current_p, $p_size ) {
1409
		return ( ( $r_count < ( $current_p * $p_size ) ) ? $r_count : ( $current_p * $p_size ) );
1410
	}
1411
1412
    /**
1413
     * @param integer $current_p
1414
     */
1415
    public static function get_first_record_num( $r_count, $current_p, $p_size ) {
1416
        if ( $current_p == 1 ) {
1417
            return 1;
1418
        } else {
1419
            return ( self::get_last_record_num( $r_count, ( $current_p - 1 ), $p_size ) + 1 );
1420
        }
1421
    }
1422
1423
    /**
1424
     * @param string $table_name
1425
     */
1426
    public static function &getRecordCount( $where = '', $table_name ) {
0 ignored issues
show
Coding Style introduced by
The function name getRecordCount is in camel caps, but expected get_record_count instead as per the coding standard.
Loading history...
1427
        _deprecated_function( __FUNCTION__, '2.0', 'FrmDb::get_count' );
1428
        $count = FrmDb::get_count( $table_name, $where );
0 ignored issues
show
Documentation introduced by
$where is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1429
        return $count;
1430
    }
1431
1432
    public static function get_referer_info() {
1433
        _deprecated_function( __FUNCTION__, '2.0', 'FrmAppHelper::get_server_value' );
1434
        return self::get_server_value('HTTP_REFERER');
1435
    }
1436
1437
	/**
1438
	 * @return array
1439
	 */
1440
	public static function json_to_array( $json_vars ) {
1441
        $vars = array();
1442
        foreach ( $json_vars as $jv ) {
1443
            $jv_name = explode('[', $jv['name']);
1444
            $last = count($jv_name) - 1;
1445
            foreach ( $jv_name as $p => $n ) {
1446
                $name = trim($n, ']');
1447
                if ( ! isset($l1) ) {
1448
                    $l1 = $name;
1449
                }
1450
1451
                if ( ! isset($l2) ) {
1452
                    $l2 = $name;
1453
                }
1454
1455
                if ( ! isset($l3) ) {
1456
                    $l3 = $name;
1457
                }
1458
1459
                $this_val = ( $p == $last ) ? $jv['value'] : array();
1460
1461
                switch ( $p ) {
1462
                    case 0:
1463
                        $l1 = $name;
1464
                        self::add_value_to_array( $name, $l1, $this_val, $vars );
1465
                    break;
1466
1467
                    case 1:
1468
                        $l2 = $name;
1469
                        self::add_value_to_array( $name, $l2, $this_val, $vars[ $l1 ] );
1470
                    break;
1471
1472 View Code Duplication
                    case 2:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1473
                        $l3 = $name;
1474
                        self::add_value_to_array( $name, $l3, $this_val, $vars[ $l1 ][ $l2 ] );
1475
                    break;
1476
1477 View Code Duplication
                    case 3:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1478
                        $l4 = $name;
1479
                        self::add_value_to_array( $name, $l4, $this_val, $vars[ $l1 ][ $l2 ][ $l3 ] );
1480
                    break;
1481
                }
1482
1483
                unset($this_val, $n);
1484
            }
1485
1486
            unset($last, $jv);
1487
        }
1488
1489
        return $vars;
1490
    }
1491
1492
    /**
1493
     * @param string $name
1494
     * @param string $l1
1495
     */
1496
    public static function add_value_to_array( $name, $l1, $val, &$vars ) {
1497
        if ( $name == '' ) {
1498
            $vars[] = $val;
1499
        } else if ( ! isset( $vars[ $l1 ] ) ) {
1500
            $vars[ $l1 ] = $val;
1501
        }
1502
    }
1503
1504
	public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
1505
        $tooltips = array(
1506
            'action_title'  => __( 'Give this action a label for easy reference.', 'formidable' ),
1507
            'email_to'      => __( 'Add one or more recipient addresses separated by a ",".  FORMAT: Name <[email protected]> or [email protected].  [admin_email] is the address set in WP General Settings.', 'formidable' ),
1508
            'cc'            => __( 'Add CC addresses separated by a ",".  FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
1509
            'bcc'           => __( 'Add BCC addresses separated by a ",".  FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
1510
            'reply_to'      => __( 'If you would like a different reply to address than the "from" address, add a single address here.  FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
1511
            'from'          => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <[email protected]> or [email protected].', 'formidable' ),
1512
            '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() ) ),
1513
        );
1514
1515
        if ( ! isset( $tooltips[ $name ] ) ) {
1516
            return;
1517
        }
1518
1519
        if ( 'open' == $class ) {
1520
            echo ' frm_help"';
1521
        } else {
1522
            echo ' class="frm_help"';
1523
        }
1524
1525
        echo ' title="'. esc_attr( $tooltips[ $name ] );
1526
1527
        if ( 'open' != $class ) {
1528
            echo '"';
1529
        }
1530
    }
1531
1532
	/**
1533
	 * Add the current_page class to that page in the form nav
1534
	 */
1535
	public static function select_current_page( $page, $current_page, $action = array() ) {
1536
		if ( $current_page != $page ) {
1537
			return;
1538
		}
1539
1540
		$frm_action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
1541
		if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
1542
			echo ' class="current_page"';
1543
		}
1544
	}
1545
1546
    /**
1547
     * Prepare and json_encode post content
1548
     *
1549
     * @since 2.0
1550
     *
1551
     * @param array $post_content
1552
     * @return string $post_content ( json encoded array )
1553
     */
1554
    public static function prepare_and_encode( $post_content ) {
1555
        //Loop through array to strip slashes and add only the needed ones
1556
		foreach ( $post_content as $key => $val ) {
1557
			// Replace problematic characters (like &quot;)
1558
			$val = str_replace( '&quot;', '"', $val );
1559
1560
			self::prepare_action_slashes( $val, $key, $post_content );
1561
            unset( $key, $val );
1562
        }
1563
1564
        // json_encode the array
1565
        $post_content = json_encode( $post_content );
1566
1567
	    // add extra slashes for \r\n since WP strips them
1568
		$post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
1569
1570
        // allow for &quot
1571
	    $post_content = str_replace( '&quot;', '\\"', $post_content );
1572
1573
        return $post_content;
1574
    }
1575
1576
	private static function prepare_action_slashes( $val, $key, &$post_content ) {
1577
		if ( ! isset( $post_content[ $key ] ) ) {
1578
			return;
1579
		}
1580
1581
		if ( is_array( $val ) ) {
1582
			foreach ( $val as $k1 => $v1 ) {
1583
				self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
1584
				unset( $k1, $v1 );
1585
			}
1586
		} else {
1587
			// Strip all slashes so everything is the same, no matter where the value is coming from
1588
			$val = stripslashes( $val );
1589
1590
			// Add backslashes before double quotes and forward slashes only
1591
			$post_content[ $key ] = addcslashes( $val, '"\\/' );
1592
		}
1593
	}
1594
1595
	/**
1596
	 * Prepare and save settings in styles and actions
1597
	 *
1598
	 * @param array $settings
1599
	 * @param string $group
1600
	 *
1601
	 * @since 2.0.6
1602
	 */
1603
	public static function save_settings( $settings, $group ) {
1604
		$settings = (array) $settings;
1605
		$settings['post_content'] = FrmAppHelper::prepare_and_encode( $settings['post_content'] );
1606
1607
		if ( empty( $settings['ID'] ) ) {
1608
			unset( $settings['ID']);
1609
		}
1610
1611
		// delete all caches for this group
1612
		self::cache_delete_group( $group );
1613
1614
		return self::save_json_post( $settings );
1615
	}
1616
1617
	/**
1618
	 * Since actions are JSON encoded, we don't want any filters messing with it.
1619
	 * Remove the filters and then add them back in case any posts or views are
1620
	 * also being imported.
1621
	 *
1622
	 * Used when saving form actions and styles
1623
	 *
1624
	 * @since 2.0.4
1625
	 */
1626
	public static function save_json_post( $settings ) {
1627
		global $wp_filter;
1628
		$filters = $wp_filter['content_save_pre'];
1629
1630
		// Remove the balanceTags filter in case WordPress is trying to validate the XHTML
1631
		remove_all_filters( 'content_save_pre' );
1632
1633
		$post = wp_insert_post( $settings );
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1634
1635
		// add the content filters back for views or posts
1636
		$wp_filter['content_save_pre'] = $filters;
1637
1638
		return $post;
1639
	}
1640
1641
	public static function maybe_json_decode( $string ) {
1642
        if ( is_array($string) ) {
1643
            return $string;
1644
        }
1645
1646
        $new_string = json_decode($string, true);
1647
        if ( function_exists('json_last_error') ) {
1648
			// php 5.3+
1649
            if ( json_last_error() == JSON_ERROR_NONE ) {
1650
                $string = $new_string;
1651
            }
1652
        } else if ( isset($new_string) ) {
1653
			// php < 5.3 fallback
1654
            $string = $new_string;
1655
        }
1656
        return $string;
1657
    }
1658
1659
    /**
1660
     * @since 1.07.10
1661
     *
1662
     * @param string $post_type The name of the post type that may need to be highlighted
1663
     * @return echo The javascript to open and highlight the Formidable menu
1664
     */
1665
	public static function maybe_highlight_menu( $post_type ) {
1666
        global $post, $pagenow;
1667
1668
        if ( isset($_REQUEST['post_type']) && $_REQUEST['post_type'] != $post_type ) {
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
1669
            return;
1670
        }
1671
1672
        if ( is_object($post) && $post->post_type != $post_type ) {
1673
            return;
1674
        }
1675
1676
        self::load_admin_wide_js();
1677
        echo '<script type="text/javascript">jQuery(document).ready(function(){frmSelectSubnav();});</script>';
1678
    }
1679
1680
    /**
1681
     * Load the JS file on non-Formidable pages in the admin area
1682
     * @since 2.0
1683
     */
1684
	public static function load_admin_wide_js( $load = true ) {
1685
        $version = FrmAppHelper::plugin_version();
1686
		wp_register_script( 'formidable_admin_global', FrmAppHelper::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
1687
1688
        wp_localize_script( 'formidable_admin_global', 'frmGlobal', array(
1689
			'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
1690
            'deauthorize'  => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
1691
			'url'          => FrmAppHelper::plugin_url(),
1692
			'loading'      => __( 'Loading&hellip;' ),
1693
			'nonce'        => wp_create_nonce( 'frm_ajax' ),
1694
        ) );
1695
1696
		if ( $load ) {
1697
			wp_enqueue_script( 'formidable_admin_global' );
1698
		}
1699
    }
1700
1701
	/**
1702
	 * @since 2.0.9
1703
	 */
1704
	public static function load_font_style() {
1705
		wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
1706
	}
1707
1708
    /**
1709
     * @param string $location
1710
     */
1711
	public static function localize_script( $location ) {
1712
		$ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
1713
		$ajax_url = apply_filters( 'frm_ajax_url', $ajax_url );
1714
1715
		wp_localize_script( 'formidable', 'frm_js', array(
1716
			'ajax_url'  => $ajax_url,
1717
			'images_url' => self::plugin_url() . '/images',
1718
			'loading'   => __( 'Loading&hellip;' ),
1719
			'remove'    => __( 'Remove', 'formidable' ),
1720
			'offset'    => apply_filters( 'frm_scroll_offset', 4 ),
1721
			'nonce'     => wp_create_nonce( 'frm_ajax' ),
1722
			'id'        => __( 'ID', 'formidable' ),
1723
		) );
1724
1725
		if ( $location == 'admin' ) {
1726
			$frm_settings = self::get_settings();
1727
			wp_localize_script( 'formidable_admin', 'frm_admin_js', array(
1728
				'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' ),
1729
				'desc'              => __( '(Click to add description)', 'formidable' ),
1730
				'blank'             => __( '(Blank)', 'formidable' ),
1731
				'no_label'          => __( '(no label)', 'formidable' ),
1732
				'saving'            => esc_attr( __( 'Saving', 'formidable' ) ),
1733
				'saved'             => esc_attr( __( 'Saved', 'formidable' ) ),
1734
				'ok'                => __( 'OK' ),
1735
				'cancel'            => __( 'Cancel', 'formidable' ),
1736
				'default'           => __( 'Default', 'formidable' ),
1737
				'clear_default'     => __( 'Clear default value when typing', 'formidable' ),
1738
				'no_clear_default'  => __( 'Do not clear default value when typing', 'formidable' ),
1739
				'valid_default'     => __( 'Default value will pass form validation', 'formidable' ),
1740
				'no_valid_default'  => __( 'Default value will NOT pass form validation', 'formidable' ),
1741
				'confirm'           => __( 'Are you sure?', 'formidable' ),
1742
				'conf_delete'       => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
1743
				'conf_delete_sec'   => __( 'WARNING: This will delete all fields inside of the section as well.', 'formidable' ),
1744
				'conf_no_repeat'    => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
1745
				'default_unique'    => $frm_settings->unique_msg,
1746
				'default_conf'      => __( 'The entered values do not match', 'formidable' ),
1747
				'enter_email'       => __( 'Enter Email', 'formidable' ),
1748
				'confirm_email'     => __( 'Confirm Email', 'formidable' ),
1749
				'enter_password'    => __( 'Enter Password', 'formidable' ),
1750
				'confirm_password'  => __( 'Confirm Password', 'formidable' ),
1751
				'import_complete'   => __( 'Import Complete', 'formidable' ),
1752
				'updating'          => __( 'Please wait while your site updates.', 'formidable' ),
1753
				'no_save_warning'   => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
1754
				'private'           => __( 'Private' ),
1755
				'jquery_ui_url'     => self::jquery_ui_base_url(),
1756
			) );
1757
		}
1758
	}
1759
1760
    /**
1761
     * @since 1.07.10
1762
     *
1763
     * @param float $min_version The version the add-on requires
1764
     * @return echo The message on the plugins listing page
1765
     */
1766
	public static function min_version_notice( $min_version ) {
1767
        $frm_version = self::plugin_version();
1768
1769
        // check if Formidable meets minimum requirements
1770
        if ( version_compare($frm_version, $min_version, '>=') ) {
1771
            return;
1772
        }
1773
1774
        $wp_list_table = _get_list_table('WP_Plugins_List_Table');
1775
		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">' .
1776
        __( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
1777
        '</div></td></tr>';
1778
    }
1779
1780
    public static function locales( $type = 'date' ) {
1781
        $locales = array(
1782
            'en' => __( 'English', 'formidable' ),    '' => __( 'English/Western', 'formidable' ),
1783
            'af' => __( 'Afrikaans', 'formidable' ),  'sq' => __( 'Albanian', 'formidable' ),
1784
            'ar' => __( 'Arabic', 'formidable' ),     'hy' => __( 'Armenian', 'formidable' ),
1785
            'az' => __( 'Azerbaijani', 'formidable' ), 'eu' => __( 'Basque', 'formidable' ),
1786
            'bs' => __( 'Bosnian', 'formidable' ),    'bg' => __( 'Bulgarian', 'formidable' ),
1787
            'ca' => __( 'Catalan', 'formidable' ),    'zh-HK' => __( 'Chinese Hong Kong', 'formidable' ),
1788
            'zh-CN' => __( 'Chinese Simplified', 'formidable' ), 'zh-TW' => __( 'Chinese Traditional', 'formidable' ),
1789
            'hr' => __( 'Croatian', 'formidable' ),   'cs' => __( 'Czech', 'formidable' ),
1790
            'da' => __( 'Danish', 'formidable' ),     'nl' => __( 'Dutch', 'formidable' ),
1791
            'en-GB' => __( 'English/UK', 'formidable' ), 'eo' => __( 'Esperanto', 'formidable' ),
1792
            'et' => __( 'Estonian', 'formidable' ),   'fo' => __( 'Faroese', 'formidable' ),
1793
            'fa' => __( 'Farsi/Persian', 'formidable' ), 'fil' => __( 'Filipino', 'formidable' ),
1794
            'fi' => __( 'Finnish', 'formidable' ),    'fr' => __( 'French', 'formidable' ),
1795
            'fr-CA' => __( 'French/Canadian', 'formidable' ), 'fr-CH' => __( 'French/Swiss', 'formidable' ),
1796
            'de' => __( 'German', 'formidable' ),     'de-AT' => __( 'German/Austria', 'formidable' ),
1797
            'de-CH' => __( 'German/Switzerland', 'formidable' ), 'el' => __( 'Greek', 'formidable' ),
1798
            'he' => __( 'Hebrew', 'formidable' ),     'iw' => __( 'Hebrew', 'formidable' ),
1799
            'hi' => __( 'Hindi', 'formidable' ),      'hu' => __( 'Hungarian', 'formidable' ),
1800
            'is' => __( 'Icelandic', 'formidable' ),  'id' => __( 'Indonesian', 'formidable' ),
1801
            'it' => __( 'Italian', 'formidable' ),    'ja' => __( 'Japanese', 'formidable' ),
1802
            'ko' => __( 'Korean', 'formidable' ),     'lv' => __( 'Latvian', 'formidable' ),
1803
            'lt' => __( 'Lithuanian', 'formidable' ), 'ms' => __( 'Malaysian', 'formidable' ),
1804
            'no' => __( 'Norwegian', 'formidable' ),  'pl' => __( 'Polish', 'formidable' ),
1805
            'pt' => __( 'Portuguese', 'formidable' ), 'pt-BR' => __( 'Portuguese/Brazilian', 'formidable' ),
1806
            'pt-PT' => __( 'Portuguese/Portugal', 'formidable' ), 'ro' => __( 'Romanian', 'formidable' ),
1807
            'ru' => __( 'Russian', 'formidable' ),    'sr' => __( 'Serbian', 'formidable' ),
1808
            'sr-SR' => __( 'Serbian', 'formidable' ), 'sk' => __( 'Slovak', 'formidable' ),
1809
            'sl' => __( 'Slovenian', 'formidable' ),  'es' => __( 'Spanish', 'formidable' ),
1810
            'es-419' => __( 'Spanish/Latin America', 'formidable' ), 'sv' => __( 'Swedish', 'formidable' ),
1811
            'ta' => __( 'Tamil', 'formidable' ),      'th' => __( 'Thai', 'formidable' ),
1812
            'tu' => __( 'Turkish', 'formidable' ),    'tr' => __( 'Turkish', 'formidable' ),
1813
            'uk' => __( 'Ukranian', 'formidable' ),   'vi' => __( 'Vietnamese', 'formidable' ),
1814
        );
1815
1816
        if ( $type == 'captcha' ) {
1817
            // remove the languages unavailable for the captcha
1818
            $unset = array(
1819
                '', 'af', 'sq', 'hy', 'az', 'eu', 'bs',
1820
                'zh-HK', 'eo', 'et', 'fo', 'fr-CH',
1821
                'he', 'is', 'ms', 'sr-SR', 'ta', 'tu',
1822
            );
1823
        } else {
1824
            // remove the languages unavailable for the datepicker
1825
            $unset = array(
1826
                'en', 'fil', 'fr-CA', 'de-AT', 'de-AT',
1827
                'de-CH', 'iw', 'hi', 'pt', 'pt-PT',
1828
                'es-419', 'tr',
1829
            );
1830
        }
1831
1832
        $locales = array_diff_key($locales, array_flip($unset));
1833
        $locales = apply_filters('frm_locales', $locales);
1834
1835
        return $locales;
1836
    }
1837
}
1838