Completed
Push — master ( f02ac1...d938d5 )
by Stephanie
02:22
created

FrmAppHelper::get_admin_header()   B

Complexity

Conditions 7
Paths 20

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 20
nop 1
dl 0
loc 11
rs 8.8333
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.04.02';
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
		if ( ! isset( $atts['import_link'] ) ) {
890
			$atts['import_link'] = false;
891
		}
892
893
		include( self::plugin_path() . '/classes/views/shared/admin-header.php' );
894
	}
895
896
	/**
897
	 * @since 3.0
898
	 */
899
	public static function add_new_item_link( $atts ) {
900
		if ( isset( $atts['new_link'] ) && ! empty( $atts['new_link'] ) ) { ?>
901
			<a href="<?php echo esc_url( $atts['new_link'] ); ?>" class="button button-primary frm-button-primary frm-with-plus">
902
				<?php self::icon_by_class( 'frmfont frm_plus_icon frm_svg15' ); ?>
903
				<?php esc_html_e( 'Add New', 'formidable' ); ?>
904
			</a>
905
			<?php
906
		} elseif ( isset( $atts['link_hook'] ) ) {
907
			do_action( $atts['link_hook']['hook'], $atts['link_hook']['param'] );
908
		}
909
	}
910
911
	/**
912
	 * @since 3.06
913
	 */
914
	public static function show_search_box( $atts ) {
915
		$defaults = array(
916
			'placeholder' => '',
917
			'tosearch'    => '',
918
			'text'        => __( 'Search', 'formidable' ),
919
			'input_id'    => '',
920
		);
921
		$atts = array_merge( $defaults, $atts );
922
923
		if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) {
924
			$atts['tosearch'] = 'frm-card';
925
		}
926
927
		$class = 'frm-search-input';
928
		if ( ! empty( $atts['tosearch'] ) ) {
929
			$class .= ' frm-auto-search';
930
		}
931
932
		$input_id = $atts['input_id'] . '-search-input';
933
934
		?>
935
		<p class="frm-search">
936
			<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
937
				<?php echo esc_html( $atts['text'] ); ?>:
938
			</label>
939
			<span class="frmfont frm_search_icon"></span>
940
			<input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s"
941
				value="<?php _admin_search_query(); ?>" placeholder="<?php echo esc_attr( $atts['placeholder'] ); ?>"
942
				class="<?php echo esc_attr( $class ); ?>" data-tosearch="<?php echo esc_attr( $atts['tosearch'] ); ?>"
943
				<?php if ( ! empty( $atts['tosearch'] ) ) { ?>
944
				autocomplete="off"
945
				<?php } ?>
946
				/>
947
			<?php
948
			if ( empty( $atts['tosearch'] ) ) {
949
				submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) );
950
			}
951
			?>
952
		</p>
953
		<?php
954
	}
955
956
	/**
957
	 * @param string $type
958
	 */
959
	public static function trigger_hook_load( $type, $object = null ) {
960
		// Only load the form hooks once.
961
		$hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object );
962
		if ( ! $hooks_loaded ) {
963
			do_action( 'frm_load_' . $type . '_hooks' );
964
		}
965
	}
966
967
	/**
968
	 * Save all front-end js scripts into a single file
969
	 *
970
	 * @since 3.0
971
	 */
972
	public static function save_combined_js() {
973
		$file_atts = apply_filters(
974
			'frm_js_location',
975
			array(
976
				'file_name'     => 'frm.min.js',
977
				'new_file_path' => self::plugin_path() . '/js',
978
			)
979
		);
980
		$new_file  = new FrmCreateFile( $file_atts );
981
982
		$files = array(
983
			self::plugin_path() . '/js/jquery/jquery.placeholder.min.js',
984
			self::plugin_path() . '/js/formidable.min.js',
985
		);
986
		$files = apply_filters( 'frm_combined_js_files', $files );
987
		$new_file->combine_files( $files );
988
	}
989
990
	/**
991
	 * Check a value from a shortcode to see if true or false.
992
	 * True when value is 1, true, 'true', 'yes'
993
	 *
994
	 * @since 1.07.10
995
	 *
996
	 * @param string $value The value to compare
997
	 *
998
	 * @return boolean True or False
999
	 */
1000
	public static function is_true( $value ) {
1001
		return ( true === $value || 1 == $value || 'true' == $value || 'yes' == $value );
1002
	}
1003
1004
	public static function get_pages() {
1005
		$query = array(
1006
			'post_type'   => 'page',
1007
			'post_status' => array( 'publish', 'private' ),
1008
			'numberposts' => - 1,
1009
			'orderby'     => 'title',
1010
			'order'       => 'ASC',
1011
		);
1012
1013
		return get_posts( $query );
1014
	}
1015
1016
	/**
1017
	 * Renders an autocomplete page selection or a regular dropdown depending on
1018
	 * the total page count
1019
	 *
1020
	 * @since 4.03.06
1021
	 */
1022
	public static function maybe_autocomplete_pages_options( $args ) {
1023
		$args = self::preformat_selection_args( $args );
1024
1025
		$pages_count = wp_count_posts( 'page' );
1026
1027
		if ( $pages_count->publish <= 50 ) {
1028
			self::wp_pages_dropdown( $args );
1029
			return;
1030
		}
1031
1032
		wp_enqueue_script( 'jquery-ui-autocomplete' );
1033
1034
		$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...
1035
		$title = '';
1036
1037
		if ( $selected ) {
1038
			$title = get_the_title( $selected );
1039
		}
1040
1041
		?>
1042
		<input type="text" class="frm-page-search"
1043
			placeholder="<?php esc_html_e( 'Select a Page', 'formidable' ); ?>"
1044
			value="<?php echo esc_attr( $title ); ?>" />
1045
		<input type="hidden" name="<?php echo esc_attr( $args['field_name'] ); ?>"
1046
			value="<?php echo esc_attr( $selected ); ?>" />
1047
		<?php
1048
	}
1049
1050
	/**
1051
	 * @param array   $args
1052
	 * @param string  $page_id Deprecated.
1053
	 * @param boolean $truncate Deprecated.
1054
	 */
1055
	public static function wp_pages_dropdown( $args = array(), $page_id = '', $truncate = false ) {
1056
		self::prep_page_dropdown_params( $page_id, $truncate, $args );
1057
1058
		$pages    = self::get_pages();
1059
		$selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' );
1060
1061
		?>
1062
		<select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown">
1063
			<option value=""><?php echo esc_html( $args['placeholder'] ); ?></option>
1064
			<?php foreach ( $pages as $page ) { ?>
1065
				<option value="<?php echo esc_attr( $page->ID ); ?>" <?php selected( $selected, $page->ID ); ?>>
1066
					<?php echo esc_html( $args['truncate'] ? self::truncate( $page->post_title, $args['truncate'] ) : $page->post_title ); ?>
1067
				</option>
1068
			<?php } ?>
1069
		</select>
1070
		<?php
1071
	}
1072
1073
	/**
1074
	 * Fill in missing parameters passed to wp_pages_dropdown().
1075
	 * This is for reverse compatibility with switching 3 params to 1.
1076
	 *
1077
	 * @since 4.03.06
1078
	 */
1079
	private static function prep_page_dropdown_params( $page_id, $truncate, &$args ) {
1080
		if ( ! is_array( $args ) ) {
1081
			$args = array(
1082
				'field_name' => $args,
1083
				'page_id'    => $page_id,
1084
				'truncate'   => $truncate,
1085
			);
1086
		}
1087
1088
		$args = self::preformat_selection_args( $args );
1089
	}
1090
1091
	/**
1092
	 * Filter to format args for page dropdown or autocomplete
1093
	 *
1094
	 * @since 4.03.06
1095
	 */
1096
	private static function preformat_selection_args( $args ) {
1097
		$defaults = array(
1098
			'truncate'    => false,
1099
			'placeholder' => ' ',
1100
			'field_name'  => '',
1101
			'page_id'     => '',
1102
		);
1103
1104
		return array_merge( $defaults, $args );
1105
	}
1106
1107
	public static function post_edit_link( $post_id ) {
1108
		$post = get_post( $post_id );
1109
		if ( $post ) {
1110
			$post_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
1111
			$post_url = self::maybe_full_screen_link( $post_url );
1112
1113
			return '<a href="' . esc_url( $post_url ) . '">' . self::truncate( $post->post_title, 50 ) . '</a>';
1114
		}
1115
1116
		return '';
1117
	}
