Completed
Push — master ( 68fe52...454706 )
by Stephanie
02:58
created

FrmAppHelper::add_value_to_array()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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