Completed
Pull Request — master (#171)
by Stephanie
02:21
created

FrmAppHelper::remove_get_action()   A

Complexity

Conditions 6
Paths 13

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 13
nop 0
dl 0
loc 15
rs 9.2222
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 = 97; //version of the database we are moving to
8
	public static $pro_db_version = 37; //deprecated
9
	public static $font_version = 7;
10
11
	/**
12
	 * @since 2.0
13
	 */
14
	public static $plug_version = '4.05';
15
16
	/**
17
	 * @since 1.07.02
18
	 *
19
	 * @param none
20
	 *
21
	 * @return string The version of this plugin
22
	 */
23
	public static function plugin_version() {
24
		return self::$plug_version;
25
	}
26
27
	public static function plugin_folder() {
28
		return basename( self::plugin_path() );
29
	}
30
31
	public static function plugin_path() {
32
		return dirname( dirname( dirname( __FILE__ ) ) );
33
	}
34
35
	public static function plugin_url() {
36
		// Prevously FRM_URL constant.
37
		return plugins_url( '', self::plugin_path() . '/formidable.php' );
38
	}
39
40
	public static function relative_plugin_url() {
41
		return str_replace( array( 'https:', 'http:' ), '', self::plugin_url() );
42
	}
43
44
	/**
45
	 * @return string Site URL
46
	 */
47
	public static function site_url() {
48
		return site_url();
49
	}
50
51
	/**
52
	 * Get the name of this site
53
	 * Used for [sitename] shortcode
54
	 *
55
	 * @since 2.0
56
	 * @return string
57
	 */
58
	public static function site_name() {
59
		return get_option( 'blogname' );
60
	}
61
62
	public static function make_affiliate_url( $url ) {
63
		$affiliate_id = self::get_affiliate();
64
		if ( ! empty( $affiliate_id ) ) {
65
			$url = str_replace( array( 'http://', 'https://' ), '', $url );
66
			$url = 'http://www.shareasale.com/r.cfm?u=' . absint( $affiliate_id ) . '&b=841990&m=64739&afftrack=plugin&urllink=' . urlencode( $url );
67
		}
68
69
		return $url;
70
	}
71
72
	public static function get_affiliate() {
73
		return absint( apply_filters( 'frm_affiliate_id', 0 ) );
74
	}
75
76
	/**
77
	 * @since 3.04.02
78
	 * @param array|string $args
79
	 * @param string       $page
80
	 */
81
	public static function admin_upgrade_link( $args, $page = '' ) {
82
		if ( empty( $page ) ) {
83
			$page = 'https://formidableforms.com/lite-upgrade/';
84
		} else {
85
			$page = 'https://formidableforms.com/' . $page;
86
		}
87
88
		$anchor = '';
89
		if ( is_array( $args ) ) {
90
			$medium  = $args['medium'];
91
			$content = $args['content'];
92
			if ( isset( $args['anchor'] ) ) {
93
				$anchor = '#' . $args['anchor'];
94
			}
95
		} else {
96
			$medium = $args;
97
		}
98
99
		$query_args = array(
100
			'utm_source'   => 'WordPress',
101
			'utm_medium'   => $medium,
102
			'utm_campaign' => 'liteplugin',
103
		);
104
105
		if ( isset( $content ) ) {
106
			$query_args['utm_content'] = $content;
107
		}
108
109
		if ( is_array( $args ) && isset( $args['param'] ) ) {
110
			$query_args['f'] = $args['param'];
111
		}
112
113
		$link = add_query_arg( $query_args, $page ) . $anchor;
114
		return self::make_affiliate_url( $link );
115
	}
116
117
	/**
118
	 * Get the Formidable settings
119
	 *
120
	 * @since 2.0
121
	 *
122
	 * @param array $args - May include the form id when values need translation.
123
	 * @return FrmSettings $frm_setings
124
	 */
125
	public static function get_settings( $args = array() ) {
126
		global $frm_settings;
127
		if ( empty( $frm_settings ) ) {
128
			$frm_settings = new FrmSettings( $args );
129
		} elseif ( isset( $args['current_form'] ) ) {
130
			// If the global has already been set, allow strings to be filtered.
131
			$frm_settings->maybe_filter_for_form( $args );
132
		}
133
134
		return $frm_settings;
135
	}
136
137
	public static function get_menu_name() {
138
		$frm_settings = self::get_settings();
139
140
		return $frm_settings->menu;
141
	}
142
143
	/**
144
	 * @since 3.05
145
	 */
146
	public static function svg_logo( $atts = array() ) {
147
		$defaults = array(
148
			'height' => 18,
149
			'width'  => 18,
150
			'fill'   => '#4d4d4d',
151
			'orange' => '#f05a24',
152
		);
153
		$atts     = array_merge( $defaults, $atts );
154
155
		return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 599.68 601.37" width="' . esc_attr( $atts['width'] ) . '" height="' . esc_attr( $atts['height'] ) . '">
156
			<path fill="' . esc_attr( $atts['orange'] ) . '" d="M289.6 384h140v76h-140z"/>
157
			<path fill="' . esc_attr( $atts['fill'] ) . '" d="M400.2 147h-200c-17 0-30.6 12.2-30.6 29.3V218h260v-71zM397.9 264H169.6v196h75V340H398a32.2 32.2 0 0 0 30.1-21.4 24.3 24.3 0 0 0 1.7-8.7V264zM299.8 601.4A300.3 300.3 0 0 1 0 300.7a299.8 299.8 0 1 1 511.9 212.6 297.4 297.4 0 0 1-212 88zm0-563A262 262 0 0 0 38.3 300.7a261.6 261.6 0 1 0 446.5-185.5 259.5 259.5 0 0 0-185-76.8z"/>
158
		</svg>';
159
	}
160
161
	/**
162
	 * @since 4.0
163
	 */
164
	public static function show_logo( $atts = array() ) {
165
		echo self::kses( self::svg_logo( $atts ), 'all' ); // WPCS: XSS ok.
166
	}
167
168
	/**
169
	 * @since 4.03.02
170
	 */
171
	public static function show_header_logo() {
172
		$icon = self::svg_logo(
173
			array(
174
				'height' => 35,
175
				'width'  => 35,
176
			)
177
		);
178
179
		$new_icon = apply_filters( 'frm_icon', $icon, true );
180
		if ( $new_icon !== $icon ) {
181
			if ( strpos( $new_icon, '<svg' ) === 0 ) {
182
				$icon = str_replace( 'viewBox="0 0 20', 'width="30" height="35" style="color:#929699" viewBox="0 0 20', $new_icon );
183
			} else {
184
				// Show nothing if it isn't an SVG.
185
				$icon = '<div style="height:39px"></div>';
186
			}
187
		}
188
		echo self::kses( $icon, 'all' ); // WPCS: XSS ok.
189
	}
190
191
	/**
192
	 * @since 2.02.04
193
	 */
194
	public static function ips_saved() {
195
		$frm_settings = self::get_settings();
196
197
		return ! $frm_settings->no_ips;
198
	}
199
200
	public static function pro_is_installed() {
201
		return apply_filters( 'frm_pro_installed', false );
202
	}
203
204
	public static function is_formidable_admin() {
205
		$page          = self::simple_get( 'page', 'sanitize_title' );
206
		$is_formidable = strpos( $page, 'formidable' ) !== false;
207
		if ( empty( $page ) ) {
208
			global $pagenow;
209
			$post_type     = self::simple_get( 'post_type', 'sanitize_title' );
210
			$is_formidable = ( $post_type == 'frm_display' );
211
			if ( empty( $post_type ) && $pagenow == 'post.php' ) {
212
				global $post;
213
				$is_formidable = ( $post && $post->post_type == 'frm_display' );
214
			}
215
		}
216
217
		return $is_formidable;
218
	}
219
220
	/**
221
	 * Check for certain page in Formidable settings
222
	 *
223
	 * @since 2.0
224
	 *
225
	 * @param string $page The name of the page to check
226
	 *
227
	 * @return boolean
228
	 */
229
	public static function is_admin_page( $page = 'formidable' ) {
230
		global $pagenow;
231
		$get_page = self::simple_get( 'page', 'sanitize_title' );
232
		if ( $pagenow ) {
233
			// allow this to be true during ajax load i.e. ajax form builder loading
234
			$is_page = ( $pagenow == 'admin.php' || $pagenow == 'admin-ajax.php' ) && $get_page == $page;
235
			if ( $is_page ) {
236
				return true;
237
			}
238
		}
239
240
		return is_admin() && $get_page == $page;
241
	}
242
243
	/**
244
	 * If the current page is for editing or creating a view.
245
	 * Returns false for the views listing page.
246
	 *
247
	 * @since 4.0
248
	 */
249
	public static function is_view_builder_page() {
250
		global $pagenow;
251
252
		if ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' ) {
253
			return false;
254
		}
255
256
		$post_type = self::simple_get( 'post_type', 'sanitize_title' );
257
258
		if ( empty( $post_type ) ) {
259
			$post_id = self::simple_get( 'post', 'absint' );
260
			$post    = get_post( $post_id );
261
			if ( ! empty( $post ) ) {
262
				$post_type = $post->post_type;
263
			}
264
		}
265
266
		return $post_type === 'frm_display';
267
	}
268
269
	/**
270
	 * Check for the form preview page
271
	 *
272
	 * @since 2.0
273
	 *
274
	 * @param None
275
	 *
276
	 * @return boolean
277
	 */
278
	public static function is_preview_page() {
279
		global $pagenow;
280
		$action = self::simple_get( 'action', 'sanitize_title' );
281
282
		return $pagenow && $pagenow == 'admin-ajax.php' && $action == 'frm_forms_preview';
283
	}
284
285
	/**
286
	 * Check for ajax except the form preview page
287
	 *
288
	 * @since 2.0
289
	 *
290
	 * @param None
291
	 *
292
	 * @return boolean
293
	 */
294
	public static function doing_ajax() {
295
		return wp_doing_ajax() && ! self::is_preview_page();
296
	}
297
298
	public static function js_suffix() {
299
		return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
300
	}
301
302
	/**
303
	 * @since 2.0.8
304
	 */
305
	public static function prevent_caching() {
306
		global $frm_vars;
307
308
		return isset( $frm_vars['prevent_caching'] ) && $frm_vars['prevent_caching'];
309
	}
310
311
	/**
312
	 * Check if on an admin page
313
	 *
314
	 * @since 2.0
315
	 *
316
	 * @param None
317
	 *
318
	 * @return boolean
319
	 */
320
	public static function is_admin() {
321
		return is_admin() && ! wp_doing_ajax();
322
	}
323
324
	/**
325
	 * Check if value contains blank value or empty array
326
	 *
327
	 * @since 2.0
328
	 *
329
	 * @param mixed $value - value to check
330
	 * @param string
331
	 *
332
	 * @return boolean
333
	 */
334
	public static function is_empty_value( $value, $empty = '' ) {
335
		return ( is_array( $value ) && empty( $value ) ) || $value === $empty;
336
	}
337
338
	public static function is_not_empty_value( $value, $empty = '' ) {
339
		return ! self::is_empty_value( $value, $empty );
340
	}
341
342
	/**
343
	 * Get any value from the $_SERVER
344
	 *
345
	 * @since 2.0
346
	 *
347
	 * @param string $value
348
	 *
349
	 * @return string
350
	 */
351
	public static function get_server_value( $value ) {
352
		return isset( $_SERVER[ $value ] ) ? wp_strip_all_tags( wp_unslash( $_SERVER[ $value ] ) ) : '';
353
	}
354
355
	/**
356
	 * Check for the IP address in several places
357
	 * Used by [ip] shortcode
358
	 *
359
	 * @return string The IP address of the current user
360
	 */