1118
1119
	/**
1120
	 * Hide the WordPress menus on some pages.
1121
	 *
1122
	 * @since 4.0
1123
	 */
1124
	public static function is_full_screen() {
1125
		$action       = self::simple_get( 'frm_action', 'sanitize_title' );
1126
		$full_builder = self::is_admin_page( 'formidable' ) && ( $action === 'edit' || $action === 'settings' || $action === 'duplicate' );
1127
		$styler       = self::is_admin_page( 'formidable-styles' );
1128
		$full_entries = self::simple_get( 'frm-full', 'absint' );
1129
1130
		return $full_builder || $full_entries || $styler || self::is_view_builder_page();
1131
	}
1132
1133
	/**
1134
	 * @since 4.0
1135
	 */
1136
	public static function maybe_full_screen_link( $link ) {
1137
		$is_full = self::simple_get( 'frm-full', 'absint' );
1138
		if ( $is_full && ! empty( $link ) && $link !== '#' ) {
1139
			$link .= '&frm-full=1';
1140
		}
1141
		return $link;
1142
	}
1143
1144
	public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) {
1145
		?>
1146
		<select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"
1147
			<?php echo ( 'multiple' === $multiple ) ? 'multiple="multiple"' : ''; ?>
1148
			class="frm_multiselect">
1149
			<?php self::roles_options( $capability ); ?>
1150
		</select>
1151
		<?php
1152
	}
1153
1154
	public static function roles_options( $capability ) {
1155
		global $frm_vars;
1156
		if ( isset( $frm_vars['editable_roles'] ) ) {
1157
			$editable_roles = $frm_vars['editable_roles'];
1158
		} else {
1159
			$editable_roles             = get_editable_roles();
1160
			$frm_vars['editable_roles'] = $editable_roles;
1161
		}
1162
1163
		foreach ( $editable_roles as $role => $details ) {
1164
			$name = translate_user_role( $details['name'] );
1165
			?>
1166
			<option value="<?php echo esc_attr( $role ); ?>" <?php echo in_array( $role, (array) $capability ) ? ' selected="selected"' : ''; ?>><?php echo esc_attr( $name ); ?> </option>
1167
			<?php
1168
			unset( $role, $details );
1169
		}
1170
	}
1171
1172
	public static function frm_capabilities( $type = 'auto' ) {
1173
		$cap = array(
1174
			'frm_view_forms'      => __( 'View Forms', 'formidable' ),
1175
			'frm_edit_forms'      => __( 'Add and Edit Forms', 'formidable' ),
1176
			'frm_delete_forms'    => __( 'Delete Forms', 'formidable' ),
1177
			'frm_change_settings' => __( 'Access this Settings Page', 'formidable' ),
1178
			'frm_view_entries'    => __( 'View Entries from Admin Area', 'formidable' ),
1179
			'frm_delete_entries'  => __( 'Delete Entries from Admin Area', 'formidable' ),
1180
		);
1181
1182
		if ( ! self::pro_is_installed() && 'pro' != $type ) {
1183
			return $cap;
1184
		}
1185
1186
		$cap['frm_create_entries'] = __( 'Add Entries from Admin Area', 'formidable' );
1187
		$cap['frm_edit_entries']   = __( 'Edit Entries from Admin Area', 'formidable' );
1188
		$cap['frm_view_reports']   = __( 'View Reports', 'formidable' );
1189
		$cap['frm_edit_displays']  = __( 'Add/Edit Views', 'formidable' );
1190
1191
		return $cap;
1192
	}
1193
1194
	public static function user_has_permission( $needed_role ) {
1195
		if ( $needed_role == '-1' ) {
1196
			return false;
1197
		}
1198
1199
		// $needed_role will be equal to blank if "Logged-in users" is selected.
1200
		if ( ( $needed_role == '' && is_user_logged_in() ) || current_user_can( $needed_role ) ) {
1201
			return true;
1202
		}
1203
1204
		$roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
1205
		foreach ( $roles as $role ) {
1206
			if ( current_user_can( $role ) ) {
1207
				return true;
1208
			}
1209
			if ( $role == $needed_role ) {
1210
				break;
1211
			}
1212
		}
1213
1214
		return false;
1215
	}
1216
1217
	/**
1218
	 * Make sure administrators can see Formidable menu
1219
	 *
1220
	 * @since 2.0
1221
	 */
1222
	public static function maybe_add_permissions() {
1223
		self::force_capability( 'frm_view_entries' );
1224
1225
		if ( ! current_user_can( 'administrator' ) || current_user_can( 'frm_view_forms' ) ) {
1226
			return;
1227
		}
1228
1229
		$user_id   = get_current_user_id();
1230
		$user      = new WP_User( $user_id );
1231
		$frm_roles = self::frm_capabilities();
1232
		foreach ( $frm_roles as $frm_role => $frm_role_description ) {
1233
			$user->add_cap( $frm_role );
1234
			unset( $frm_role, $frm_role_description );
1235
		}
1236
	}
1237
1238
	/**
1239
	 * Make sure admins have permission to see the menu items
1240
	 *
1241
	 * @since 2.0.6
1242
	 */
1243
	public static function force_capability( $cap = 'frm_change_settings' ) {
1244
		if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) {
1245
			$role      = get_role( 'administrator' );
1246
			$frm_roles = self::frm_capabilities();
1247
			foreach ( $frm_roles as $frm_role => $frm_role_description ) {
1248
				$role->add_cap( $frm_role );
1249
			}
1250
		}
1251
	}
1252
1253
	/**
1254
	 * Check if the user has permision for action.
1255
	 * Return permission message and stop the action if no permission
1256
	 *
1257
	 * @since 2.0
1258
	 *
1259
	 * @param string $permission
1260
	 */
1261
	public static function permission_check( $permission, $show_message = 'show' ) {
1262
		$permission_error = self::permission_nonce_error( $permission );
1263
		if ( $permission_error !== false ) {
1264
			if ( 'hide' == $show_message ) {
1265
				$permission_error = '';
1266
			}
1267
			wp_die( esc_html( $permission_error ) );
1268
		}
1269
	}
1270
1271
	/**
1272
	 * Check user permission and nonce
1273
	 *
1274
	 * @since 2.0
1275
	 *
1276
	 * @param string $permission
1277
	 *
1278
	 * @return false|string The permission message or false if allowed
1279
	 */
1280
	public static function permission_nonce_error( $permission, $nonce_name = '', $nonce = '' ) {
1281
		if ( ! empty( $permission ) && ! current_user_can( $permission ) && ! current_user_can( 'administrator' ) ) {
1282
			$frm_settings = self::get_settings();
1283
1284
			return $frm_settings->admin_permission;
1285
		}
1286
1287
		$error = false;
1288
		if ( empty( $nonce_name ) ) {
1289
			return $error;
1290
		}
1291
1292
		$nonce_value = ( $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : '';
1293
		if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) {
1294
			$frm_settings = self::get_settings();
1295
			$error        = $frm_settings->admin_permission;
1296
		}
1297
1298
		return $error;
1299
	}
1300
1301
	public static function checked( $values, $current ) {
1302
		if ( self::check_selected( $values, $current ) ) {
1303
			echo ' checked="checked"';
1304
		}
1305
	}
1306
1307
	public static function check_selected( $values, $current ) {
1308
		$values  = self::recursive_function_map( $values, 'trim' );
1309
		$values  = self::recursive_function_map( $values, 'htmlspecialchars_decode' );
1310
		$current = htmlspecialchars_decode( trim( $current ) );
1311
1312
		return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
1313
	}
1314
1315
	public static function recursive_function_map( $value, $function ) {
1316
		if ( is_array( $value ) ) {
1317
			$original_function = $function;
1318
			if ( count( $value ) ) {
1319
				$function = explode( ', ', FrmDb::prepare_array_values( $value, $function ) );
1320
			} else {
1321
				$function = array( $function );
1322
			}
1323
			if ( ! self::is_assoc( $value ) ) {
1324
				$value = array_map( array( 'FrmAppHelper', 'recursive_function_map' ), $value, $function );
1325
			} else {
1326
				foreach ( $value as $k => $v ) {
1327
					if ( ! is_array( $v ) ) {
1328
						$value[ $k ] = call_user_func( $original_function, $v );
1329
					}
1330
				}
1331
			}
1332
		} else {
1333
			$value = call_user_func( $function, $value );
1334
		}
1335
1336
		return $value;
1337
	}
