Completed
Push — master ( feb49b...2e7061 )
by Stephanie
06:17 queued 03:03
created

FrmAppHelper::icon_by_class()   B

Complexity

Conditions 7
Paths 40

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

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