361
	public static function get_ip_address() {
362
		$ip_options = array(
363
			'HTTP_CLIENT_IP',
364
			'HTTP_CF_CONNECTING_IP',
365
			'HTTP_X_FORWARDED_FOR',
366
			'HTTP_X_FORWARDED',
367
			'HTTP_X_CLUSTER_CLIENT_IP',
368
			'HTTP_X_REAL_IP',
369
			'HTTP_FORWARDED_FOR',
370
			'HTTP_FORWARDED',
371
			'REMOTE_ADDR',
372
		);
373
		$ip = '';
374
		foreach ( $ip_options as $key ) {
375
			if ( ! isset( $_SERVER[ $key ] ) ) {
376
				continue;
377
			}
378
379
			$key = self::get_server_value( $key );
380
			foreach ( explode( ',', $key ) as $ip ) {
381
				$ip = trim( $ip ); // just to be safe.
382
383
				if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) {
384
					return sanitize_text_field( $ip );
385
				}
386
			}
387
		}
388
389
		return sanitize_text_field( $ip );
390
	}
391
392
	public static function get_param( $param, $default = '', $src = 'get', $sanitize = '' ) {
393
		if ( strpos( $param, '[' ) ) {
394
			$params = explode( '[', $param );
395
			$param  = $params[0];
396
		}
397
398
		if ( $src == 'get' ) {
399
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
400
			$value = isset( $_POST[ $param ] ) ? wp_unslash( $_POST[ $param ] ) : ( isset( $_GET[ $param ] ) ? wp_unslash( $_GET[ $param ] ) : $default );
401
			if ( ! isset( $_POST[ $param ] ) && isset( $_GET[ $param ] ) && ! is_array( $value ) ) {
402
				// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
403
				$value = htmlspecialchars_decode( wp_unslash( $_GET[ $param ] ) );
404
			}
405
			self::sanitize_value( $sanitize, $value );
406
		} else {
407
			$value = self::get_simple_request(
408
				array(
409
					'type'     => $src,
410
					'param'    => $param,
411
					'default'  => $default,
412
					'sanitize' => $sanitize,
413
				)
414
			);
415
		}
416
417
		if ( isset( $params ) && is_array( $value ) && ! empty( $value ) ) {
418
			foreach ( $params as $k => $p ) {
419
				if ( ! $k || ! is_array( $value ) ) {
420
					continue;
421
				}
422
423
				$p     = trim( $p, ']' );
424
				$value = isset( $value[ $p ] ) ? $value[ $p ] : $default;
425
			}
426
		}
427
428
		return $value;
429
	}
430
431 View Code Duplication
	public static function get_post_param( $param, $default = '', $sanitize = '', $serialized = false ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
432
		return self::get_simple_request(
433
			array(
434
				'type'     => 'post',
435
				'param'    => $param,
436
				'default'  => $default,
437
				'sanitize' => $sanitize,
438
				'serialized' => $serialized,
439
			)
440
		);
441
	}
442
443
	/**
444
	 * @since 2.0
445
	 *
446
	 * @param string $param
447
	 * @param string $sanitize
448
	 * @param string $default
449
	 *
450
	 * @return string|array
451
	 */
452 View Code Duplication
	public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
453
		return self::get_simple_request(
454
			array(
455
				'type'     => 'get',
456
				'param'    => $param,
457
				'default'  => $default,
458
				'sanitize' => $sanitize,
459
			)
460
		);
461
	}
462
463
	/**
464
	 * Get a GET/POST/REQUEST value and sanitize it
465
	 *
466
	 * @since 2.0.6
467
	 *
468
	 * @param array $args
469
	 *
470
	 * @return string|array
471
	 */
472
	public static function get_simple_request( $args ) {
473
		$defaults = array(
474
			'param'    => '',
475
			'default'  => '',
476
			'type'     => 'get',
477
			'sanitize' => 'sanitize_text_field',
478
			'serialized' => false,
479
		);
480
		$args     = wp_parse_args( $args, $defaults );
481
482
		$value = $args['default'];
483
		if ( $args['type'] == 'get' ) {
484 View Code Duplication
			if ( $_GET && isset( $_GET[ $args['param'] ] ) ) {
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...
485
				// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
486
				$value = wp_unslash( $_GET[ $args['param'] ] );
487
			}
488
		} elseif ( $args['type'] == 'post' ) {
489
			if ( isset( $_POST[ $args['param'] ] ) ) {
490
				// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
491
				$value = wp_unslash( $_POST[ $args['param'] ] );
492
				if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) {
493
					self::unserialize_or_decode( $value );
494
				}
495
			}
496 View Code Duplication
		} else {
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...
497
			if ( isset( $_REQUEST[ $args['param'] ] ) ) {
498
				// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
499
				$value = wp_unslash( $_REQUEST[ $args['param'] ] );
500
			}
501
		}
502
503
		self::sanitize_value( $args['sanitize'], $value );
504
505
		return $value;
506
	}
507
508
	/**
509
	 * Preserve backslashes in a value, but make sure value doesn't get compounding slashes
510
	 *
511
	 * @since 2.0.8
512
	 *
513
	 * @param string $value
514
	 *
515
	 * @return string $value
516
	 */
517
	public static function preserve_backslashes( $value ) {
518
		// If backslashes have already been added, don't add them again
519
		if ( strpos( $value, '\\\\' ) === false ) {
520
			$value = addslashes( $value );
521
		}
522
523
		return $value;
524
	}
525
526
	public static function sanitize_value( $sanitize, &$value ) {
527
		if ( ! empty( $sanitize ) ) {
528
			if ( is_array( $value ) ) {
529
				$temp_values = $value;
530
				foreach ( $temp_values as $k => $v ) {
531
					self::sanitize_value( $sanitize, $value[ $k ] );
532
				}
533
			} else {
534
				$value = call_user_func( $sanitize, $value );
535
			}
536
		}
537
	}
538
539
	public static function sanitize_request( $sanitize_method, &$values ) {
540
		$temp_values = $values;
541
		foreach ( $temp_values as $k => $val ) {
542
			if ( isset( $sanitize_method[ $k ] ) ) {
543
				$values[ $k ] = call_user_func( $sanitize_method[ $k ], $val );
544
			}
545
		}
546
	}
547
548
	/**
549
	 * @since 4.0.04
550
	 */
551
	public static function sanitize_with_html( &$value ) {
552
		self::sanitize_value( 'wp_kses_post', $value );
553
		self::decode_specialchars( $value );
554
	}
555
556
	/**
557
	 * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&amp;'
558
	 * this MUST be done, else we'll be back to the '& entity' problem.
559
	 *
560
	 * @since 4.0.04
561
	 */
562
	public static function decode_specialchars( &$value ) {
563
		if ( is_array( $value ) ) {
564
			$temp_values = $value;
565
			foreach ( $temp_values as $k => $v ) {
566
				self::decode_specialchars( $value[ $k ] );
567
			}
568
		} else {
569
			self::decode_amp( $value );
570
		}
571
	}
572
573
	/**
574
	 * The wp_specialchars_decode function changes too much.
575
	 * This will leave HTML as is, but still convert &.
576
	 * Adapted from wp_specialchars_decode().
577
	 *
578
	 * @since 4.03.01
579
	 *
580
	 * @param string $string The string to prep.
581
	 */
582
	private static function decode_amp( &$string ) {
583
		// Don't bother if there are no entities - saves a lot of processing
584
		if ( empty( $string ) || strpos( $string, '&' ) === false ) {
585
			return;
586
		}
587
588
		$translation = array(
589
			'&quot;'  => '"',
590
			'&#034;'  => '"',
591
			'&#x22;'  => '"',
592
			'&lt; '   => '< ', // The space preserves the HTML.
593
			'&#060; ' => '< ', // The space preserves the HTML.
594
			'&gt;'    => '>',
595
			'&#062;'  => '>',
596
			'&amp;'   => '&',
597
			'&#038;'  => '&',
598
			'&#x26;'  => '&',
599
		);
600
601
		$translation_preg = array(
602
			'/&#0*34;/'   => '&#034;',
603
			'/&#x0*22;/i' => '&#x22;',
604
			'/&#0*60;/'   => '&#060;',
605
			'/&#0*62;/'   => '&#062;',
606
			'/&#0*38;/'   => '&#038;',
607
			'/&#x0*26;/i' => '&#x26;',
608
		);
609
610
		// Remove zero padding on numeric entities
611
		$string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string );
612
613
		// Replace characters according to translation table
614
		$string = strtr( $string, $translation );
615
	}
616
617
	/**
618
	 * Sanitize the value, and allow some HTML
619
	 *
620
	 * @since 2.0
621
	 *
622
	 * @param string $value
623
	 * @param array|string $allowed 'all' for everything included as defaults
624
	 *
625
	 * @return string
626
	 */
627
	public static function kses( $value, $allowed = array() ) {
628
		$allowed_html = self::allowed_html( $allowed );
629
630
		return wp_kses( $value, $allowed_html );
631
	}
632
633
	/**
634
	 * @since 2.05.03
635
	 */
636
	private static function allowed_html( $allowed ) {
637
		$html         = self::safe_html();
638
		$allowed_html = array();
639
		if ( $allowed == 'all' ) {
640
			$allowed_html = $html;
641
		} elseif ( ! empty( $allowed ) ) {
642
			foreach ( (array) $allowed as $a ) {
643
				$allowed_html[ $a ] = isset( $html[ $a ] ) ? $html[ $a ] : array();
644
			}
645
		}
646
647
		return apply_filters( 'frm_striphtml_allowed_tags', $allowed_html );
648
	}
649
650
	/**
651
	 * @since 2.05.03
652
	 */
653
	private static function safe_html() {
654
		$allow_class = array(
655
			'class' => true,
656
			'id'    => true,
657
		);
658
659
		return array(
660
			'a'          => array(
661
				'class'  => true,
662
				'href'   => true,
663
				'id'     => true,
664
				'rel'    => true,
665
				'target' => true,
666
				'title'  => true,
667
			),
668
			'abbr'       => array(
669
				'title' => true,
670
			),
671
			'aside'      => $allow_class,
672
			'b'          => array(),
673
			'blockquote' => array(
674
				'cite' => true,
675
			),
676
			'br'         => array(),
677
			'cite'       => array(
678
				'title' => true,
679
			),
680
			'code'       => array(),
681
			'defs'       => array(),
682
			'del'        => array(
683
				'datetime' => true,
684
				'title'    => true,
685
			),
686
			'dd'         => array(),
687
			'div'        => array(
688
				'class' => true,
689
				'id'    => true,
690
				'title' => true,
691
				'style' => true,
692
			),
693
			'dl'         => array(),
694
			'dt'         => array(),
695
			'em'         => array(),
696
			'h1'         => $allow_class,
697
			'h2'         => $allow_class,
698
			'h3'         => $allow_class,
699
			'h4'         => $allow_class,
700
			'h5'         => $allow_class,
701
			'h6'         => $allow_class,
702
			'i'          => array(
703
				'class' => true,
704
				'id'    => true,
705
				'icon'  => true,
706
				'style' => true,
707
			),
708
			'img'        => array(
709
				'alt'    => true,
710
				'class'  => true,
711
				'height' => true,
712
				'id'     => true,
713
				'src'    => true,
714
				'width'  => true,
715
			),
716
			'li'         => $allow_class,
717
			'ol'         => $allow_class,
718
			'p'          => $allow_class,
719
			'path'       => array(
720
				'd'    => true,
721
				'fill' => true,
722
			),
723
			'pre'        => array(),
724
			'q'          => array(
725
				'cite'  => true,
726
				'title' => true,
727
			),
728
			'rect'       => array(
729
				'class'  => true,
730
				'fill'   => true,
731
				'height' => true,
732
				'width'  => true,
733
				'x'      => true,
734
				'y'      => true,
735
			),
736
			'section'    => $allow_class,
737
			'span'       => array(
738
				'class' => true,
739
				'id'    => true,
740
				'title' => true,
741
				'style' => true,
742
			),
743
			'strike'     => array(),
744
			'strong'     => array(),
745
			'symbol'     => array(
746
				'class'   => true,
747
				'id'      => true,
748
				'viewbox' => true,
749
			),
750
			'svg'        => array(
751
				'class'   => true,
752
				'id'      => true,
753
				'xmlns'   => true,
754
				'viewbox' => true,
755
				'width'   => true,
756
				'height'  => true,
757
				'style'   => true,
758
			),
759
			'use'        => array(
760
				'href'   => true,
761
				'xlink:href' => true,
762
			),
763
			'ul'         => $allow_class,
764
		);
765
	}
