Completed
Push — master ( 707409...ea219b )
by Stephanie
10:05
created

FrmAppHelper::get_affiliate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 9
rs 9.6666
cc 2
eloc 7
nc 2
nop 0
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 = 31;
9
10
	/**
11
	 * @since 2.0
12
	 */
13
	public static $plug_version = '2.0.20';
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 ( $affiliate_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $affiliate_id of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

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