1338
1339
	public static function is_assoc( $array ) {
1340
		return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
1341
	}
1342
1343
	/**
1344
	 * Flatten a multi-dimensional array
1345
	 */
1346
	public static function array_flatten( $array, $keys = 'keep' ) {
1347
		$return = array();
1348
		foreach ( $array as $key => $value ) {
1349
			if ( is_array( $value ) ) {
1350
				$return = array_merge( $return, self::array_flatten( $value, $keys ) );
1351
			} else {
1352
				if ( $keys == 'keep' ) {
1353
					$return[ $key ] = $value;
1354
				} else {
1355
					$return[] = $value;
1356
				}
1357
			}
1358
		}
1359
1360
		return $return;
1361
	}
1362
1363
	public static function esc_textarea( $text, $is_rich_text = false ) {
1364
		$safe_text = str_replace( '&quot;', '"', $text );
1365
		if ( ! $is_rich_text ) {
1366
			$safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES );
1367
		}
1368
		$safe_text = str_replace( '&amp; ', '& ', $safe_text );
1369
1370
		return apply_filters( 'esc_textarea', $safe_text, $text );
1371
	}
1372
1373
	/**
1374
	 * Add auto paragraphs to text areas
1375
	 *
1376
	 * @since 2.0
1377
	 */
1378
	public static function use_wpautop( $content ) {
1379
		if ( apply_filters( 'frm_use_wpautop', true ) && ! is_array( $content ) ) {
1380
			$content = wpautop( str_replace( '<br>', '<br />', $content ) );
1381
		}
1382
1383
		return $content;
1384
	}
1385
1386
	public static function replace_quotes( $val ) {
1387
		// Replace double quotes.
1388
		$val = str_replace( array( '&#8220;', '&#8221;', '&#8243;' ), '"', $val );
1389
1390
		// Replace single quotes.
1391
		$val = str_replace( array( '&#8216;', '&#8217;', '&#8242;', '&prime;', '&rsquo;', '&lsquo;' ), "'", $val );
1392
1393
		return $val;
1394
	}
1395
1396
	/**
1397
	 * @since 2.0
1398
	 * @return string The base Google APIS url for the current version of jQuery UI
1399
	 */
1400
	public static function jquery_ui_base_url() {
1401
		$url = 'http' . ( is_ssl() ? 's' : '' ) . '://ajax.googleapis.com/ajax/libs/jqueryui/' . self::script_version( 'jquery-ui-core', '1.11.4' );
1402
		$url = apply_filters( 'frm_jquery_ui_base_url', $url );
1403
1404
		return $url;
1405
	}
1406
1407
	/**
1408
	 * @param string $handle
1409
	 */
1410
	public static function script_version( $handle, $default = 0 ) {
1411
		global $wp_scripts;
1412
		if ( ! $wp_scripts ) {
1413
			return $default;
1414
		}
1415
1416
		$ver = $default;
1417
		if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
1418
			return $ver;
1419
		}
1420
1421
		$query = $wp_scripts->registered[ $handle ];
1422
		if ( is_object( $query ) && ! empty( $query->ver ) ) {
1423
			$ver = $query->ver;
1424
		}
1425
1426
		return $ver;
1427
	}
1428
1429
	public static function js_redirect( $url ) {
1430
		return '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>';
1431
	}
1432
1433
	public static function get_user_id_param( $user_id ) {
1434
		if ( ! $user_id || empty( $user_id ) || is_numeric( $user_id ) ) {
1435
			return $user_id;
1436
		}
1437
1438
		$user_id = sanitize_text_field( $user_id );
1439
		if ( $user_id == 'current' ) {
1440
			$user_id = get_current_user_id();
1441
		} else {
1442
			if ( is_email( $user_id ) ) {
1443
				$user = get_user_by( 'email', $user_id );
1444
			} else {
1445
				$user = get_user_by( 'login', $user_id );
1446
			}
1447
1448
			if ( $user ) {
1449
				$user_id = $user->ID;
1450
			}
1451
			unset( $user );
1452
		}
1453
1454
		return $user_id;
1455
	}
1456
1457
	public static function get_file_contents( $filename, $atts = array() ) {
1458
		if ( ! is_file( $filename ) ) {
1459
			return false;
1460
		}
1461
1462
		extract( $atts );
1463
		ob_start();
1464
		include( $filename );
1465
		$contents = ob_get_contents();
1466
		ob_end_clean();
1467
1468
		return $contents;
1469
	}
1470
1471
	/**
1472
	 * @param string $table_name
1473
	 * @param string $column
1474
	 * @param int $id
1475
	 * @param int $num_chars
1476
	 */
1477
	public static function get_unique_key( $name = '', $table_name, $column, $id = 0, $num_chars = 5 ) {
1478
		$key = '';
1479
1480
		if ( ! empty( $name ) ) {
1481
			$key = sanitize_key( $name );
1482
		}
1483
1484
		if ( empty( $key ) ) {
1485
			$max_slug_value = pow( 36, $num_chars );
1486
			$min_slug_value = 37; // we want to have at least 2 characters in the slug
1487
			$key            = base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
1488
		}
1489
1490
		$not_allowed = array(
1491
			'id',
1492
			'key',
1493
			'created-at',
1494
			'detaillink',
1495
			'editlink',
1496
			'siteurl',
1497
			'evenodd',
1498
		);
1499
1500
		if ( is_numeric( $key ) || in_array( $key, $not_allowed ) ) {
1501
			$key = $key . 'a';
1502
		}
1503
1504
		$key_check = FrmDb::get_var(
1505
			$table_name,
1506
			array(
1507
				$column => $key,
1508
				'ID !'  => $id,
1509
			),
1510
			$column
1511
		);
1512
1513
		if ( $key_check || is_numeric( $key_check ) ) {
1514
			// Create a unique field id if it has already been used.
1515
			$key = $key . substr( md5( microtime() . rand() ), 0, 10 );
1516
		}
1517
1518
		return $key;
1519
	}
1520
1521
	/**
1522
	 * Editing a Form or Entry
1523
	 *
1524
	 * @param string $table
1525
	 *
1526
	 * @return bool|array
1527
	 */
1528
	public static function setup_edit_vars( $record, $table, $fields = '', $default = false, $post_values = array(), $args = array() ) {
1529
		if ( ! $record ) {
1530
			return false;
1531
		}
1532
1533
		if ( empty( $post_values ) ) {
1534
			$post_values = wp_unslash( $_POST );
1535
		}
1536
1537
		$values = array(
1538
			'id'     => $record->id,
1539
			'fields' => array(),
1540
		);
1541
1542
		foreach ( array( 'name', 'description' ) as $var ) {
1543
			$default_val    = isset( $record->{$var} ) ? $record->{$var} : '';
1544
			$values[ $var ] = self::get_param( $var, $default_val, 'get', 'wp_kses_post' );
1545
			unset( $var, $default_val );
1546
		}
1547
1548
		$values['description'] = self::use_wpautop( $values['description'] );
1549
1550
		self::fill_form_opts( $record, $table, $post_values, $values );
1551
1552
		self::prepare_field_arrays( $fields, $record, $values, array_merge( $args, compact( 'default', 'post_values' ) ) );
1553
1554
		if ( $table == 'entries' ) {
1555
			$values = FrmEntriesHelper::setup_edit_vars( $values, $record );
1556
		} elseif ( $table == 'forms' ) {
1557
			$values = FrmFormsHelper::setup_edit_vars( $values, $record, $post_values );
1558
		}
1559
1560
		return $values;
1561
	}
1562
1563
	private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
1564
		if ( ! empty( $fields ) ) {
1565
			foreach ( (array) $fields as $field ) {
1566
				$field->default_value   = apply_filters( 'frm_get_default_value', $field->default_value, $field, true );
1567
				$args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
1568
				self::fill_field_defaults( $field, $record, $values, $args );
1569
			}
1570
		}
1571
	}
1572
1573
	private static function fill_field_defaults( $field, $record, array &$values, $args ) {
1574
		$post_values = $args['post_values'];
1575
1576
		if ( $args['default'] ) {
1577
			$meta_value = $field->default_value;
1578
		} else {
1579
			if ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) {
1580
				if ( ! isset( $field->field_options['custom_field'] ) ) {
1581
					$field->field_options['custom_field'] = '';
1582
				}
1583
				$meta_value = FrmProEntryMetaHelper::get_post_value(
1584
					$record->post_id,
1585
					$field->field_options['post_field'],
1586
					$field->field_options['custom_field'],
1587
					array(
1588
						'truncate' => false,
1589
						'type'     => $field->type,
1590
						'form_id'  => $field->form_id,
1591
						'field'    => $field,
1592
					)
1593
				);
1594
			} else {
1595
				$meta_value = FrmEntryMeta::get_meta_value( $record, $field->id );
1596
			}
1597
		}