766
767
	/**
768
	 * Used when switching the action for a bulk action
769
	 *
770
	 * @since 2.0
771
	 */
772
	public static function remove_get_action() {
773
		if ( ! isset( $_GET ) ) {
774
			return;
775
		}
776
777
		$action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' );
778
		if ( empty( $action_name ) ) {
779
			return;
780
		}
781
782
		$new_action = self::get_param( $action_name, '', 'get', 'sanitize_text_field' );
783
		if ( ! empty( $new_action ) ) {
784
			$_SERVER['REQUEST_URI'] = str_replace( '&action=' . $new_action, '', self::get_server_value( 'REQUEST_URI' ) );
785
		}
786
	}
787
788
	/**
789
	 * Check the WP query for a parameter
790
	 *
791
	 * @since 2.0
792
	 * @return string|array
793
	 */
794
	public static function get_query_var( $value, $param ) {
795
		if ( $value != '' ) {
796
			return $value;
797
		}
798
799
		global $wp_query;
800
		if ( isset( $wp_query->query_vars[ $param ] ) ) {
801
			$value = $wp_query->query_vars[ $param ];
802
		}
803
804
		return $value;
805
	}
806
807
	/**
808
	 * Try to show the SVG if possible. Otherwise, use the font icon.
809
	 *
810
	 * @since 4.0.02
811
	 * @param string $class
812
	 * @param array  $atts
813
	 */
814
	public static function icon_by_class( $class, $atts = array() ) {
815
		$echo = ! isset( $atts['echo'] ) || $atts['echo'];
816
		if ( isset( $atts['echo'] ) ) {
817
			unset( $atts['echo'] );
818
		}
819
820
		$html_atts = self::array_to_html_params( $atts );
821
822
		$icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) );
823
		if ( $icon === $class ) {
824
			$icon = '<i class="' . esc_attr( $class ) . '"' . $html_atts . '></i>';
825
		} else {
826
			$class = strpos( $icon, ' ' ) === false ? '' : ' ' . $icon;
827
			if ( strpos( $icon, ' ' ) ) {
828
				$icon = explode( ' ', $icon );
829
				$icon = reset( $icon );
830
			}
831
			$icon  = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '>
832
				<use xlink:href="#' . esc_attr( $icon ) . '" />
833
			</svg>';
834
		}
835
836
		if ( $echo ) {
837
			echo $icon; // WPCS: XSS ok.
838
		} else {
839
			return $icon;
840
		}
841
	}
842
843
	/**
844
	 * Include svg images.
845
	 *
846
	 * @since 4.0.02
847
	 */
848
	public static function include_svg() {
849
		include_once( self::plugin_path() . '/images/icons.svg' );
850
	}
851
852
	/**
853
	 * Convert an associative array to HTML values.
854
	 *
855
	 * @since 4.0.02
856
	 * @param array $atts
857
	 * @return string
858
	 */
859
	public static function array_to_html_params( $atts ) {
860
		$html = '';
861
		if ( ! empty( $atts ) ) {
862
			foreach ( $atts as $key => $value ) {
863
				$html .= ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
864
			}
865
		}
866
		return $html;
867
	}
868
869
	/**
870
	 * @since 3.0
871
	 */
872
	public static function get_admin_header( $atts ) {
873
		$has_nav = ( isset( $atts['form'] ) && ! empty( $atts['form'] ) && ( ! isset( $atts['is_template'] ) || ! $atts['is_template'] ) );
874
		if ( ! isset( $atts['close'] ) || empty( $atts['close'] ) ) {
875
			$atts['close'] = admin_url( 'admin.php?page=formidable' );
876
		}
877
		if ( ! isset( $atts['import_link'] ) ) {
878
			$atts['import_link'] = false;
879
		}
880
881
		include( self::plugin_path() . '/classes/views/shared/admin-header.php' );
882
	}
883
884
	/**
885
	 * @since 3.0
886
	 */
887
	public static function add_new_item_link( $atts ) {
888
		if ( isset( $atts['new_link'] ) && ! empty( $atts['new_link'] ) ) { ?>
889
			<a href="<?php echo esc_url( $atts['new_link'] ); ?>" class="button button-primary frm-button-primary frm-with-plus">
890
				<?php self::icon_by_class( 'frmfont frm_plus_icon frm_svg15' ); ?>
891
				<?php esc_html_e( 'Add New', 'formidable' ); ?>
892
			</a>
893
			<?php
894
		} elseif ( isset( $atts['link_hook'] ) ) {
895
			do_action( $atts['link_hook']['hook'], $atts['link_hook']['param'] );
896
		}
897
	}
898
899
	/**
900
	 * @since 3.06
901
	 */
902
	public static function show_search_box( $atts ) {
903
		$defaults = array(
904
			'placeholder' => '',
905
			'tosearch'    => '',
906
			'text'        => __( 'Search', 'formidable' ),
907
			'input_id'    => '',
908
		);
909
		$atts = array_merge( $defaults, $atts );
910
911
		if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
912
			$atts['tosearch'] = 'frm-card';
913
		}
914
915
		$class = 'frm-search-input';
916
		if ( ! empty( $atts['tosearch'] ) ) {
917
			$class .= ' frm-auto-search';
918
		}
919
920
		$input_id = $atts['input_id'] . '-search-input';
921
922
		?>
923
		<p class="frm-search">
924
			<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
925
				<?php echo esc_html( $atts['text'] ); ?>:
926
			</label>
927
			<span class="frmfont frm_search_icon"></span>
928
			<input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s"
929
				value="<?php _admin_search_query(); ?>" placeholder="<?php echo esc_attr( $atts['placeholder'] ); ?>"
930
				class="<?php echo esc_attr( $class ); ?>" data-tosearch="<?php echo esc_attr( $atts['tosearch'] ); ?>"
931
				<?php if ( ! empty( $atts['tosearch'] ) ) { ?>
932
				autocomplete="off"
933
				<?php } ?>
934
				/>
935
			<?php
936
			if ( empty( $atts['tosearch'] ) ) {
937
				submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
938
			}
939
			?>
940
		</p>
941
		<?php
942
	}
943
944
	/**
945
	 * @param string $type
946
	 */
947
	public static function trigger_hook_load( $type, $object = null ) {
948
		// Only load the form hooks once.
949
		$hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
950
		if ( ! $hooks_loaded ) {
951
			do_action( 'frm_load_' . $type . '_hooks' );
952
		}
953
	}
954
955
	/**
956
	 * Save all front-end js scripts into a single file
957
	 *
958
	 * @since 3.0
959
	 */
960
	public static function save_combined_js() {
961
		$file_atts = apply_filters(
962
			'frm_js_location',
963
			array(
964
				'file_name'     => 'frm.min.js',
965
				'new_file_path' => self::plugin_path() . '/js',
966
			)
967
		);
968
		$new_file  = new FrmCreateFile( $file_atts );
969
970
		$files = array(
971
			self::plugin_path() . '/js/jquery/jquery.placeholder.min.js',
972
			self::plugin_path() . '/js/formidable.min.js',
973
		);
974
		$files = apply_filters( 'frm_combined_js_files', $files );
975
		$new_file->combine_files( $files );
976
	}
977
978
	/**
979
	 * Check a value from a shortcode to see if true or false.
980
	 * True when value is 1, true, 'true', 'yes'
981
	 *
982
	 * @since 1.07.10
983
	 *
984
	 * @param string $value The value to compare
985
	 *
986
	 * @return boolean True or False
987
	 */
988
	public static function is_true( $value ) {
989
		return ( true === $value || 1 == $value || 'true' == $value || 'yes' == $value );
990
	}
991
992
	public static function get_pages() {
993
		$query = array(
994
			'post_type'   => 'page',
995
			'post_status' => array( 'publish', 'private' ),
996
			'numberposts' => - 1,
997
			'orderby'     => 'title',
998
			'order'       => 'ASC',
999
		);
1000
1001
		return get_posts( $query );
1002
	}
1003
1004
	/**
1005
	 * Renders an autocomplete page selection or a regular dropdown depending on
1006
	 * the total page count
1007
	 *
1008
	 * @since 4.03.06
1009
	 */
1010
	public static function maybe_autocomplete_pages_options( $args ) {
1011
		$args = self::preformat_selection_args( $args );
1012
1013
		$pages_count = wp_count_posts( 'page' );
1014
1015
		if ( $pages_count->publish <= 50 ) {
1016
			self::wp_pages_dropdown( $args );
1017
			return;
1018
		}
1019
1020
		wp_enqueue_script( 'jquery-ui-autocomplete' );
1021
1022
		$selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
0 ignored issues
show
Security Bug introduced by
It seems like $args['page_id'] can also be of type false; however, FrmAppHelper::get_post_param() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1023
		$title = '';
1024
1025
		if ( $selected ) {
1026
			$title = get_the_title( $selected );
1027
		}
1028
1029
		?>
1030
		<input type="text" class="frm-page-search"
1031
			placeholder="<?php esc_html_e( 'Select a Page', 'formidable' ); ?>"
1032
			value="<?php echo esc_attr( $title ); ?>" />
1033
		<input type="hidden" name="<?php echo esc_attr( $args['field_name'] ); ?>"
1034
			value="<?php echo esc_attr( $selected ); ?>" />
1035
		<?php
1036
	}
1037
1038
	/**
1039
	 * @param array   $args
1040
	 * @param string  $page_id Deprecated.
1041
	 * @param boolean $truncate Deprecated.
1042
	 */
1043
	public static function wp_pages_dropdown( $args = array(), $page_id = '', $truncate = false ) {
1044
		self::prep_page_dropdown_params( $page_id, $truncate, $args );
1045
1046
		$pages    = self::get_pages();
1047
		$selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
1048
1049
		?>
1050
		<select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
1051
			<option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1052
			<?php foreach ( $pages as $page ) { ?>
1053
				<option value="<?php echo esc_attr( $page->ID ); ?>" <?php selected( $selected, $page->ID ); ?>>
1054
					<?php echo esc_html( $args['truncate'] ? self::truncate( $page->post_title, $args['truncate'] ) : $page->post_title ); ?>
1055
				</option>
1056
			<?php } ?>
1057
		</select>
1058
		<?php
1059
	}
1060
1061
	/**
1062
	 * Fill in missing parameters passed to wp_pages_dropdown().
1063
	 * This is for reverse compatibility with switching 3 params to 1.
1064
	 *
1065
	 * @since 4.03.06
1066
	 */
1067
	private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
1068
		if ( ! is_array( $args ) ) {
1069
			$args = array(
1070
				'field_name' => $args,
1071
				'page_id'    => $page_id,
1072
				'truncate'   => $truncate,
1073
			);
1074
		}
1075
1076
		$args = self::preformat_selection_args( $args );
1077
	}
1078
1079
	/**
1080
	 * Filter to format args for page dropdown or autocomplete
1081
	 *
1082
	 * @since 4.03.06
1083
	 */
1084
	private static function preformat_selection_args( $args ) {
1085
		$defaults = array(
1086
			'truncate'    => false,
1087
			'placeholder' => ' ',
1088
			'field_name'  => '',
1089
			'page_id'     => '',
1090
		);
1091
1092
		return array_merge( $defaults, $args );
1093
	}
