Completed
Push — master ( 368c73...94ce40 )
by Stephanie
02:18
created

FrmAppHelper::fill_field_defaults()   C

Complexity

Conditions 11
Paths 32

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 32
nop 4
dl 0
loc 51
rs 6.9224
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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