Completed
Push — master ( d50f71...6f2b4b )
by Stephanie
02:27
created

FrmAppHelper::permission_check()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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