1094
1095
	public static function post_edit_link( $post_id ) {
1096
		$post = get_post( $post_id );
1097
		if ( $post ) {
1098
			$post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1099
			$post_url = self::maybe_full_screen_link( $post_url );
1100
1101
			return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
1102
		}
1103
1104
		return '';
1105
	}
1106
1107
	/**
1108
	 * Hide the WordPress menus on some pages.
1109
	 *
1110
	 * @since 4.0
1111
	 */
1112
	public static function is_full_screen() {
1113
		$action       = self::simple_get( 'frm_action', 'sanitize_title' );
1114
		$full_builder = self::is_admin_page( 'formidable' ) && ( $action === 'edit' || $action === 'settings' || $action === 'duplicate' );
1115
		$styler       = self::is_admin_page( 'formidable-styles' ) || self::is_admin_page( 'formidable-styles2' );
1116
		$full_entries = self::simple_get( 'frm-full', 'absint' );
1117
1118
		return $full_builder || $full_entries || $styler || self::is_view_builder_page();
1119
	}
1120
1121
	/**
1122
	 * @since 4.0
1123
	 */
1124
	public static function maybe_full_screen_link( $link ) {
1125
		$is_full = self::simple_get( 'frm-full', 'absint' );
1126
		if ( $is_full && ! empty( $link ) && $link !== '#' ) {
1127
			$link .= '&frm-full=1';
1128
		}
1129
		return $link;
1130
	}
1131
1132
	public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
1133
		?>
1134
		<select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
1135
			<?php echo ( 'multiple' === $multiple ) ? 'multiple="multiple"' : ''; ?>
1136
			class="frm_multiselect">
1137
			<?php self::roles_options( $capability ); ?>
1138
		</select>
1139
		<?php
1140
	}
1141
1142
	public static function roles_options( $capability ) {
1143
		global $frm_vars;
1144
		if ( isset( $frm_vars['editable_roles'] ) ) {
1145
			$editable_roles = $frm_vars['editable_roles'];
1146
		} else {
1147
			$editable_roles             = get_editable_roles();
1148
			$frm_vars['editable_roles'] = $editable_roles;
1149
		}
1150
1151
		foreach ( $editable_roles as $role => $details ) {
1152
			$name = translate_user_role( $details['name'] );
1153
			?>
1154
			<option value="<?php echo esc_attr( $role ); ?>" <?php echo in_array( $role, (array) $capability ) ? ' selected="selected"' : ''; ?>><?php echo esc_attr( $name ); ?> </option>
1155
			<?php
1156
			unset( $role, $details );
1157
		}
1158
	}
1159
1160
	public static function frm_capabilities( $type = 'auto' ) {
1161
		$cap = array(
1162
			'frm_view_forms'      => __( 'View Forms', 'formidable' ),
1163
			'frm_edit_forms'      => __( 'Add and Edit Forms', 'formidable' ),
1164
			'frm_delete_forms'    => __( 'Delete Forms', 'formidable' ),
1165
			'frm_change_settings' => __( 'Access this Settings Page', 'formidable' ),
1166
			'frm_view_entries'    => __( 'View Entries from Admin Area', 'formidable' ),
1167
			'frm_delete_entries'  => __( 'Delete Entries from Admin Area', 'formidable' ),
1168
		);
1169
1170
		if ( ! self::pro_is_installed() && 'pro' != $type ) {
1171
			return $cap;
1172
		}
1173
1174
		$cap['frm_create_entries'] = __( 'Add Entries from Admin Area', 'formidable' );
1175
		$cap['frm_edit_entries']   = __( 'Edit Entries from Admin Area', 'formidable' );
1176
		$cap['frm_view_reports']   = __( 'View Reports', 'formidable' );
1177
		$cap['frm_edit_displays']  = __( 'Add/Edit Views', 'formidable' );
1178
1179
		return $cap;
1180
	}
1181
1182
	public static function user_has_permission( $needed_role ) {
1183
		if ( $needed_role == '-1' ) {
1184
			return false;
1185
		}
1186
1187
		// $needed_role will be equal to blank if "Logged-in users" is selected.
1188
		if ( ( $needed_role == '' && is_user_logged_in() ) || current_user_can( $needed_role ) ) {
1189
			return true;
1190
		}
1191
1192
		$roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
1193
		foreach ( $roles as $role ) {
1194
			if ( current_user_can( $role ) ) {
1195
				return true;
1196
			}
1197
			if ( $role == $needed_role ) {
1198
				break;
1199
			}
1200
		}
1201
1202
		return false;
1203
	}
1204
1205
	/**
1206
	 * Make sure administrators can see Formidable menu
1207
	 *
1208
	 * @since 2.0
1209
	 */
1210
	public static function maybe_add_permissions() {
1211
		self::force_capability( 'frm_view_entries' );
1212
1213
		if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
1214
			return;
1215
		}
1216
1217
		$user_id   = get_current_user_id();
1218
		$user      = new WP_User( $user_id );
1219
		$frm_roles = self::frm_capabilities();
1220
		foreach ( $frm_roles as $frm_role => $frm_role_description ) {
1221
			$user->add_cap( $frm_role );
1222
			unset( $frm_role, $frm_role_description );
1223
		}
1224
	}
1225
1226
	/**
1227
	 * Make sure admins have permission to see the menu items
1228
	 *
1229
	 * @since 2.0.6
1230
	 */
1231
	public static function force_capability( $cap = 'frm_change_settings' ) {
1232
		if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
1233
			$role      = get_role( 'administrator' );
1234
			$frm_roles = self::frm_capabilities();
1235
			foreach ( $frm_roles as $frm_role => $frm_role_description ) {
1236
				$role->add_cap( $frm_role );
1237
			}
1238
		}
1239
	}
1240
1241
	/**
1242
	 * Check if the user has permision for action.
1243
	 * Return permission message and stop the action if no permission
1244
	 *
1245
	 * @since 2.0
1246
	 *
1247
	 * @param string $permission
1248
	 */
1249
	public static function permission_check( $permission, $show_message = 'show' ) {
1250
		$permission_error = self::permission_nonce_error( $permission );
1251
		if ( $permission_error !== false ) {
1252
			if ( 'hide' == $show_message ) {
1253
				$permission_error = '';
1254
			}
1255
			wp_die( esc_html( $permission_error ) );
1256
		}
1257
	}
1258
1259
	/**
1260
	 * Check user permission and nonce
1261
	 *
1262
	 * @since 2.0
1263
	 *
1264
	 * @param string $permission
1265
	 *
1266
	 * @return false|string The permission message or false if allowed
1267
	 */
1268
	public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
1269
		if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
1270
			$frm_settings = self::get_settings();
1271
1272
			return $frm_settings->admin_permission;
1273
		}
1274
1275
		$error = false;
1276
		if ( empty( $nonce_name ) ) {
1277
			return $error;
1278
		}
1279
1280
		$nonce_value = ( $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
1281
		if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
1282
			$frm_settings = self::get_settings();
1283
			$error        = $frm_settings->admin_permission;
1284
		}
1285
1286
		return $error;
1287
	}
1288
1289
	public static function checked( $values, $current ) {
1290
		if ( self::check_selected( $values, $current ) ) {
1291
			echo ' checked="checked"';
1292
		}
1293
	}
1294
1295
	public static function check_selected( $values, $current ) {
1296
		$values  = self::recursive_function_map( $values, 'trim' );
1297
		$values  = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
1298
		$current = htmlspecialchars_decode( trim( $current ) );
1299
1300
		return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
1301
	}
1302
1303
	public static function recursive_function_map( $value, $function ) {
1304
		if ( is_array( $value ) ) {
1305
			$original_function = $function;
1306
			if ( count( $value ) ) {
1307
				$function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
1308
			} else {
1309
				$function = array( $function );
1310
			}
1311
			if ( ! self::is_assoc( $value ) ) {
1312
				$value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
1313
			} else {
1314
				foreach ( $value as $k => $v ) {
1315
					if ( ! is_array( $v ) ) {
1316
						$value[ $k ] = call_user_func( $original_function, $v );
1317
					}
1318
				}
1319
			}
1320
		} else {
1321
			$value = call_user_func( $function, $value );
1322
		}
1323
1324
		return $value;
1325
	}
1326
1327
	public static function is_assoc( $array ) {
1328
		return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
1329
	}
1330
1331
	/**
1332
	 * Flatten a multi-dimensional array
1333
	 */
1334
	public static function array_flatten( $array, $keys = 'keep' ) {
1335
		$return = array();
1336
		foreach ( $array as $key => $value ) {
1337
			if ( is_array( $value ) ) {
1338
				$return = array_merge( $return, self::array_flatten( $value, $keys ) );
1339
			} else {
1340
				if ( $keys == 'keep' ) {
1341
					$return[ $key ] = $value;
1342
				} else {
1343
					$return[] = $value;
1344
				}
1345
			}
1346
		}
1347
1348
		return $return;
1349
	}
1350
1351
	public static function esc_textarea( $text, $is_rich_text = false ) {
1352
		$safe_text = str_replace( '&quot;', '"', $text );
1353
		if ( ! $is_rich_text ) {
1354
			$safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
1355
		}
1356
		$safe_text = str_replace( '&amp; ', '& ', $safe_text );
1357
1358
		return apply_filters( 'esc_textarea', $safe_text, $text );
1359
	}
1360
1361
	/**
1362
	 * Add auto paragraphs to text areas
1363
	 *
1364
	 * @since 2.0
1365
	 */
1366
	public static function use_wpautop( $content ) {
1367
		if ( apply_filters( 'frm_use_wpautop', true ) && ! is_array( $content ) ) {
1368
			$content = wpautop( str_replace( '<br>', '<br />', $content ) );
1369
		}
1370
1371
		return $content;
1372
	}
1373
1374
	public static function replace_quotes( $val ) {
1375
		// Replace double quotes.
1376
		$val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
1377
1378
		// Replace single quotes.
1379
		$val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
1380
1381
		return $val;
1382
	}
1383
1384
	/**
1385
	 * @since 2.0
1386
	 * @return string The base Google APIS url for the current version of jQuery UI
1387
	 */
1388
	public static function jquery_ui_base_url() {
1389
		$url = 'http' . ( is_ssl() ? 's' : '' ) . '://ajax.googleapis.com/ajax/libs/jqueryui/' . self::script_version( 'jquery-ui-core', '1.11.4' );
1390
		$url = apply_filters( 'frm_jquery_ui_base_url', $url );
1391
1392
		return $url;
1393
	}
1394
1395
	/**
1396
	 * @param string $handle
1397
	 */
1398
	public static function script_version( $handle, $default = 0 ) {
1399
		global $wp_scripts;
1400
		if ( ! $wp_scripts ) {
1401
			return $default;
1402
		}
1403
1404
		$ver = $default;
1405
		if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
1406
			return $ver;
1407
		}
1408
1409
		$query = $wp_scripts->registered[ $handle ];
1410
		if ( is_object( $query ) && ! empty( $query->ver ) ) {
1411
			$ver = $query->ver;
1412
		}
1413
1414
		return $ver;
1415
	}
1416
1417
	public static function js_redirect( $url ) {
1418
		return '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>';
1419
	}
1420
1421
	public static function get_user_id_param( $user_id ) {
1422
		if ( ! $user_id || empty( $user_id ) || is_numeric( $user_id ) ) {
1423
			return $user_id;
1424
		}
1425
1426
		$user_id = sanitize_text_field( $user_id );
1427
		if ( $user_id == 'current' ) {
1428
			$user_id = get_current_user_id();
1429
		} else {
1430
			if ( is_email( $user_id ) ) {
1431
				$user = get_user_by( 'email', $user_id );
1432
			} else {
1433
				$user = get_user_by( 'login', $user_id );
1434
			}
1435
1436
			if ( $user ) {
1437
				$user_id = $user->ID;
1438
			}
1439
			unset( $user );
1440
		}
1441
1442
		return $user_id;
1443
	}