1598
1599
		$field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
1600
		if ( isset( $post_values['item_meta'][ $field->id ] ) ) {
1601
			$new_value = $post_values['item_meta'][ $field->id ];
1602
			self::unserialize_or_decode( $new_value );
1603
		} else {
1604
			$new_value = $meta_value;
1605
		}
1606
1607
		$field_array                   = self::start_field_array( $field );
1608
		$field_array['value']          = $new_value;
1609
		$field_array['type']           = apply_filters( 'frm_field_type', $field_type, $field, $new_value );
1610
		$field_array['parent_form_id'] = $args['parent_form_id'];
1611
1612
		$args['field_type'] = $field_type;
1613
1614
		FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
1615
1616
		if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
1617
			$field_array['unique_msg'] = '';
1618
		}
1619
1620
		$field_array = array_merge( $field->field_options, $field_array );
1621
1622
		$values['fields'][ $field->id ] = $field_array;
1623
	}
1624
1625
	/**
1626
	 * @since 3.0
1627
	 *
1628
	 * @param object $field
1629
	 *
1630
	 * @return array
1631
	 */
1632
	public static function start_field_array( $field ) {
1633
		return array(
1634
			'id'            => $field->id,
1635
			'default_value' => $field->default_value,
1636
			'name'          => $field->name,
1637
			'description'   => $field->description,
1638
			'options'       => $field->options,
1639
			'required'      => $field->required,
1640
			'field_key'     => $field->field_key,
1641
			'field_order'   => $field->field_order,
1642
			'form_id'       => $field->form_id,
1643
		);
1644
	}
1645
1646
	/**
1647
	 * @param string $table
1648
	 */
1649
	private static function fill_form_opts( $record, $table, $post_values, array &$values ) {
1650
		if ( $table == 'entries' ) {
1651
			$form = $record->form_id;
1652
			FrmForm::maybe_get_form( $form );
1653
		} else {
1654
			$form = $record;
1655
		}
1656
1657
		if ( ! $form ) {
1658
			return;
1659
		}
1660
1661
		$values['form_name']      = isset( $record->form_id ) ? $form->name : '';
1662
		$values['parent_form_id'] = isset( $record->form_id ) ? $form->parent_form_id : 0;
1663
1664
		if ( ! is_array( $form->options ) ) {
1665
			return;
1666
		}
1667
1668
		foreach ( $form->options as $opt => $value ) {
1669
			if ( isset( $post_values[ $opt ] ) ) {
1670
				$values[ $opt ] = $post_values[ $opt ];
1671
				self::unserialize_or_decode( $values[ $opt ] );
1672
			} else {
1673
				$values[ $opt ] = $value;
1674
			}
1675
		}
1676
1677
		self::fill_form_defaults( $post_values, $values );
1678
	}
1679
1680
	/**
1681
	 * Set to POST value or default
1682
	 */
1683
	private static function fill_form_defaults( $post_values, array &$values ) {
1684
		$form_defaults = FrmFormsHelper::get_default_opts();
1685
1686
		foreach ( $form_defaults as $opt => $default ) {
1687
			if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) {
1688
				$values[ $opt ] = ( $post_values && isset( $post_values['options'][ $opt ] ) ) ? $post_values['options'][ $opt ] : $default;
1689
			}
1690
1691
			unset( $opt, $default );
1692
		}
1693
1694
		if ( ! isset( $values['custom_style'] ) ) {
1695
			$values['custom_style'] = self::custom_style_value( $post_values );
1696
		}
1697
1698
		foreach ( array( 'before', 'after', 'submit' ) as $h ) {
1699
			if ( ! isset( $values[ $h . '_html' ] ) ) {
1700
				$values[ $h . '_html' ] = ( isset( $post_values['options'][ $h . '_html' ] ) ? $post_values['options'][ $h . '_html' ] : FrmFormsHelper::get_default_html( $h ) );
1701
			}
1702
			unset( $h );
1703
		}
1704
	}
1705
1706
	/**
1707
	 * @since 2.2.10
1708
	 *
1709
	 * @param array $post_values
1710
	 *
1711
	 * @return boolean|int
1712
	 */
1713
	public static function custom_style_value( $post_values ) {
1714
		if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) {
1715
			$custom_style = absint( $post_values['options']['custom_style'] );
1716
		} else {
1717
			$frm_settings = self::get_settings();
1718
			$custom_style = ( $frm_settings->load_style != 'none' );
1719
		}
1720
1721
		return $custom_style;
1722
	}
1723
1724
	public static function truncate( $str, $length, $minword = 3, $continue = '...' ) {
1725
		if ( is_array( $str ) ) {
1726
			return '';
1727
		}
1728
1729
		$length       = (int) $length;
1730
		$str          = wp_strip_all_tags( $str );
1731
		$original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) );
1732
1733
		if ( $length == 0 ) {
1734
			return '';
1735
		} elseif ( $length <= 10 ) {
1736
			$sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) );
1737
1738
			return $sub . ( ( $length < $original_len ) ? $continue : '' );
1739
		}
1740
1741
		$sub = '';
1742
		$len = 0;
1743
1744
		$words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) );
1745
1746
		foreach ( $words as $word ) {
1747
			$part      = ( ( $sub != '' ) ? ' ' : '' ) . $word;
1748
			$total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) );
1749
			if ( $total_len > $length && substr_count( $sub, ' ' ) ) {
1750
				break;
1751
			}
1752
1753
			$sub .= $part;
1754
			$len += self::mb_function( array( 'mb_strlen', 'strlen' ), array( $part ) );
1755
1756
			if ( substr_count( $sub, ' ' ) > $minword && $total_len >= $length ) {
1757
				break;
1758
			}
1759
1760
			unset( $total_len, $word );
1761
		}
1762
1763
		return $sub . ( ( $len < $original_len ) ? $continue : '' );
1764
	}
1765
1766
	public static function mb_function( $function_names, $args ) {
1767
		$mb_function_name = $function_names[0];
1768
		$function_name    = $function_names[1];
1769
		if ( function_exists( $mb_function_name ) ) {
1770
			$function_name = $mb_function_name;
1771
		}
1772
1773
		return call_user_func_array( $function_name, $args );
1774
	}
1775
1776
	public static function get_formatted_time( $date, $date_format = '', $time_format = '' ) {
1777
		if ( empty( $date ) ) {
1778
			return $date;
1779
		}
1780
1781
		if ( empty( $date_format ) ) {
1782
			$date_format = get_option( 'date_format' );
1783
		}
1784
1785
		if ( preg_match( '/^\d{1-2}\/\d{1-2}\/\d{4}$/', $date ) && self::pro_is_installed() ) {
1786
			$frmpro_settings = new FrmProSettings();
1787
			$date            = FrmProAppHelper::convert_date( $date, $frmpro_settings->date_format, 'Y-m-d' );
1788
		}
1789
1790
		$formatted = self::get_localized_date( $date_format, $date );
1791
1792
		$do_time = ( gmdate( 'H:i:s', strtotime( $date ) ) != '00:00:00' );
1793
		if ( $do_time ) {
1794
			$formatted .= self::add_time_to_date( $time_format, $date );
1795
		}
1796
1797
		return $formatted;
1798
	}
1799
1800
	private static function add_time_to_date( $time_format, $date ) {
1801
		if ( empty( $time_format ) ) {
1802
			$time_format = get_option( 'time_format' );
1803
		}
1804
1805
		$trimmed_format = trim( $time_format );
1806
		$time           = '';
1807
		if ( $time_format && ! empty( $trimmed_format ) ) {
1808
			$time = ' ' . __( 'at', 'formidable' ) . ' ' . self::get_localized_date( $time_format, $date );
1809
		}
1810
1811
		return $time;
1812
	}
1813
1814
	/**
1815
	 * @since 2.0.8
1816
	 */
1817
	public static function get_localized_date( $date_format, $date ) {
1818
		$date = get_date_from_gmt( $date );
1819
1820
		return date_i18n( $date_format, strtotime( $date ) );
1821
	}
