Completed
Push — master ( 469bb7...e89fdc )
by Stephanie
03:56
created

FrmAppHelper::get_formatted_time()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 23
Code Lines 13

Duplication

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