1444
1445
	public static function get_file_contents( $filename, $atts = array() ) {
1446
		if ( ! is_file( $filename ) ) {
1447
			return false;
1448
		}
1449
1450
		extract( $atts );
1451
		ob_start();
1452
		include( $filename );
1453
		$contents = ob_get_contents();
1454
		ob_end_clean();
1455
1456
		return $contents;
1457
	}
1458
1459
	/**
1460
	 * @param string $table_name
1461
	 * @param string $column
1462
	 * @param int $id
1463
	 * @param int $num_chars
1464
	 */
1465
	public static function get_unique_key( $name = '', $table_name, $column, $id = 0, $num_chars = 5 ) {
1466
		$key = '';
1467
1468
		if ( ! empty( $name ) ) {
1469
			$key = sanitize_key( $name );
1470
		}
1471
1472
		if ( empty( $key ) ) {
1473
			$max_slug_value = pow( 36, $num_chars );
1474
			$min_slug_value = 37; // we want to have at least 2 characters in the slug
1475
			$key            = base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
1476
		}
1477
1478
		$not_allowed = array(
1479
			'id',
1480
			'key',
1481
			'created-at',
1482
			'detaillink',
1483
			'editlink',
1484
			'siteurl',
1485
			'evenodd',
1486
		);
1487
1488
		if ( is_numeric( $key ) || in_array( $key, $not_allowed ) ) {
1489
			$key = $key . 'a';
1490
		}
1491
1492
		$key_check = FrmDb::get_var(
1493
			$table_name,
1494
			array(
1495
				$column => $key,
1496
				'ID !'  => $id,
1497
			),
1498
			$column
1499
		);
1500
1501
		if ( $key_check || is_numeric( $key_check ) ) {
1502
			// Create a unique field id if it has already been used.
1503
			$key = $key . substr( md5( microtime() . rand() ), 0, 10 );
1504
		}
1505
1506
		return $key;
1507
	}
1508
1509
	/**
1510
	 * Editing a Form or Entry
1511
	 *
1512
	 * @param string $table
1513
	 *
1514
	 * @return bool|array
1515
	 */
1516
	public static function setup_edit_vars( $record, $table, $fields = '', $default = false, $post_values = array(), $args = array() ) {
1517
		if ( ! $record ) {
1518
			return false;
1519
		}
1520
1521
		if ( empty( $post_values ) ) {
1522
			$post_values = wp_unslash( $_POST );
1523
		}
1524
1525
		$values = array(
1526
			'id'     => $record->id,
1527
			'fields' => array(),
1528
		);
1529
1530
		foreach ( array( 'name', 'description' ) as $var ) {
1531
			$default_val    = isset( $record->{$var} ) ? $record->{$var} : '';
1532
			$values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
1533
			unset( $var, $default_val );
1534
		}
1535
1536
		$values['description'] = self::use_wpautop( $values['description'] );
1537
1538
		self::fill_form_opts( $record, $table, $post_values, $values );
1539
1540
		self::prepare_field_arrays( $fields, $record, $values, array_merge( $args, compact( 'default', 'post_values' ) ) );
1541
1542
		if ( $table == 'entries' ) {
1543
			$values = FrmEntriesHelper::setup_edit_vars( $values, $record );
1544
		} elseif ( $table == 'forms' ) {
1545
			$values = FrmFormsHelper::setup_edit_vars( $values, $record, $post_values );
1546
		}
1547
1548
		return $values;
1549
	}
1550
1551
	private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
1552
		if ( ! empty( $fields ) ) {
1553
			foreach ( (array) $fields as $field ) {
1554
				if ( ! self::is_admin_page() ) {
1555
					// Don't prep default values on the form settings page.
1556
					$field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
1557
				}
1558
				$args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
1559
				self::fill_field_defaults( $field, $record, $values, $args );
1560
			}
1561
		}
1562
	}
1563
1564
	private static function fill_field_defaults( $field, $record, array &$values, $args ) {
1565
		$post_values = $args['post_values'];
1566
1567
		if ( $args['default'] ) {
1568
			$meta_value = $field->default_value;
1569
		} else {
1570
			if ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) {
1571
				if ( ! isset( $field->field_options['custom_field'] ) ) {
1572
					$field->field_options['custom_field'] = '';
1573
				}
1574
				$meta_value = FrmProEntryMetaHelper::get_post_value(
1575
					$record->post_id,
1576
					$field->field_options['post_field'],
1577
					$field->field_options['custom_field'],
1578
					array(
1579
						'truncate' => false,
1580
						'type'     => $field->type,
1581
						'form_id'  => $field->form_id,
1582
						'field'    => $field,
1583
					)
1584
				);
1585
			} else {
1586
				$meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
1587
			}
1588
		}
1589
1590
		$field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
1591
		if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
1592
			$new_value = $post_values['item_meta'][ $field->id ];
1593
			self::unserialize_or_decode( $new_value );
1594
		} else {
1595
			$new_value = $meta_value;
1596
		}
1597
1598
		$field_array                   = self::start_field_array( $field );
1599
		$field_array['value']          = $new_value;
1600
		$field_array['type']           = apply_filters( 'frm_field_type', $field_type, $field, $new_value );
1601
		$field_array['parent_form_id'] = $args['parent_form_id'];
1602
1603
		$args['field_type'] = $field_type;
1604
1605
		FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
1606
1607
		if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
1608
			$field_array['unique_msg'] = '';
1609
		}
1610
1611
		$field_array = array_merge( (array) $field->field_options, $field_array );
1612
1613
		$values['fields'][ $field->id ] = $field_array;
1614
	}
1615
1616
	/**
1617
	 * @since 3.0
1618
	 *
1619
	 * @param object $field
1620
	 *
1621
	 * @return array
1622
	 */
1623
	public static function start_field_array( $field ) {
1624
		return array(
1625
			'id'            => $field->id,
1626
			'default_value' => $field->default_value,
1627
			'name'          => $field->name,
1628
			'description'   => $field->description,
1629
			'options'       => $field->options,
1630
			'required'      => $field->required,
1631
			'field_key'     => $field->field_key,
1632
			'field_order'   => $field->field_order,
1633
			'form_id'       => $field->form_id,
1634
		);
1635
	}
1636
1637
	/**
1638
	 * @param string $table
1639
	 */
1640
	private static function fill_form_opts( $record, $table, $post_values, array &$values ) {
1641
		if ( $table == 'entries' ) {
1642
			$form = $record->form_id;
1643
			FrmForm::maybe_get_form( $form );
1644
		} else {
1645
			$form = $record;
1646
		}
1647
1648
		if ( ! $form ) {
1649
			return;
1650
		}
1651
1652
		$values['form_name']      = isset( $record->form_id ) ? $form->name : '';
1653
		$values['parent_form_id'] = isset( $record->form_id ) ? $form->parent_form_id : 0;
1654
1655
		if ( ! is_array( $form->options ) ) {
1656
			return;
1657
		}
1658
1659
		foreach ( $form->options as $opt => $value ) {
1660
			if ( isset( $post_values[ $opt ] ) ) {
1661
				$values[ $opt ] = $post_values[ $opt ];
1662
				self::unserialize_or_decode( $values[ $opt ] );
1663
			} else {
1664
				$values[ $opt ] = $value;
1665
			}
1666
		}
1667
1668
		self::fill_form_defaults( $post_values, $values );
1669
	}
1670
1671
	/**
1672
	 * Set to POST value or default
1673
	 */
1674
	private static function fill_form_defaults( $post_values, array &$values ) {
1675
		$form_defaults = FrmFormsHelper::get_default_opts();
1676
1677
		foreach ( $form_defaults as $opt => $default ) {
1678
			if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
1679
				$values[ $opt ] = ( $post_values && isset( $post_values['options'][ $opt ] ) ) ? $post_values['options'][ $opt ] : $default;
1680
			}
1681
1682
			unset( $opt, $default );
1683
		}
1684
1685
		if ( ! isset( $values['custom_style'] ) ) {
1686
			$values['custom_style'] = self::custom_style_value( $post_values );
1687
		}
1688
1689
		foreach ( array( 'before', 'after', 'submit' ) as $h ) {
1690
			if ( ! isset( $values[ $h . '_html' ] ) ) {
1691
				$values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
1692
			}
1693
			unset( $h );
1694
		}
1695
	}
1696
1697
	/**
1698
	 * @since 2.2.10
1699
	 *
1700
	 * @param array $post_values
1701
	 *
1702
	 * @return boolean|int
1703
	 */
1704
	public static function custom_style_value( $post_values ) {
1705
		if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
1706
			$custom_style = absint( $post_values['options']['custom_style'] );
1707
		} else {
1708
			$frm_settings = self::get_settings();
1709
			$custom_style = ( $frm_settings->load_style != 'none' );
1710
		}
1711
1712
		return $custom_style;
1713
	}
1714
1715
	public static function truncate( $str, $length, $minword = 3, $continue = '...' ) {
1716
		if ( is_array( $str ) ) {
1717
			return '';
1718
		}
1719
1720
		$length       = (int) $length;
1721
		$str          = wp_strip_all_tags( $str );
1722
		$original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
1723
1724
		if ( $length == 0 ) {
1725
			return '';
1726
		} elseif ( $length <= 10 ) {
1727
			$sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
1728
1729
			return $sub . ( ( $length < $original_len ) ? $continue : '' );
1730
		}
1731
1732
		$sub = '';
1733
		$len = 0;
1734
1735
		$words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
1736
1737
		foreach ( $words as $word ) {
1738
			$part      = ( ( $sub != '' ) ? ' ' : '' ) . $word;
1739
			$total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
1740
			if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
1741
				break;
1742
			}
1743
1744
			$sub .= $part;
1745
			$len += self::mb_function( array( 'mb_strlen', 'strlen' ), array( $part ) );
1746
1747
			if ( substr_count( $sub, ' ' ) > $minword && $total_len >= $length ) {
1748
				break;
1749
			}
1750
1751
			unset( $total_len, $word );
1752
		}
1753
1754
		return $sub . ( ( $len < $original_len ) ? $continue : '' );
1755
	}
1756
1757
	public static function mb_function( $function_names, $args ) {
1758
		$mb_function_name = $function_names[0];
1759
		$function_name    = $function_names[1];
1760
		if ( function_exists( $mb_function_name ) ) {
1761
			$function_name = $mb_function_name;
1762
		}
1763
1764
		return call_user_func_array( $function_name, $args );
1765
	}
1766
1767
	public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
1768
		if ( empty( $date ) ) {
1769
			return $date;
1770
		}
1771
1772
		if ( empty( $date_format ) ) {
1773
			$date_format = get_option( 'date_format' );
1774
		}
1775
1776
		if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
1777
			$frmpro_settings = new FrmProSettings();
1778
			$date            = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
1779
		}
1780
1781
		$formatted = self::get_localized_date( $date_format, $date );
1782
1783
		$do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
1784
		if ( $do_time ) {
1785
			$formatted .= self::add_time_to_date( $time_format, $date );
1786
		}
1787
1788
		return $formatted;
1789
	}
1790
1791
	private static function add_time_to_date( $time_format, $date ) {
1792
		if ( empty( $time_format ) ) {
1793
			$time_format = get_option( 'time_format' );
1794
		}
1795
1796
		$trimmed_format = trim( $time_format );
1797
		$time           = '';
1798
		if ( $time_format && ! empty( $trimmed_format ) ) {
1799
			$time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
1800
		}
1801
1802
		return $time;
1803
	}