1822
1823
	/**
1824
	 * Gets the time ago in words
1825
	 *
1826
	 * @param int $from in seconds
1827
	 * @param int|string $to in seconds
1828
	 *
1829
	 * @return string $time_ago
1830
	 */
1831
	public static function human_time_diff( $from, $to = '', $levels = 1 ) {
1832
		if ( empty( $to ) ) {
1833
			$now = new DateTime();
1834
		} else {
1835
			$now = new DateTime( '@' . $to );
1836
		}
1837
		$ago = new DateTime( '@' . $from );
1838
1839
		// Get the time difference
1840
		$diff_object = $now->diff( $ago );
1841
		$diff        = get_object_vars( $diff_object );
1842
1843
		// Add week amount and update day amount
1844
		$diff['w'] = floor( $diff['d'] / 7 );
1845
		$diff['d'] -= $diff['w'] * 7;
1846
1847
		$time_strings = self::get_time_strings();
1848
1849
		foreach ( $time_strings as $k => $v ) {
1850
			if ( $diff[ $k ] ) {
1851
				$time_strings[ $k ] = $diff[ $k ] . ' ' . ( $diff[ $k ] > 1 ? $v[1] : $v[0] );
1852
			} else {
1853
				unset( $time_strings[ $k ] );
1854
			}
1855
		}
1856
1857
		$levels_deep     = apply_filters( 'frm_time_ago_levels', $levels, compact( 'time_strings', 'from', 'to' ) );
1858
		$time_strings    = array_slice( $time_strings, 0, $levels_deep );
1859
		$time_ago_string = $time_strings ? implode( ' ', $time_strings ) : '0 ' . __( 'seconds', 'formidable' );
1860
1861
		return $time_ago_string;
1862
	}
1863
1864
	/**
1865
	 * Get the translatable time strings
1866
	 *
1867
	 * @since 2.0.20
1868
	 * @return array
1869
	 */
1870
	private static function get_time_strings() {
1871
		return array(
1872
			'y' => array( __( 'year', 'formidable' ), __( 'years', 'formidable' ) ),
1873
			'm' => array( __( 'month', 'formidable' ), __( 'months', 'formidable' ) ),
1874
			'w' => array( __( 'week', 'formidable' ), __( 'weeks', 'formidable' ) ),
1875
			'd' => array( __( 'day', 'formidable' ), __( 'days', 'formidable' ) ),
1876
			'h' => array( __( 'hour', 'formidable' ), __( 'hours', 'formidable' ) ),
1877
			'i' => array( __( 'minute', 'formidable' ), __( 'minutes', 'formidable' ) ),
1878
			's' => array( __( 'second', 'formidable' ), __( 'seconds', 'formidable' ) ),
1879
		);
1880
	}
1881
1882
	// Pagination Methods.
1883
1884
	/**
1885
	 * @param integer $current_p
1886
	 */
1887
	public static function get_last_record_num( $r_count, $current_p, $p_size ) {
1888
		return ( ( $r_count < ( $current_p * $p_size ) ) ? $r_count : ( $current_p * $p_size ) );
1889
	}
1890
1891
	/**
1892
	 * @param integer $current_p
1893
	 */
1894
	public static function get_first_record_num( $r_count, $current_p, $p_size ) {
1895
		if ( $current_p == 1 ) {
1896
			return 1;
1897
		} else {
1898
			return ( self::get_last_record_num( $r_count, ( $current_p - 1 ), $p_size ) + 1 );
1899
		}
1900
	}
1901
1902
	/**
1903
	 * @return array
1904
	 */
1905
	public static function json_to_array( $json_vars ) {
1906
		$vars = array();
1907
		foreach ( $json_vars as $jv ) {
1908
			$jv_name = explode( '[', $jv['name'] );
1909
			$last    = count( $jv_name ) - 1;
1910
			foreach ( $jv_name as $p => $n ) {
1911
				$name = trim( $n, ']' );
1912
				if ( ! isset( $l1 ) ) {
1913
					$l1 = $name;
1914
				}
1915
1916
				if ( ! isset( $l2 ) ) {
1917
					$l2 = $name;
1918
				}
1919
1920
				if ( ! isset( $l3 ) ) {
1921
					$l3 = $name;
1922
				}
1923
1924
				$this_val = ( $p == $last ) ? $jv['value'] : array();
1925
1926
				switch ( $p ) {
1927
					case 0:
1928
						$l1 = $name;
1929
						self::add_value_to_array( $name, $l1, $this_val, $vars );
1930
						break;
1931
1932
					case 1:
1933
						$l2 = $name;
1934
						self::add_value_to_array( $name, $l2, $this_val, $vars[ $l1 ] );
1935
						break;
1936
1937 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...
1938
						$l3 = $name;
1939
						self::add_value_to_array( $name, $l3, $this_val, $vars[ $l1 ][ $l2 ] );
1940
						break;
1941
1942 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...
1943
						$l4 = $name;
1944
						self::add_value_to_array( $name, $l4, $this_val, $vars[ $l1 ][ $l2 ][ $l3 ] );
1945
				}
1946
1947
				unset( $this_val, $n );
1948
			}
1949
1950
			unset( $last, $jv );
1951
		}
1952
1953
		return $vars;
1954
	}
1955
1956
	/**
1957
	 * @param string $name
1958
	 * @param string $l1
1959
	 */
1960
	public static function add_value_to_array( $name, $l1, $val, &$vars ) {
1961
		if ( $name == '' ) {
1962
			$vars[] = $val;
1963
		} elseif ( ! isset( $vars[ $l1 ] ) ) {
1964
			$vars[ $l1 ] = $val;
1965
		}
1966
	}
1967
1968
	public static function maybe_add_tooltip( $name, $class = 'closed', $form_name = '' ) {
1969
		$tooltips = array(
1970
			'action_title'  => __( 'Give this action a label for easy reference.', 'formidable' ),
1971
			'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' ),
1972
			'cc'            => __( 'Add CC addresses separated by a ",".  FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
1973
			'bcc'           => __( 'Add BCC addresses separated by a ",".  FORMAT: Name <[email protected]> or [email protected].', 'formidable' ),
1974
			'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' ),
1975
			'from'          => __( 'Enter the name and/or email address of the sender. FORMAT: John Bates <[email protected]> or [email protected].', 'formidable' ),
1976
			/* translators: %1$s: Form name, %2$s: Date */
1977
			'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() ) ),
1978
		);
1979
1980
		if ( ! isset( $tooltips[ $name ] ) ) {
1981
			return;
1982
		}
1983
1984
		if ( 'open' == $class ) {
1985
			echo ' frm_help"';
1986
		} else {
1987
			echo ' class="frm_help"';
1988
		}
1989
1990
		echo ' title="' . esc_attr( $tooltips[ $name ] );
1991
1992
		if ( 'open' != $class ) {
1993
			echo '"';
1994
		}
1995
	}
1996
1997
	/**
1998
	 * Add the current_page class to that page in the form nav
1999
	 */
2000
	public static function select_current_page( $page, $current_page, $action = array() ) {
2001
		if ( $current_page != $page ) {
2002
			return;
2003
		}
2004
2005
		$frm_action = self::simple_get( 'frm_action', 'sanitize_title' );
2006
		if ( empty( $action ) || ( ! empty( $frm_action ) && in_array( $frm_action, $action ) ) ) {
2007
			echo ' class="current_page"';
2008
		}
2009
	}
2010
2011
	/**
2012
	 * Prepare and json_encode post content
2013
	 *
2014
	 * @since 2.0
2015
	 *
2016
	 * @param array $post_content
2017
	 *
2018
	 * @return string $post_content ( json encoded array )
2019
	 */
2020
	public static function prepare_and_encode( $post_content ) {
2021
		// Loop through array to strip slashes and add only the needed ones.
2022
		foreach ( $post_content as $key => $val ) {
2023
			// Replace problematic characters (like &quot;)
2024
			$val = str_replace( '&quot;', '"', $val );
2025
2026
			self::prepare_action_slashes( $val, $key, $post_content );
2027
			unset( $key, $val );
2028
		}
2029
2030
		// json_encode the array.
2031
		$post_content = json_encode( $post_content );
2032
2033
		// Add extra slashes for \r\n since WP strips them.
2034
		$post_content = str_replace( array( '\\r', '\\n', '\\u', '\\t' ), array( '\\\\r', '\\\\n', '\\\\u', '\\\\t' ), $post_content );
2035
2036
		// allow for &quot
2037
		$post_content = str_replace( '&quot;', '\\"', $post_content );
2038
2039
		return $post_content;
2040
	}
