Completed
Push — master ( da536e...a50277 )
by Stephanie
02:41
created

FrmAppHelper::get_settings()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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