1804
1805
	/**
1806
	 * @since 2.0.8
1807
	 */
1808
	public static function get_localized_date( $date_format, $date ) {
1809
		$date = get_date_from_gmt( $date );
1810
1811
		return date_i18n( $date_format, strtotime( $date ) );
1812
	}
1813
1814
	/**
1815
	 * Gets the time ago in words
1816
	 *
1817
	 * @param int $from in seconds
1818
	 * @param int|string $to in seconds
1819
	 *
1820
	 * @return string $time_ago
1821
	 */
1822
	public static function human_time_diff( $from, $to = '', $levels = 1 ) {
1823
		if ( empty( $to ) ) {
1824
			$now = new DateTime();
1825
		} else {
1826
			$now = new DateTime( '@' . $to );
1827
		}
1828
		$ago = new DateTime( '@' . $from );
1829
1830
		// Get the time difference
1831
		$diff_object = $now->diff( $ago );
1832
		$diff        = get_object_vars( $diff_object );
1833
1834
		// Add week amount and update day amount
1835
		$diff['w'] = floor( $diff['d'] / 7 );
1836
		$diff['d'] -= $diff['w'] * 7;
1837
1838
		$time_strings = self::get_time_strings();
1839
1840
		if ( ! is_numeric( $levels ) ) {
1841
			// Show time in specified unit.
1842
			$levels = self::get_unit( $levels );
1843
			if ( isset( $time_strings[ $levels ] ) ) {
1844
				$diff = array(
1845
					$levels => self::time_format( $levels, $diff ),
1846
				);
1847
				$time_strings = array(
1848
					$levels => $time_strings[ $levels ],
1849
				);
1850
			}
1851
			$levels = 1;
1852
		}
1853
1854
		foreach ( $time_strings as $k => $v ) {
1855
			if ( isset( $diff[ $k ] ) && $diff[ $k ] ) {
1856
				$time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
1857
			} elseif ( isset( $diff[ $k ] ) && count( $time_strings ) === 1 ) {
1858
				// Account for 0.
1859
				$time_strings[ $k ] = $diff[ $k ] . ' ' . $v[1];
1860
			} else {
1861
				unset( $time_strings[ $k ] );
1862
			}
1863
		}
1864
1865
		$levels_deep     = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
1866
		$time_strings    = array_slice( $time_strings, 0, $levels_deep );
1867
		$time_ago_string = implode( ' ', $time_strings );
1868
1869
		return $time_ago_string;
1870
	}
1871
1872
	/**
1873
	 * @since 4.05.01
1874
	 */
1875
	private static function time_format( $unit, $diff ) {
1876
		$return = array(
1877
			'y' => 'y',
1878
			'd' => 'days',
1879
		);
1880
		if ( isset( $return[ $unit ] ) ) {
1881
			return $diff[ $return[ $unit ] ];
1882
		}
1883
1884
		$total = $diff['days'] * self::convert_time( 'd', $unit );
1885
1886
		$times = array( 'h', 'i', 's' );
1887
1888
		foreach ( $times as $time ) {
1889
			if ( ! isset( $diff[ $time ] ) ) {
1890
				continue;
1891
			}
1892
1893
			$total += $diff[ $time ] * self::convert_time( $time, $unit );
1894
		}
1895
1896
		return floor( $total );
1897
	}
1898
1899
	/**
1900
	 * @since 4.05.01
1901
	 */
1902
	private static function convert_time( $from, $to ) {
1903
		$convert = array(
1904
			's' => 1,
1905
			'i' => MINUTE_IN_SECONDS,
1906
			'h' => HOUR_IN_SECONDS,
1907
			'd' => DAY_IN_SECONDS,
1908
			'w' => WEEK_IN_SECONDS,
1909
			'm' => DAY_IN_SECONDS * 30.42,
1910
			'y' => DAY_IN_SECONDS * 365.25,
1911
		);
1912
1913
		return $convert[ $from ] / $convert[ $to ];
1914
	}
1915
1916
	/**
1917
	 * @since 4.05.01
1918
	 */
1919
	private static function get_unit( $unit ) {
1920
		$units = self::get_time_strings();
1921
		if ( isset( $units[ $unit ] ) || is_numeric( $unit ) ) {
1922
			return $unit;
1923
		}
1924
1925
		foreach ( $units as $u => $strings ) {
1926
			if ( in_array( $unit, $strings ) ) {
1927
				return $u;
1928
			}
1929
		}
1930
	}
1931
1932
	/**
1933
	 * Get the translatable time strings
1934
	 *
1935
	 * @since 2.0.20
1936
	 * @return array
1937
	 */
1938
	private static function get_time_strings() {
1939
		return array(
1940
			'y' => array( __( 'year', 'formidable' ), __( 'years', 'formidable' ) ),
1941
			'm' => array( __( 'month', 'formidable' ), __( 'months', 'formidable' ) ),
1942
			'w' => array( __( 'week', 'formidable' ), __( 'weeks', 'formidable' ) ),
1943
			'd' => array( __( 'day', 'formidable' ), __( 'days', 'formidable' ) ),
1944
			'h' => array( __( 'hour', 'formidable' ), __( 'hours', 'formidable' ) ),
1945
			'i' => array( __( 'minute', 'formidable' ), __( 'minutes', 'formidable' ) ),
1946
			's' => array( __( 'second', 'formidable' ), __( 'seconds', 'formidable' ) ),
1947
		);
1948
	}
1949
1950
	// Pagination Methods.
1951
1952
	/**
1953
	 * @param integer $current_p
1954
	 */
1955
	public static function get_last_record_num( $r_count, $current_p, $p_size ) {
1956
		return ( ( $r_count < ( $current_p * $p_size ) ) ? $r_count : ( $current_p * $p_size ) );
1957
	}
1958
1959
	/**
1960
	 * @param integer $current_p
1961
	 */
1962
	public static function get_first_record_num( $r_count, $current_p, $p_size ) {
1963
		if ( $current_p == 1 ) {
1964
			return 1;
1965
		} else {
1966
			return ( self::get_last_record_num( $r_count, ( $current_p - 1 ), $p_size ) + 1 );
1967
		}
1968
	}
1969
1970
	/**
1971
	 * @return array
1972
	 */
1973
	public static function json_to_array( $json_vars ) {
1974
		$vars = array();
1975
		foreach ( $json_vars as $jv ) {
1976
			$jv_name = explode( '[', $jv['name'] );
1977
			$last    = count( $jv_name ) - 1;
1978
			foreach ( $jv_name as $p => $n ) {
1979
				$name = trim( $n, ']' );
1980
				if ( ! isset( $l1 ) ) {
1981
					$l1 = $name;
1982
				}
1983
1984
				if ( ! isset( $l2 ) ) {
1985
					$l2 = $name;
1986
				}
1987
1988
				if ( ! isset( $l3 ) ) {
1989
					$l3 = $name;
1990
				}
1991
1992
				$this_val = ( $p == $last ) ? $jv['value'] : array();
1993
1994
				switch ( $p ) {
1995
					case 0:
1996
						$l1 = $name;
1997
						self::add_value_to_array( $name, $l1, $this_val, $vars );
1998
						break;
1999
2000
					case 1:
2001
						$l2 = $name;
2002
						self::add_value_to_array( $name, $l2, $this_val, $vars[ $l1 ] );
2003
						break;
2004
2005 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...
2006
						$l3 = $name;
2007
						self::add_value_to_array( $name, $l3, $this_val, $vars[ $l1 ][ $l2 ] );
2008
						break;
2009
2010 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...
2011
						$l4 = $name;
2012
						self::add_value_to_array( $name, $l4, $this_val, $vars[ $l1 ][ $l2 ][ $l3 ] );
2013
				}
2014
2015
				unset( $this_val, $n );
2016
			}
2017
2018
			unset( $last, $jv );
2019
		}
2020
2021
		return $vars;
2022
	}
2023
2024
	/**
2025
	 * @param string $name
2026
	 * @param string $l1
2027
	 */
2028
	public static function add_value_to_array( $name, $l1, $val, &$vars ) {
2029
		if ( $name == '' ) {
2030
			$vars[] = $val;
2031
		} elseif ( ! isset( $vars[ $l1 ] ) ) {
2032
			$vars[ $l1 ] = $val;
2033
		}
2034
	}
2035
2036
	public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
2037
		$tooltips = array(
2038
			'action_title'  => __( 'Give this action a label for easy reference.', 'formidable' ),
2039
			'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' ),
2040
			'cc'            => __( 'Add CC addresses separated by a ",".  FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
2041
			'bcc'           => __( 'Add BCC addresses separated by a ",".  FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
2042
			'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' ),
2043
			'from'          => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <[email protected]> or [email protected].', 'formidable' ),
2044
			/* translators: %1$s: Form name, %2$s: Date */
2045
			'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() ) ),
2046
		);
2047
2048
		if ( ! isset( $tooltips[ $name ] ) ) {
2049
			return;
2050
		}
2051
2052
		if ( 'open' == $class ) {
2053
			echo ' frm_help"';
2054
		} else {
2055
			echo ' class="frm_help"';
2056
		}
2057
2058
		echo ' title="' . esc_attr( $tooltips[ $name ] );
2059
2060
		if ( 'open' != $class ) {
2061
			echo '"';
2062
		}
2063
	}
2064
2065
	/**
2066
	 * Add the current_page class to that page in the form nav
2067
	 */
2068
	public static function select_current_page( $page, $current_page, $action = array() ) {
2069
		if ( $current_page != $page ) {
2070
			return;
2071
		}
2072
2073
		$frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
2074
		if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
2075
			echo ' class="current_page"';
2076
		}
2077
	}
2078
2079
	/**
2080
	 * Prepare and json_encode post content
2081
	 *
2082
	 * @since 2.0
2083
	 *
2084
	 * @param array $post_content
2085
	 *
2086
	 * @return string $post_content ( json encoded array )
2087
	 */
2088
	public static function prepare_and_encode( $post_content ) {
2089
		// Loop through array to strip slashes and add only the needed ones.
2090
		foreach ( $post_content as $key => $val ) {
2091
			// Replace problematic characters (like &quot;)
2092
			$val = str_replace( '&quot;', '"', $val );
2093
2094
			self::prepare_action_slashes( $val, $key, $post_content );
2095
			unset( $key, $val );
2096
		}
2097
2098
		// json_encode the array.
2099
		$post_content = json_encode( $post_content );
2100
2101
		// Add extra slashes for \r\n since WP strips them.
2102
		$post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
2103
2104
		// allow for &quot
2105
		$post_content = str_replace( '&quot;', '\\"', $post_content );
2106
2107
		return $post_content;
2108
	}
2109
2110
	private static function prepare_action_slashes( $val, $key, &$post_content ) {
2111
		if ( ! isset( $post_content[ $key ] ) ) {
2112
			return;
2113
		}
2114
2115
		if ( is_array( $val ) ) {
2116
			foreach ( $val as $k1 => $v1 ) {
2117
				self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
2118
				unset( $k1, $v1 );
2119
			}
2120
		} else {
2121
			// Strip all slashes so everything is the same, no matter where the value is coming from
2122
			$val = stripslashes( $val );
2123
2124
			// Add backslashes before double quotes and forward slashes only
2125
			$post_content[ $key ] = addcslashes( $val, '"\\/' );
2126
		}
2127
	}
2128
2129
	/**
2130
	 * Check for either json or serilized data. This is temporary while transitioning
2131
	 * all data to json.
2132
	 *
2133
	 * @since 4.02.03
2134
	 */
2135
	public static function unserialize_or_decode( &$value ) {
2136
		if ( is_array( $value ) ) {
2137
			return;
2138
		}
2139
2140
		if ( is_serialized( $value ) ) {
2141
			$value = maybe_unserialize( $value );
2142
		} else {
2143
			$value = self::maybe_json_decode( $value, false );
2144
		}
2145
	}