2041
2042
	private static function prepare_action_slashes( $val, $key, &$post_content ) {
2043
		if ( ! isset( $post_content[ $key ] ) ) {
2044
			return;
2045
		}
2046
2047
		if ( is_array( $val ) ) {
2048
			foreach ( $val as $k1 => $v1 ) {
2049
				self::prepare_action_slashes( $v1, $k1, $post_content[ $key ] );
2050
				unset( $k1, $v1 );
2051
			}
2052
		} else {
2053
			// Strip all slashes so everything is the same, no matter where the value is coming from
2054
			$val = stripslashes( $val );
2055
2056
			// Add backslashes before double quotes and forward slashes only
2057
			$post_content[ $key ] = addcslashes( $val, '"\\/' );
2058
		}
2059
	}
2060
2061
	/**
2062
	 * Check for either json or serilized data. This is temporary while transitioning
2063
	 * all data to json.
2064
	 *
2065
	 * @since 4.02.03
2066
	 */
2067
	public static function unserialize_or_decode( &$value ) {
2068
		if ( is_array( $value ) ) {
2069
			return;
2070
		}
2071
2072
		if ( is_serialized( $value ) ) {
2073
			$value = maybe_unserialize( $value );
2074
		} else {
2075
			$value = self::maybe_json_decode( $value, false );
2076
		}
2077
	}
2078
2079
	/**
2080
	 * Decode a JSON string.
2081
	 * Do not switch shortcodes like [24] to array unless intentional ie XML values.
2082
	 */
2083
	public static function maybe_json_decode( $string, $single_to_array = true ) {
2084
		if ( is_array( $string ) ) {
2085
			return $string;
2086
		}
2087
2088
		$new_string = json_decode( $string, true );
2089
		if ( function_exists( 'json_last_error' ) ) {
2090
			// php 5.3+
2091
			$single_value = false;
2092
			if ( ! $single_to_array ) {
2093
				$single_value = is_array( $new_string ) && count( $new_string ) === 1 && isset( $new_string[0] );
2094
			}
2095
			if ( json_last_error() == JSON_ERROR_NONE && is_array( $new_string ) && ! $single_value ) {
2096
				$string = $new_string;
2097
			}
2098
		}
2099
2100
		return $string;
2101
	}
2102
2103
	/**
2104
	 * Reformat the json serialized array in name => value array.
2105
	 *
2106
	 * @since 4.02.03
2107
	 */
2108
	public static function format_form_data( &$form ) {
2109
		$formatted = array();
2110
2111
		foreach ( $form as $input ) {
2112
			if ( ! isset( $input['name'] ) ) {
2113
				continue;
2114
			}
2115
			$key = $input['name'];
2116
			if ( isset( $formatted[ $key ] ) ) {
2117
				if ( is_array( $formatted[ $key ] ) ) {
2118
					$formatted[ $key ][] = $input['value'];
2119
				} else {
2120
					$formatted[ $key ] = array( $formatted[ $key ], $input['value'] );
2121
				}
2122
			} else {
2123
				$formatted[ $key ] = $input['value'];
2124
			}
2125
		}
2126
2127
		parse_str( http_build_query( $formatted ), $form );
2128
	}
2129
2130
	/**
2131
	 * @since 4.02.03
2132
	 */
2133
	public static function maybe_json_encode( $value ) {
2134
		if ( is_array( $value ) ) {
2135
			$value = wp_json_encode( $value );
2136
		}
2137
		return $value;
2138
	}
2139
2140
	/**
2141
	 * @since 1.07.10
2142
	 *
2143
	 * @param string $post_type The name of the post type that may need to be highlighted
2144
	 * echo The javascript to open and highlight the Formidable menu
2145
	 */
2146
	public static function maybe_highlight_menu( $post_type ) {
2147
		global $post;
2148
2149
		if ( isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] != $post_type ) {
2150
			return;
2151
		}
2152
2153
		if ( is_object( $post ) && $post->post_type != $post_type ) {
2154
			return;
2155
		}
2156
2157
		self::load_admin_wide_js();
2158
		echo '<script type="text/javascript">jQuery(document).ready(function(){frmSelectSubnav();});</script>';
2159
	}
2160
2161
	/**
2162
	 * Load the JS file on non-Formidable pages in the admin area
2163
	 *
2164
	 * @since 2.0
2165
	 */
2166
	public static function load_admin_wide_js( $load = true ) {
2167
		$version = self::plugin_version();
2168
		wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version );
2169
2170
		$global_strings = array(
2171
			'updating_msg' => __( 'Please wait while your site updates.', 'formidable' ),
2172
			'deauthorize'  => __( 'Are you sure you want to deauthorize Formidable Forms on this site?', 'formidable' ),
2173
			'url'          => self::plugin_url(),
2174
			'app_url'      => 'https://formidableforms.com/',
2175
			'loading'      => __( 'Loading&hellip;', 'formidable' ),
2176
			'nonce'        => wp_create_nonce( 'frm_ajax' ),
2177
		);
2178
		wp_localize_script( 'formidable_admin_global', 'frmGlobal', $global_strings );
2179
2180
		if ( $load ) {
2181
			wp_enqueue_script( 'formidable_admin_global' );
2182
		}
2183
	}
2184
2185
	/**
2186
	 * @since 2.0.9
2187
	 */
2188
	public static function load_font_style() {
2189
		wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() );
2190
	}
2191
2192
	/**
2193
	 * @param string $location
2194
	 */
2195
	public static function localize_script( $location ) {
2196
		global $wp_scripts;
2197
2198
		$ajax_url = admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' );
2199
		$ajax_url = apply_filters( 'frm_ajax_url', $ajax_url );
2200
2201
		$script_strings = array(
2202
			'ajax_url'     => $ajax_url,
2203
			'images_url'   => self::plugin_url() . '/images',
2204
			'loading'      => __( 'Loading&hellip;', 'formidable' ),
2205
			'remove'       => __( 'Remove', 'formidable' ),
2206
			'offset'       => apply_filters( 'frm_scroll_offset', 4 ),
2207
			'nonce'        => wp_create_nonce( 'frm_ajax' ),
2208
			'id'           => __( 'ID', 'formidable' ),
2209
			'no_results'   => __( 'No results match', 'formidable' ),
2210
			'file_spam'    => __( 'That file looks like Spam.', 'formidable' ),
2211
			'calc_error'   => __( 'There is an error in the calculation in the field with key', 'formidable' ),
2212
			'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ),
2213
		);
2214
2215
		$data = $wp_scripts->get_data( 'formidable', 'data' );
2216
		if ( empty( $data ) ) {
2217
			wp_localize_script( 'formidable', 'frm_js', $script_strings );
2218
		}
2219
2220
		if ( $location == 'admin' ) {
2221
			$frm_settings         = self::get_settings();
2222
			$admin_script_strings = array(
2223
				'desc'              => __( '(Click to add description)', 'formidable' ),
2224
				'blank'             => __( '(Blank)', 'formidable' ),
2225
				'no_label'          => __( '(no label)', 'formidable' ),
2226
				'saving'            => esc_attr( __( 'Saving', 'formidable' ) ),
2227
				'saved'             => esc_attr( __( 'Saved', 'formidable' ) ),
2228
				'ok'                => __( 'OK', 'formidable' ),
2229
				'cancel'            => __( 'Cancel', 'formidable' ),
2230
				'default'           => __( 'Default', 'formidable' ),
2231
				'clear_default'     => __( 'Clear default value when typing', 'formidable' ),
2232
				'no_clear_default'  => __( 'Do not clear default value when typing', 'formidable' ),
2233
				'valid_default'     => __( 'Default value will pass form validation', 'formidable' ),
2234
				'no_valid_default'  => __( 'Default value will NOT pass form validation', 'formidable' ),
2235
				'caution'           => __( 'Heads up', 'formidable' ),
2236
				'confirm'           => __( 'Are you sure?', 'formidable' ),
2237
				'conf_delete'       => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ),
2238
				'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' ),
2239
				'conf_no_repeat'    => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ),
2240
				'default_unique'    => $frm_settings->unique_msg,
2241
				'default_conf'      => __( 'The entered values do not match', 'formidable' ),
2242
				'enter_email'       => __( 'Enter Email', 'formidable' ),
