Completed
Push — master ( 5d7e04...7d6f01 )
by Jamie
03:33
created

FrmAppHelper::jquery_ui_base_url()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 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 = 32; //version of the database we are moving to
8
	public static $pro_db_version = 37;
9
10
	/**
11
	 * @since 2.0
12
	 */
13
	public static $plug_version = '2.02.06';
14
15
    /**
16
     * @since 1.07.02
17
     *
18
     * @param none
19
     * @return string The version of this plugin
20
     */
21
    public static function plugin_version() {
22
        return self::$plug_version;
23
    }
24
25
    public static function plugin_folder() {
26
        return basename(self::plugin_path());
27
    }
28
29
    public static function plugin_path() {
30
        return dirname(dirname(dirname(__FILE__)));
31
    }
32
33
    public static function plugin_url() {
34
        //prevously FRM_URL constant
35
		return plugins_url( '', self::plugin_path() . '/formidable.php' );
36
    }
37
38
	public static function relative_plugin_url() {
39
		return str_replace( array( 'https:', 'http:' ), '', self::plugin_url() );
40
	}
41
42
    /**
43
     * @return string Site URL
44
     */
45
    public static function site_url() {
46
        return site_url();
47
    }
48
49
    /**
50
     * Get the name of this site
51
     * Used for [sitename] shortcode
52
     *
53
     * @since 2.0
54
     * @return string
55
     */
56
    public static function site_name() {
57
        return get_option('blogname');
58
    }
59
60
	public static function make_affiliate_url( $url ) {
61
		$affiliate_id = self::get_affiliate();
62
		if ( ! empty( $affiliate_id ) ) {
63
			$url = add_query_arg( 'aff', $affiliate_id, $url );
64
		}
65
		return $url;
66
	}
67
68
	public static function get_affiliate() {
69
		return '';
70
		$affiliate_id = apply_filters( 'frm_affiliate_link', get_option('frm_aff') );
0 ignored issues
show
Unused Code introduced by
$affiliate_id = apply_fi...get_option('frm_aff')); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

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