2146
2147
	/**
2148
	 * Decode a JSON string.
2149
	 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
2150
	 */
2151
	public static function maybe_json_decode( $string, $single_to_array = true ) {
2152
		if ( is_array( $string ) ) {
2153
			return $string;
2154
		}
2155
2156
		$new_string = json_decode( $string, true );
2157
		if ( function_exists( 'json_last_error' ) ) {
2158
			// php 5.3+
2159
			$single_value = false;
2160
			if ( ! $single_to_array ) {
2161
				$single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
2162
			}
2163
			if ( json_last_error() == JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
2164
				$string = $new_string;
2165
			}
2166
		}
2167
2168
		return $string;
2169
	}
2170
2171
	/**
2172
	 * Reformat the json serialized array in name => value array.
2173
	 *
2174
	 * @since 4.02.03
2175
	 */
2176
	public static function format_form_data( &$form ) {
2177
		$formatted = array();
2178
2179
		foreach ( $form as $input ) {
2180
			if ( ! isset( $input['name'] ) ) {
2181
				continue;
2182
			}
2183
			$key = $input['name'];
2184
			if ( isset( $formatted[ $key ] ) ) {
2185
				if ( is_array( $formatted[ $key ] ) ) {
2186
					$formatted[ $key ][] = $input['value'];
2187
				} else {
2188
					$formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
2189
				}
2190
			} else {
2191
				$formatted[ $key ] = $input['value'];
2192
			}
2193
		}
2194
2195
		parse_str( http_build_query( $formatted ), $form );
2196
	}
2197
2198
	/**
2199
	 * @since 4.02.03
2200
	 */
2201
	public static function maybe_json_encode( $value ) {
2202
		if ( is_array( $value ) ) {
2203
			$value = wp_json_encode( $value );
2204
		}
2205
		return $value;
2206
	}
2207
2208
	/**
2209
	 * @since 1.07.10
2210
	 *
2211
	 * @param string $post_type The name of the post type that may need to be highlighted
2212
	 * echo The javascript to open and highlight the Formidable menu
2213
	 */
2214
	public static function maybe_highlight_menu( $post_type ) {
2215
		global $post;
2216
2217
		if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
2218
			return;
2219
		}
2220
2221
		if ( is_object( $post ) && $post->post_type != $post_type ) {
2222
			return;
2223
		}
2224
2225
		self::load_admin_wide_js();
2226
		echo '<script type="text/javascript">jQuery(document).ready(function(){frmSelectSubnav();});</script>';
2227
	}
2228
2229
	/**
2230
	 * Load the JS file on non-Formidable pages in the admin area
2231
	 *
2232
	 * @since 2.0
2233
	 */
2234
	public static function load_admin_wide_js( $load = true ) {
2235
		$version = self::plugin_version();
2236
		wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
2237
2238
		$global_strings = array(
2239
			'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
2240
			'deauthorize'  => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
2241
			'url'          => self::plugin_url(),
2242
			'app_url'      => 'https://formidableforms.com/',
2243
			'loading'      => __( 'Loading&hellip;', 'formidable' ),
2244
			'nonce'        => wp_create_nonce( 'frm_ajax' ),
2245
		);
2246
		wp_localize_script( 'formidable_admin_global', 'frmGlobal', $global_strings );
2247
2248
		if ( $load ) {
2249
			wp_enqueue_script( 'formidable_admin_global' );
2250
		}
2251
	}
2252
2253
	/**
2254
	 * @since 2.0.9
2255
	 */
2256
	public static function load_font_style() {
2257
		wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
2258
	}
2259
2260
	/**
2261
	 * @param string $location
2262
	 */
2263
	public static function localize_script( $location ) {
2264
		global $wp_scripts;
2265
2266
		$ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
2267
		$ajax_url = apply_filters( 'frm_ajax_url', $ajax_url );
2268
2269
		$script_strings = array(
2270
			'ajax_url'     => $ajax_url,
2271
			'images_url'   => self::plugin_url() . '/images',
2272
			'loading'      => __( 'Loading&hellip;', 'formidable' ),
2273
			'remove'       => __( 'Remove', 'formidable' ),
2274
			'offset'       => apply_filters( 'frm_scroll_offset', 4 ),
2275
			'nonce'        => wp_create_nonce( 'frm_ajax' ),
2276
			'id'           => __( 'ID', 'formidable' ),
2277
			'no_results'   => __( 'No results match', 'formidable' ),
2278
			'file_spam'    => __( 'That file looks like Spam.', 'formidable' ),
2279
			'calc_error'   => __( 'There is an error in the calculation in the field with key', 'formidable' ),
2280
			'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ),
2281
		);
2282
2283
		$data = $wp_scripts->get_data( 'formidable', 'data' );
2284
		if ( empty( $data ) ) {
2285
			wp_localize_script( 'formidable', 'frm_js', $script_strings );
2286
		}
2287
2288
		if ( $location == 'admin' ) {
2289
			$frm_settings         = self::get_settings();
2290
			$admin_script_strings = array(
2291
				'desc'              => __( '(Click to add description)', 'formidable' ),
2292
				'blank'             => __( '(Blank)', 'formidable' ),
2293
				'no_label'          => __( '(no label)', 'formidable' ),
2294
				'saving'            => esc_attr( __( 'Saving', 'formidable' ) ),
2295
				'saved'             => esc_attr( __( 'Saved', 'formidable' ) ),
2296
				'ok'                => __( 'OK', 'formidable' ),
2297
				'cancel'            => __( 'Cancel', 'formidable' ),
2298
				'default_label'     => __( 'Default', 'formidable' ),
2299
				'clear_default'     => __( 'Clear default value when typing', 'formidable' ),
2300
				'no_clear_default'  => __( 'Do not clear default value when typing', 'formidable' ),
2301
				'valid_default'     => __( 'Default value will pass form validation', 'formidable' ),
2302
				'no_valid_default'  => __( 'Default value will NOT pass form validation', 'formidable' ),
2303
				'caution'           => __( 'Heads up', 'formidable' ),
2304
				'confirm'           => __( 'Are you sure?', 'formidable' ),
2305
				'conf_delete'       => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
2306
				'conf_delete_sec'   => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ),
2307
				'conf_no_repeat'    => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
2308
				'default_unique'    => $frm_settings->unique_msg,
2309
				'default_conf'      => __( 'The entered values do not match', 'formidable' ),
2310
				'enter_email'       => __( 'Enter Email', 'formidable' ),
2311
				'confirm_email'     => __( 'Confirm Email', 'formidable' ),
2312
				'conditional_text'  => __( 'Conditional content here', 'formidable' ),
2313
				'new_option'        => __( 'New Option', 'formidable' ),
2314
				'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' ),
2315
				'enter_password'    => __( 'Enter Password', 'formidable' ),
2316
				'confirm_password'  => __( 'Confirm Password', 'formidable' ),
2317
				'import_complete'   => __( 'Import Complete', 'formidable' ),
2318
				'updating'          => __( 'Please wait while your site updates.', 'formidable' ),
2319
				'no_save_warning'   => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
2320
				'private_label'     => __( 'Private', 'formidable' ),
2321
				'jquery_ui_url'     => self::jquery_ui_base_url(),
2322
				'pro_url'           => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '',
2323
				'no_licenses'       => __( 'No new licenses were found', 'formidable' ),
2324
				'unmatched_parens'  => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ),
2325
				'view_shortcodes'   => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ),
2326
				'text_shortcodes'   => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
2327
				'only_one_action'   => __( 'This form action is limited to one per form. Please edit the existing form action.', 'formidable' ),
2328
				'unsafe_params'     => FrmFormsHelper::reserved_words(),
2329
				/* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
2330
				'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
2331
				/* Translators: %s is the name of a parameter that is a reserved word.  More than one word could be listed here, though that would not be common. */
2332
				'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
2333
				'reserved_words'    => __( 'See the list of reserved words in WordPress.', 'formidable' ),
2334
				'repeat_limit_min'  => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
2335
				'checkbox_limit'    => __( 'Please select a limit between 0 and 200.', 'formidable' ),
2336
				'install'           => __( 'Install', 'formidable' ),
2337
				'active'            => __( 'Active', 'formidable' ),
2338
				'select_a_field'    => __( 'Select a Field', 'formidable' ),
2339
				'no_items_found'    => __( 'No items found.', 'formidable' ),
2340
			);
2341
2342
			$data = $wp_scripts->get_data( 'formidable_admin', 'data' );
2343
			if ( empty( $data ) ) {
2344
				wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
2345
			}
2346
		}
2347
	}
2348
2349
	/**
2350
	 * Echo the message on the plugins listing page
2351
	 *
2352
	 * @since 1.07.10
2353
	 *
2354
	 * @param float $min_version The version the add-on requires
2355
	 */
2356
	public static function min_version_notice( $min_version ) {
2357
		$frm_version = self::plugin_version();
2358
2359
		// Check if Formidable meets minimum requirements.
2360
		if ( version_compare( $frm_version, $min_version, '>=' ) ) {
2361
			return;
2362
		}
2363
2364
		$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
2365
		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">' .
2366
			esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
2367
			'</div></td></tr>';
2368
	}
2369
2370
	/**
2371
	 * If Pro is far outdated, show a message.
2372
	 *
2373
	 * @since 4.0.01
2374
	 */
2375
	public static function min_pro_version_notice( $min_version ) {
2376
		if ( ! self::is_formidable_admin() ) {
2377
			// Don't show admin-wide.
2378
			return;
2379
		}
2380
2381
		self::php_version_notice();
2382
2383
		$is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
2384
		if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
2385
			return;
2386
		}
2387
2388
		$pro_version = FrmProDb::$plug_version;
0 ignored issues
show
Unused Code introduced by
$pro_version is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2389
		$expired = FrmAddonsController::is_license_expired();
2390
		?>
2391
		<div class="error frm_previous_install">
2392
			<?php
2393
			esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
2394
			if ( empty( $expired ) ) {
2395
				echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
2396
			} else {
2397
				echo '<br/>Please <a href="https://formidableforms.com/account/downloads/?utm_source=WordPress&utm_medium=outdated">renew now</a> to get the latest Pro version or <a href="https://downloads.wordpress.org/plugin/formidable.<?php echo esc_attr( $pro_version ); ?>.zip">download the previous Lite version</a> to revert.';
2398
			}
2399
			?>
2400
		</div>
2401
		<?php
2402
	}
2403
2404
	/**
2405
	 * If Pro is installed, check the version number.
2406
	 *
2407
	 * @since 4.0.01
2408
	 */
2409
	public static function meets_min_pro_version( $min_version ) {
2410
		return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
2411
	}
2412
2413
	/**
2414
	 * Show a message if the browser or PHP version is below the recommendations.
2415
	 *
2416
	 * @since 4.0.02
2417
	 */
2418
	private static function php_version_notice() {
2419
		$message = array();
2420
		if ( version_compare( phpversion(), '5.6', '<' ) ) {
2421
			$message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' );
2422
		}
2423
2424
		$browser = self::get_server_value( 'HTTP_USER_AGENT' );
2425
		$is_ie   = strpos( $browser, 'MSIE' ) !== false;
2426
		if ( $is_ie ) {
2427
			$message[] = __( 'You are using an outdated browser that is not compatible with Formidable Forms. Please update to a more current browser (we recommend Chrome).', 'formidable' );
2428
		}
2429
2430
		foreach ( $message as $m ) {
2431
			?>
2432
			<div class="error frm_previous_install">
2433
				<?php echo esc_html( $m ); ?>
2434
			</div>
2435
			<?php
2436
		}
2437
	}