2243
				'confirm_email'     => __( 'Confirm Email', 'formidable' ),
2244
				'conditional_text'  => __( 'Conditional content here', 'formidable' ),
2245
				'new_option'        => __( 'New Option', 'formidable' ),
2246
				'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' ),
2247
				'enter_password'    => __( 'Enter Password', 'formidable' ),
2248
				'confirm_password'  => __( 'Confirm Password', 'formidable' ),
2249
				'import_complete'   => __( 'Import Complete', 'formidable' ),
2250
				'updating'          => __( 'Please wait while your site updates.', 'formidable' ),
2251
				'no_save_warning'   => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ),
2252
				'private'           => __( 'Private', 'formidable' ),
2253
				'jquery_ui_url'     => self::jquery_ui_base_url(),
2254
				'pro_url'           => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '',
2255
				'no_licenses'       => __( 'No new licenses were found', 'formidable' ),
2256
				'unmatched_parens'  => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ),
2257
				'view_shortcodes'   => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ),
2258
				'text_shortcodes'   => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ),
2259
				'only_one_action'   => __( 'This form action is limited to one per form. Please edit the existing form action.', 'formidable' ),
2260
				'unsafe_params'     => FrmFormsHelper::reserved_words(),
2261
				/* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/
2262
				'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ),
2263
				/* 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. */
2264
				'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ),
2265
				'reserved_words'    => __( 'See the list of reserved words in WordPress.', 'formidable' ),
2266
				'repeat_limit_min'  => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
2267
				'checkbox_limit'    => __( 'Please select a limit between 0 and 200.', 'formidable' ),
2268
				'install'           => __( 'Install', 'formidable' ),
2269
				'active'            => __( 'Active', 'formidable' ),
2270
				'select_a_field'    => __( 'Select a Field', 'formidable' ),
2271
				'no_items_found'    => __( 'No items found.', 'formidable' ),
2272
			);
2273
2274
			$data = $wp_scripts->get_data( 'formidable_admin', 'data' );
2275
			if ( empty( $data ) ) {
2276
				wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings );
2277
			}
2278
		}
2279
	}
2280
2281
	/**
2282
	 * Echo the message on the plugins listing page
2283
	 *
2284
	 * @since 1.07.10
2285
	 *
2286
	 * @param float $min_version The version the add-on requires
2287
	 */
2288
	public static function min_version_notice( $min_version ) {
2289
		$frm_version = self::plugin_version();
2290
2291
		// Check if Formidable meets minimum requirements.
2292
		if ( version_compare( $frm_version, $min_version, '>=' ) ) {
2293
			return;
2294
		}
2295
2296
		$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
2297
		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">' .
2298
			esc_html__( 'You are running an outdated version of Formidable. This plugin may not work correctly if you do not update Formidable.', 'formidable' ) .
2299
			'</div></td></tr>';
2300
	}
2301
2302
	/**
2303
	 * If Pro is far outdated, show a message.
2304
	 *
2305
	 * @since 4.0.01
2306
	 */
2307
	public static function min_pro_version_notice( $min_version ) {
2308
		if ( ! self::is_formidable_admin() ) {
2309
			// Don't show admin-wide.
2310
			return;
2311
		}
2312
2313
		self::php_version_notice();
2314
2315
		$is_pro = self::pro_is_installed() && class_exists( 'FrmProDb' );
2316
		if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) {
2317
			return;
2318
		}
2319
2320
		$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...
2321
		$expired = FrmAddonsController::is_license_expired();
2322
		?>
2323
		<div class="error frm_previous_install">
2324
			<?php
2325
			esc_html_e( 'You are running a version of Formidable Forms that may not be compatible with your version of Formidable Forms Pro.', 'formidable' );
2326
			if ( empty( $expired ) ) {
2327
				echo ' Please <a href="' . esc_url( admin_url( 'plugins.php?s=formidable%20forms%20pro' ) ) . '">update now</a>.';
2328
			} else {
2329
				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.';
2330
			}
2331
			?>
2332
		</div>
2333
		<?php
2334
	}
2335
2336
	/**
2337
	 * If Pro is installed, check the version number.
2338
	 *
2339
	 * @since 4.0.01
2340
	 */
2341
	public static function meets_min_pro_version( $min_version ) {
2342
		return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' );
2343
	}
2344
2345
	/**
2346
	 * Show a message if the browser or PHP version is below the recommendations.
2347
	 *
2348
	 * @since 4.0.02
2349
	 */
2350
	private static function php_version_notice() {
2351
		$message = array();
2352
		if ( version_compare( phpversion(), '5.6', '<' ) ) {
2353
			$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' );
2354
		}
2355
2356
		$browser = self::get_server_value( 'HTTP_USER_AGENT' );
2357
		$is_ie   = strpos( $browser, 'MSIE' ) !== false;
2358
		if ( $is_ie ) {
2359
			$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' );
2360
		}
2361
2362
		foreach ( $message as $m ) {
2363
			?>
2364
			<div class="error frm_previous_install">
2365
				<?php echo esc_html( $m ); ?>
2366
			</div>
2367
			<?php
2368
		}
2369
	}
2370
2371
	public static function locales( $type = 'date' ) {
2372
		$locales = array(
2373
			'en'     => __( 'English', 'formidable' ),
2374
			'af'     => __( 'Afrikaans', 'formidable' ),
2375
			'sq'     => __( 'Albanian', 'formidable' ),
2376
			'ar'     => __( 'Arabic', 'formidable' ),
2377
			'hy'     => __( 'Armenian', 'formidable' ),
2378
			'az'     => __( 'Azerbaijani', 'formidable' ),
2379
			'eu'     => __( 'Basque', 'formidable' ),
2380
			'bs'     => __( 'Bosnian', 'formidable' ),
2381
			'bg'     => __( 'Bulgarian', 'formidable' ),
2382
			'ca'     => __( 'Catalan', 'formidable' ),
2383
			'zh-HK'  => __( 'Chinese Hong Kong', 'formidable' ),
2384
			'zh-CN'  => __( 'Chinese Simplified', 'formidable' ),
2385
			'zh-TW'  => __( 'Chinese Traditional', 'formidable' ),
2386
			'hr'     => __( 'Croatian', 'formidable' ),
2387
			'cs'     => __( 'Czech', 'formidable' ),
2388
			'da'     => __( 'Danish', 'formidable' ),
2389
			'nl'     => __( 'Dutch', 'formidable' ),
2390
			'en-GB'  => __( 'English/UK', 'formidable' ),
2391
			'eo'     => __( 'Esperanto', 'formidable' ),
2392
			'et'     => __( 'Estonian', 'formidable' ),
2393
			'fo'     => __( 'Faroese', 'formidable' ),
2394
			'fa'     => __( 'Farsi/Persian', 'formidable' ),
2395
			'fil'    => __( 'Filipino', 'formidable' ),
2396
			'fi'     => __( 'Finnish', 'formidable' ),
2397
			'fr'     => __( 'French', 'formidable' ),
2398
			'fr-CA'  => __( 'French/Canadian', 'formidable' ),
2399
			'fr-CH'  => __( 'French/Swiss', 'formidable' ),
2400
			'de'     => __( 'German', 'formidable' ),
2401
			'de-AT'  => __( 'German/Austria', 'formidable' ),
2402
			'de-CH'  => __( 'German/Switzerland', 'formidable' ),
2403
			'el'     => __( 'Greek', 'formidable' ),
2404
			'he'     => __( 'Hebrew', 'formidable' ),
2405
			'iw'     => __( 'Hebrew', 'formidable' ),
2406
			'hi'     => __( 'Hindi', 'formidable' ),
2407
			'hu'     => __( 'Hungarian', 'formidable' ),
2408
			'is'     => __( 'Icelandic', 'formidable' ),
2409
			'id'     => __( 'Indonesian', 'formidable' ),
2410
			'it'     => __( 'Italian', 'formidable' ),
2411
			'ja'     => __( 'Japanese', 'formidable' ),
2412
			'ko'     => __( 'Korean', 'formidable' ),
2413
			'lv'     => __( 'Latvian', 'formidable' ),
2414
			'lt'     => __( 'Lithuanian', 'formidable' ),
2415
			'ms'     => __( 'Malaysian', 'formidable' ),
2416
			'no'     => __( 'Norwegian', 'formidable' ),
2417
			'pl'     => __( 'Polish', 'formidable' ),
2418
			'pt'     => __( 'Portuguese', 'formidable' ),
2419
			'pt-BR'  => __( 'Portuguese/Brazilian', 'formidable' ),
2420
			'pt-PT'  => __( 'Portuguese/Portugal', 'formidable' ),
2421
			'ro'     => __( 'Romanian', 'formidable' ),
2422
			'ru'     => __( 'Russian', 'formidable' ),
2423
			'sr'     => __( 'Serbian', 'formidable' ),
2424
			'sr-SR'  => __( 'Serbian', 'formidable' ),
2425
			'sk'     => __( 'Slovak', 'formidable' ),
2426
			'sl'     => __( 'Slovenian', 'formidable' ),
2427
			'es'     => __( 'Spanish', 'formidable' ),
2428
			'es-419' => __( 'Spanish/Latin America', 'formidable' ),
2429
			'sv'     => __( 'Swedish', 'formidable' ),
2430
			'ta'     => __( 'Tamil', 'formidable' ),
2431
			'th'     => __( 'Thai', 'formidable' ),
2432
			'tu'     => __( 'Turkish', 'formidable' ),
2433
			'tr'     => __( 'Turkish', 'formidable' ),
2434
			'uk'     => __( 'Ukranian', 'formidable' ),
2435
			'vi'     => __( 'Vietnamese', 'formidable' ),
2436
		);
2437
2438
		if ( $type === 'captcha' ) {
2439
			// remove the languages unavailable for the captcha
2440
			$unset = array( 'af', 'sq', 'hy', 'az', 'eu', 'bs', 'zh-HK', 'eo', 'et', 'fo', 'fr-CH', 'he', 'is', 'ms', 'sr-SR', 'ta', 'tu' );
2441
		} else {
2442
			// remove the languages unavailable for the datepicker
2443
			$unset = array( 'fil', 'fr-CA', 'de-AT', 'de-CH', 'iw', 'hi', 'pt', 'pt-PT', 'es-419', 'tr' );
2444
		}
2445
2446
		$locales = array_diff_key( $locales, array_flip( $unset ) );
2447
		$locales = apply_filters( 'frm_locales', $locales );
2448
2449
		return $locales;
2450
	}
2451
2452
	/**
2453
	 * @deprecated 4.0
2454
	 */
2455
	public static function insert_opt_html( $args ) {
2456
		_deprecated_function( __METHOD__, '4.0', 'FrmFormsHelper::insert_opt_html' );
2457
		FrmFormsHelper::insert_opt_html( $args );
2458
	}
2459
2460
	/**
2461
	 * Used to filter shortcode in text widgets
2462
	 *
2463
	 * @deprecated 2.5.4
2464
	 * @codeCoverageIgnore
2465
	 */
2466
	public static function widget_text_filter_callback( $matches ) {
2467
		return FrmDeprecated::widget_text_filter_callback( $matches );
2468
	}
2469
2470
	/**
2471
	 * @deprecated 3.01
2472
	 * @codeCoverageIgnore
2473
	 */
2474
	public static function sanitize_array( &$values ) {
2475
		FrmDeprecated::sanitize_array( $values );
2476
	}
2477
2478
	/**
2479
	 * @param array $settings
2480
	 * @param string $group
2481
	 *
2482
	 * @since 2.0.6
2483
	 * @deprecated 2.05.06
2484
	 * @codeCoverageIgnore
2485
	 */
2486
	public static function save_settings( $settings, $group ) {
2487
		return FrmDeprecated::save_settings( $settings, $group );
2488
	}
2489
2490
	/**
2491
	 * @since 2.0.4
2492
	 * @deprecated 2.05.06
2493
	 * @codeCoverageIgnore
2494
	 */
2495
	public static function save_json_post( $settings ) {
2496
		return FrmDeprecated::save_json_post( $settings );
2497
	}
2498
2499
	/**
2500
	 * @since 2.0
2501
	 * @deprecated 2.05.06
2502
	 * @codeCoverageIgnore
2503
	 *
2504
	 * @param string $cache_key The unique name for this cache
2505
	 * @param string $group The name of the cache group
2506
	 * @param string $query If blank, don't run a db call
2507
	 * @param string $type The wpdb function to use with this query
2508
	 *
2509
	 * @return mixed $results The cache or query results
2510
	 */
2511
	public static function check_cache( $cache_key, $group = '', $query = '', $type = 'get_var', $time = 300 ) {
2512
		return FrmDeprecated::check_cache( $cache_key, $group, $query, $type, $time );
2513
	}
2514
2515
	/**
2516
	 * @deprecated 2.05.06
2517
	 * @codeCoverageIgnore
2518
	 */
2519
	public static function set_cache( $cache_key, $results, $group = '', $time = 300 ) {
2520
		return FrmDeprecated::set_cache( $cache_key, $results, $group, $time );
2521
	}
2522
2523
	/**
2524
	 * @deprecated 2.05.06
2525
	 * @codeCoverageIgnore
2526
	 */
2527
	public static function add_key_to_group_cache( $key, $group ) {
2528
		FrmDeprecated::add_key_to_group_cache( $key, $group );
2529
	}
2530
2531
	/**
2532
	 * @deprecated 2.05.06
2533
	 * @codeCoverageIgnore
2534
	 */
2535
	public static function get_group_cached_keys( $group ) {
2536
		return FrmDeprecated::get_group_cached_keys( $group );
2537
	}
2538
2539
	/**
2540
	 * @since 2.0
2541
	 * @deprecated 2.05.06
2542
	 * @codeCoverageIgnore
2543
	 * @return mixed The cached value or false
2544
	 */
2545
	public static function check_cache_and_transient( $cache_key ) {
2546
		return FrmDeprecated::check_cache( $cache_key );
2547
	}
2548
2549
	/**
2550
	 * @since 2.0
2551
	 * @deprecated 2.05.06
2552
	 * @codeCoverageIgnore
2553
	 *
2554
	 * @param string $cache_key
2555
	 */
2556
	public static function delete_cache_and_transient( $cache_key, $group = 'default' ) {
2557
		FrmDeprecated::delete_cache_and_transient( $cache_key, $group );
2558
	}
2559
2560
	/**
2561
	 * @since 2.0
2562
	 * @deprecated 2.05.06
2563
	 * @codeCoverageIgnore
2564
	 *
2565
	 * @param string $group The name of the cache group
2566
	 */
2567
	public static function cache_delete_group( $group ) {
2568
		FrmDeprecated::cache_delete_group( $group );
2569
	}
2570
2571
	/**
2572
	 * @since 1.07.10
2573
	 * @deprecated 2.05.06
2574
	 * @codeCoverageIgnore
2575
	 *
2576
	 * @param string $term The value to escape
2577
	 *
2578
	 * @return string The escaped value
2579
	 */
2580
	public static function esc_like( $term ) {
2581
		return FrmDeprecated::esc_like( $term );
2582
	}
2583
2584
	/**
2585
	 * @param string $order_query
2586
	 *
2587
	 * @deprecated 2.05.06
2588
	 * @codeCoverageIgnore
2589
	 */
2590
	public static function esc_order( $order_query ) {
2591
		return FrmDeprecated::esc_order( $order_query );
2592
	}
2593
2594
	/**
2595
	 * @deprecated 2.05.06
2596
	 * @codeCoverageIgnore
2597
	 */
2598
	public static function esc_order_by( &$order_by ) {
2599
		FrmDeprecated::esc_order_by( $order_by );
2600
	}
2601
2602
	/**
2603
	 * @param string $limit
2604
	 *
2605
	 * @deprecated 2.05.06
2606
	 * @codeCoverageIgnore
2607
	 */
2608
	public static function esc_limit( $limit ) {
2609
		return FrmDeprecated::esc_limit( $limit );
2610
	}
2611
2612
	/**
2613
	 * @since 2.0
2614
	 * @deprecated 2.05.06
2615
	 * @codeCoverageIgnore
2616
	 */
2617
	public static function prepare_array_values( $array, $type = '%s' ) {
2618
		return FrmDeprecated::prepare_array_values( $array, $type );
2619
	}
2620
2621
	/**
2622
	 * @deprecated 2.05.06
2623
	 * @codeCoverageIgnore
2624
	 */
2625
	public static function prepend_and_or_where( $starts_with = ' WHERE ', $where = '' ) {
2626
		return FrmDeprecated::prepend_and_or_where( $starts_with, $where );
2627
	}
2628
}
2629