2438
2439
	public static function locales( $type = 'date' ) {
2440
		$locales = array(
2441
			'en'     => __( 'English', 'formidable' ),
2442
			'af'     => __( 'Afrikaans', 'formidable' ),
2443
			'sq'     => __( 'Albanian', 'formidable' ),
2444
			'ar'     => __( 'Arabic', 'formidable' ),
2445
			'hy'     => __( 'Armenian', 'formidable' ),
2446
			'az'     => __( 'Azerbaijani', 'formidable' ),
2447
			'eu'     => __( 'Basque', 'formidable' ),
2448
			'bs'     => __( 'Bosnian', 'formidable' ),
2449
			'bg'     => __( 'Bulgarian', 'formidable' ),
2450
			'ca'     => __( 'Catalan', 'formidable' ),
2451
			'zh-HK'  => __( 'Chinese Hong Kong', 'formidable' ),
2452
			'zh-CN'  => __( 'Chinese Simplified', 'formidable' ),
2453
			'zh-TW'  => __( 'Chinese Traditional', 'formidable' ),
2454
			'hr'     => __( 'Croatian', 'formidable' ),
2455
			'cs'     => __( 'Czech', 'formidable' ),
2456
			'da'     => __( 'Danish', 'formidable' ),
2457
			'nl'     => __( 'Dutch', 'formidable' ),
2458
			'en-GB'  => __( 'English/UK', 'formidable' ),
2459
			'eo'     => __( 'Esperanto', 'formidable' ),
2460
			'et'     => __( 'Estonian', 'formidable' ),
2461
			'fo'     => __( 'Faroese', 'formidable' ),
2462
			'fa'     => __( 'Farsi/Persian', 'formidable' ),
2463
			'fil'    => __( 'Filipino', 'formidable' ),
2464
			'fi'     => __( 'Finnish', 'formidable' ),
2465
			'fr'     => __( 'French', 'formidable' ),
2466
			'fr-CA'  => __( 'French/Canadian', 'formidable' ),
2467
			'fr-CH'  => __( 'French/Swiss', 'formidable' ),
2468
			'de'     => __( 'German', 'formidable' ),
2469
			'de-AT'  => __( 'German/Austria', 'formidable' ),
2470
			'de-CH'  => __( 'German/Switzerland', 'formidable' ),
2471
			'el'     => __( 'Greek', 'formidable' ),
2472
			'he'     => __( 'Hebrew', 'formidable' ),
2473
			'iw'     => __( 'Hebrew', 'formidable' ),
2474
			'hi'     => __( 'Hindi', 'formidable' ),
2475
			'hu'     => __( 'Hungarian', 'formidable' ),
2476
			'is'     => __( 'Icelandic', 'formidable' ),
2477
			'id'     => __( 'Indonesian', 'formidable' ),
2478
			'it'     => __( 'Italian', 'formidable' ),
2479
			'ja'     => __( 'Japanese', 'formidable' ),
2480
			'ko'     => __( 'Korean', 'formidable' ),
2481
			'lv'     => __( 'Latvian', 'formidable' ),
2482
			'lt'     => __( 'Lithuanian', 'formidable' ),
2483
			'ms'     => __( 'Malaysian', 'formidable' ),
2484
			'no'     => __( 'Norwegian', 'formidable' ),
2485
			'pl'     => __( 'Polish', 'formidable' ),
2486
			'pt'     => __( 'Portuguese', 'formidable' ),
2487
			'pt-BR'  => __( 'Portuguese/Brazilian', 'formidable' ),
2488
			'pt-PT'  => __( 'Portuguese/Portugal', 'formidable' ),
2489
			'ro'     => __( 'Romanian', 'formidable' ),
2490
			'ru'     => __( 'Russian', 'formidable' ),
2491
			'sr'     => __( 'Serbian', 'formidable' ),
2492
			'sr-SR'  => __( 'Serbian', 'formidable' ),
2493
			'sk'     => __( 'Slovak', 'formidable' ),
2494
			'sl'     => __( 'Slovenian', 'formidable' ),
2495
			'es'     => __( 'Spanish', 'formidable' ),
2496
			'es-419' => __( 'Spanish/Latin America', 'formidable' ),
2497
			'sv'     => __( 'Swedish', 'formidable' ),
2498
			'ta'     => __( 'Tamil', 'formidable' ),
2499
			'th'     => __( 'Thai', 'formidable' ),
2500
			'tu'     => __( 'Turkish', 'formidable' ),
2501
			'tr'     => __( 'Turkish', 'formidable' ),
2502
			'uk'     => __( 'Ukranian', 'formidable' ),
2503
			'vi'     => __( 'Vietnamese', 'formidable' ),
2504
		);
2505
2506
		if ( $type === 'captcha' ) {
2507
			// remove the languages unavailable for the captcha
2508
			$unset = array( 'af', 'sq', 'hy', 'az', 'eu', 'bs', 'zh-HK', 'eo', 'et', 'fo', 'fr-CH', 'he', 'is', 'ms', 'sr-SR', 'ta', 'tu' );
2509
		} else {
2510
			// remove the languages unavailable for the datepicker
2511
			$unset = array( 'fil', 'fr-CA', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419', 'tr' );
2512
		}
2513
2514
		$locales = array_diff_key( $locales, array_flip( $unset ) );
2515
		$locales = apply_filters( 'frm_locales', $locales );
2516
2517
		return $locales;
2518
	}
2519
2520
	/**
2521
	 * Use the WP 4.7 wp_doing_ajax function
2522
	 *
2523
	 * @since 2.05.07
2524
	 * @deprecated 4.04.04
2525
	 */
2526
	public static function wp_doing_ajax() {
2527
		_deprecated_function( __METHOD__, '4.04.04', 'wp_doing_ajax' );
2528
		return wp_doing_ajax();
2529
	}
2530
2531
	/**
2532
	 * @deprecated 4.0
2533
	 */
2534
	public static function insert_opt_html( $args ) {
2535
		_deprecated_function( __METHOD__, '4.0', 'FrmFormsHelper::insert_opt_html' );
2536
		FrmFormsHelper::insert_opt_html( $args );
2537
	}
2538
2539
	/**
2540
	 * Used to filter shortcode in text widgets
2541
	 *
2542
	 * @deprecated 2.5.4
2543
	 * @codeCoverageIgnore
2544
	 */
2545
	public static function widget_text_filter_callback( $matches ) {
2546
		return FrmDeprecated::widget_text_filter_callback( $matches );
2547
	}
2548
2549
	/**
2550
	 * @deprecated 3.01
2551
	 * @codeCoverageIgnore
2552
	 */
2553
	public static function sanitize_array( &$values ) {
2554
		FrmDeprecated::sanitize_array( $values );
2555
	}
2556
2557
	/**
2558
	 * @param array $settings
2559
	 * @param string $group
2560
	 *
2561
	 * @since 2.0.6
2562
	 * @deprecated 2.05.06
2563
	 * @codeCoverageIgnore
2564
	 */
2565
	public static function save_settings( $settings, $group ) {
2566
		return FrmDeprecated::save_settings( $settings, $group );
2567
	}
2568
2569
	/**
2570
	 * @since 2.0.4
2571
	 * @deprecated 2.05.06
2572
	 * @codeCoverageIgnore
2573
	 */
2574
	public static function save_json_post( $settings ) {
2575
		return FrmDeprecated::save_json_post( $settings );
2576
	}
2577
2578
	/**
2579
	 * @since 2.0
2580
	 * @deprecated 2.05.06
2581
	 * @codeCoverageIgnore
2582
	 *
2583
	 * @param string $cache_key The unique name for this cache
2584
	 * @param string $group The name of the cache group
2585
	 * @param string $query If blank, don't run a db call
2586
	 * @param string $type The wpdb function to use with this query
2587
	 *
2588
	 * @return mixed $results The cache or query results
2589
	 */
2590
	public static function check_cache( $cache_key, $group = '', $query = '', $type = 'get_var', $time = 300 ) {
2591
		return FrmDeprecated::check_cache( $cache_key, $group, $query, $type, $time );
2592
	}
2593
2594
	/**
2595
	 * @deprecated 2.05.06
2596
	 * @codeCoverageIgnore
2597
	 */
2598
	public static function set_cache( $cache_key, $results, $group = '', $time = 300 ) {
2599
		return FrmDeprecated::set_cache( $cache_key, $results, $group, $time );
2600
	}
2601
2602
	/**
2603
	 * @deprecated 2.05.06
2604
	 * @codeCoverageIgnore
2605
	 */
2606
	public static function add_key_to_group_cache( $key, $group ) {
2607
		FrmDeprecated::add_key_to_group_cache( $key, $group );
2608
	}
2609
2610
	/**
2611
	 * @deprecated 2.05.06
2612
	 * @codeCoverageIgnore
2613
	 */
2614
	public static function get_group_cached_keys( $group ) {
2615
		return FrmDeprecated::get_group_cached_keys( $group );
2616
	}
2617
2618
	/**
2619
	 * @since 2.0
2620
	 * @deprecated 2.05.06
2621
	 * @codeCoverageIgnore
2622
	 * @return mixed The cached value or false
2623
	 */
2624
	public static function check_cache_and_transient( $cache_key ) {
2625
		return FrmDeprecated::check_cache( $cache_key );
2626
	}
2627
2628
	/**
2629
	 * @since 2.0
2630
	 * @deprecated 2.05.06
2631
	 * @codeCoverageIgnore
2632
	 *
2633
	 * @param string $cache_key
2634
	 */
2635
	public static function delete_cache_and_transient( $cache_key, $group = 'default' ) {
2636
		FrmDeprecated::delete_cache_and_transient( $cache_key, $group );
2637
	}
2638
2639
	/**
2640
	 * @since 2.0
2641
	 * @deprecated 2.05.06
2642
	 * @codeCoverageIgnore
2643
	 *
2644
	 * @param string $group The name of the cache group
2645
	 */
2646
	public static function cache_delete_group( $group ) {
2647
		FrmDeprecated::cache_delete_group( $group );
2648
	}
2649
2650
	/**
2651
	 * @since 1.07.10
2652
	 * @deprecated 2.05.06
2653
	 * @codeCoverageIgnore
2654
	 *
2655
	 * @param string $term The value to escape
2656
	 *
2657
	 * @return string The escaped value
2658
	 */
2659
	public static function esc_like( $term ) {
2660
		return FrmDeprecated::esc_like( $term );
2661
	}
2662
2663
	/**
2664
	 * @param string $order_query
2665
	 *
2666
	 * @deprecated 2.05.06
2667
	 * @codeCoverageIgnore
2668
	 */
2669
	public static function esc_order( $order_query ) {
2670
		return FrmDeprecated::esc_order( $order_query );
2671
	}
2672
2673
	/**
2674
	 * @deprecated 2.05.06
2675
	 * @codeCoverageIgnore
2676
	 */
2677
	public static function esc_order_by( &$order_by ) {
2678
		FrmDeprecated::esc_order_by( $order_by );
2679
	}
2680
2681
	/**
2682
	 * @param string $limit
2683
	 *
2684
	 * @deprecated 2.05.06
2685
	 * @codeCoverageIgnore
2686
	 */
2687
	public static function esc_limit( $limit ) {
2688
		return FrmDeprecated::esc_limit( $limit );
2689
	}
2690
2691
	/**
2692
	 * @since 2.0
2693
	 * @deprecated 2.05.06
2694
	 * @codeCoverageIgnore
2695
	 */
2696
	public static function prepare_array_values( $array, $type = '%s' ) {
2697
		return FrmDeprecated::prepare_array_values( $array, $type );
2698
	}
2699
2700
	/**
2701
	 * @deprecated 2.05.06
2702
	 * @codeCoverageIgnore
2703
	 */
2704
	public static function prepend_and_or_where( $starts_with = ' WHERE ', $where = '' ) {
2705
		return FrmDeprecated::prepend_and_or_where( $starts_with, $where );
2706
	}
2707
}
2708