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

FrmFormsHelper   F

Complexity

Total Complexity 227

Size/Duplication

Total Lines 1199
Duplicated Lines 1.92 %

Coupling/Cohesion

Components 3
Dependencies 9

Importance

Changes 0
Metric Value
dl 23
loc 1199
rs 0.8038
c 0
b 0
f 0
wmc 227
lcom 3
cbo 9

50 Methods

Rating   Name   Duplication   Size   Complexity  
A form_error_class() 0 3 1
A get_direct_link() 0 6 1
B forms_dropdown() 0 41 8
A add_html_attr() 0 5 2
A builder_submit_button() 0 3 1
A get_sortable_classes() 0 4 4
A get_field_link_name() 0 9 2
A get_field_link_icon() 0 9 3
A get_invalid_error_message() 0 10 2
A get_success_message() 0 7 1
B setup_new_vars() 10 46 10
A setup_edit_vars() 0 13 4
D fill_default_opts() 0 30 24
A get_default_opts() 0 19 1
A fill_form_options() 0 7 3
A get_default_html() 0 22 3
A get_draft_link() 0 5 1
A get_custom_submit() 0 25 4
B html_shortcodes() 0 82 1
B insert_opt_html() 0 34 8
A insert_code_html() 0 24 3
A prepare_field_type() 0 8 2
B auto_add_end_section_fields() 0 50 9
A maybe_create_end_section() 0 18 3
C replace_shortcodes() 0 49 12
A submit_button_label() 0 8 3
A maybe_hide_inline() 0 8 3
B get_form_style_class() 0 30 7
A maybe_align_fields_top() 0 3 2
B form_has_top_labels() 0 21 6
A field_has_top_label() 0 5 1
C get_form_style() 0 21 15
A show_errors() 0 18 2
B show_error() 0 24 8
A maybe_get_scroll_js() 0 6 2
A get_scroll_js() 0 3 1
A actions_dropdown() 0 9 3
B get_action_links() 0 34 6
A edit_form_link() 0 17 4
A delete_trash_link() 0 5 1
B format_link_html() 0 23 8
A delete_trash_info() 0 17 4
A delete_trash_links() 0 27 1
A css_classes() 0 26 1
A grid_classes() 0 29 2
A style_class_label() 0 12 4
A status_nice_name() 0 15 2
A show_plan_required() 0 14 2
A get_plan_required() 0 16 6
F form_switcher() 13 74 20

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FrmFormsHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FrmFormsHelper, and based on these observations, apply Extract Interface, too.

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	die( 'You are not allowed to call this page directly.' );
4
}
5
6
class FrmFormsHelper {
7
8
	/**
9
	 * @since 2.2.10
10
	 */
11
	public static function form_error_class() {
12
		return apply_filters( 'frm_form_error_class', 'frm_error_style' );
13
	}
14
15
	public static function get_direct_link( $key, $form = false ) {
16
		$target_url = esc_url( admin_url( 'admin-ajax.php?action=frm_forms_preview&form=' . $key ) );
17
		$target_url = apply_filters( 'frm_direct_link', $target_url, $key, $form );
18
19
		return $target_url;
20
	}
21
22
	public static function forms_dropdown( $field_name, $field_value = '', $args = array() ) {
23
		$defaults = array(
24
			'blank'        => true,
25
			'field_id'     => false,
26
			'onchange'     => false,
27
			'exclude'      => false,
28
			'class'        => '',
29
			'inc_children' => 'exclude',
30
		);
31
		$args     = wp_parse_args( $args, $defaults );
32
33
		if ( ! $args['field_id'] ) {
34
			$args['field_id'] = $field_name;
35
		}
36
37
		$query = array();
38
		if ( $args['exclude'] ) {
39
			$query['id !'] = $args['exclude'];
40
		}
41
42
		$where    = apply_filters( 'frm_forms_dropdown', $query, $field_name );
43
		$forms    = FrmForm::get_published_forms( $where, 999, $args['inc_children'] );
44
		$add_html = array();
45
		self::add_html_attr( $args['onchange'], 'onchange', $add_html );
46
		self::add_html_attr( $args['class'], 'class', $add_html );
47
48
		?>
49
		<select name="<?php echo esc_attr( $field_name ); ?>"
50
			id="<?php echo esc_attr( $args['field_id'] ); ?>"
51
			<?php echo wp_strip_all_tags( implode( ' ', $add_html ) ); // WPCS: XSS ok. ?>>
52
			<?php if ( $args['blank'] ) { ?>
53
				<option value=""><?php echo ( $args['blank'] == 1 ) ? ' ' : '- ' . esc_attr( $args['blank'] ) . ' -'; ?></option>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
54
			<?php } ?>
55
			<?php foreach ( $forms as $form ) { ?>
56
				<option value="<?php echo esc_attr( $form->id ); ?>" <?php selected( $field_value, $form->id ); ?>>
57
					<?php echo esc_html( '' === $form->name ? __( '(no title)', 'formidable' ) : FrmAppHelper::truncate( $form->name, 50 ) . ( $form->parent_form_id ? __( ' (child)', 'formidable' ) : '' ) ); ?>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
58
				</option>
59
			<?php } ?>
60
		</select>
61
		<?php
62
	}
63
64
	/**
65
	 * @param string $class
66
	 * @param string $param
67
	 * @param array $add_html
68
	 *
69
	 * @since 2.0.6
70
	 */
71
	public static function add_html_attr( $class, $param, &$add_html ) {
72
		if ( ! empty( $class ) ) {
73
			$add_html[ $param ] = sanitize_title( $param ) . '="' . esc_attr( trim( sanitize_text_field( $class ) ) ) . '"';
74
		}
75
	}
76
77
	public static function form_switcher( $selected = false ) {
78
		$where = apply_filters( 'frm_forms_dropdown', array(), '' );
79
		$forms = FrmForm::get_published_forms( $where );
80
81
		$args = array(
82
			'id'   => 0,
83
			'form' => 0,
84
		);
85
		if ( isset( $_GET['id'] ) && ! isset( $_GET['form'] ) ) {
86
			unset( $args['form'] );
87
		} elseif ( isset( $_GET['form'] ) && ! isset( $_GET['id'] ) ) {
88
			unset( $args['id'] );
89
		}
90
91
		$frm_action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
92
		if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) && in_array( $frm_action, array( 'edit', 'show', 'destroy_all' ) ) ) {
93
			$args['frm_action'] = 'list';
94
			$args['form']       = 0;
95
		} elseif ( FrmAppHelper::is_admin_page( 'formidable' ) && in_array( $frm_action, array( 'new', 'duplicate' ) ) ) {
96
			$args['frm_action'] = 'edit';
97
		} elseif ( isset( $_GET['post'] ) ) {
98
			$args['form'] = 0;
99
			$base         = admin_url( 'edit.php?post_type=frm_display' );
100
		}
101
102
		$name = ( $selected === false ) ? __( 'Switch Form', 'formidable' ) : $selected;
103
		$name = '' === $name ? __( '(no title)', 'formidable' ) : strip_tags( $name );
104
		$truncated_name = FrmAppHelper::truncate( $name, 20 );
105
106
		?>
107
		<div id="frm_bs_dropdown" class="dropdown <?php echo esc_attr( is_rtl() ? 'pull-right' : 'pull-left' ); ?>">
108
			<a href="#" id="frm-navbarDrop" class="frm-dropdown-toggle" data-toggle="dropdown">
109
				<h1 title="<?php echo esc_attr( $truncated_name === $name ? '' : $name ); ?>">
110
					<?php echo esc_html( $truncated_name ); ?>
111
					<?php FrmAppHelper::icon_by_class( 'frmfont frm_arrowdown4_icon', array( 'aria-hidden' => 'true' ) ); ?>
112
				</h1>
113
			</a>
114
			<ul class="frm-dropdown-menu frm-on-top frm-inline-modal frm_code_list frm-full-hover" role="menu" aria-labelledby="frm-navbarDrop">
115 View Code Duplication
				<?php if ( count( $forms ) > 8 ) { ?>
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...
116
				<li class="frm-with-search">
117
					<?php
118
					FrmAppHelper::show_search_box(
119
						array(
120
							'input_id'    => 'dropform',
121
							'placeholder' => __( 'Search Forms', 'formidable' ),
122
							'tosearch'    => 'frm-dropdown-form',
123
						)
124
					);
125
					?>
126
				</li>
127
				<?php } ?>
128
				<?php
129
				foreach ( $forms as $form ) {
130
					if ( isset( $args['id'] ) ) {
131
						$args['id'] = $form->id;
132
					}
133
					if ( isset( $args['form'] ) ) {
134
						$args['form'] = $form->id;
135
					}
136
137
					$url       = isset( $base ) ? add_query_arg( $args, $base ) : add_query_arg( $args );
138
					$form_name = empty( $form->name ) ? __( '(no title)', 'formidable' ) : $form->name;
139
					?>
140
					<li class="frm-dropdown-form">
141
						<a href="<?php echo esc_url( $url ); ?>" tabindex="-1"><?php echo esc_html( $form_name ); ?></a>
142
					</li>
143
					<?php
144
					unset( $form );
145
				}
146
				?>
147
			</ul>
148
		</div>
149
		<?php
150
	}
151
152
	/**
153
	 * @since 3.05
154
	 * @deprecated 4.0
155
	 *
156
	 * @param array $values - The form array
157
	 */
158
	public static function builder_submit_button( $values ) {
159
		FrmDeprecated::builder_submit_button( $values );
160
	}
161
162
	public static function get_sortable_classes( $col, $sort_col, $sort_dir ) {
163
		echo ( $sort_col == $col ) ? 'sorted' : 'sortable';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
164
		echo ( $sort_col == $col && $sort_dir == 'desc' ) ? ' asc' : ' desc';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
165
	}
166
167
	/**
168
	 * @since 3.0
169
	 */
170
	public static function get_field_link_name( $field_type ) {
171
		if ( is_array( $field_type ) ) {
172
			$field_label = $field_type['name'];
173
		} else {
174
			$field_label = $field_type;
175
		}
176
177
		return $field_label;
178
	}
179
180
	/**
181
	 * @since 3.0
182
	 */
183
	public static function get_field_link_icon( $field_type ) {
184
		if ( is_array( $field_type ) && isset( $field_type['icon'] ) ) {
185
			$icon = $field_type['icon'];
186
		} else {
187
			$icon = 'frm_icon_font frm_pencil_icon';
188
		}
189
190
		return $icon;
191
	}
192
193
	/**
194
	 * Get the invalid form error message
195
	 *
196
	 * @since 2.02.07
197
	 *
198
	 * @param array $args
199
	 *
200
	 * @return string
201
	 */
202
	public static function get_invalid_error_message( $args ) {
203
		$settings_args = $args;
204
		if ( isset( $args['form'] ) ) {
205
			$settings_args['current_form'] = $args['form']->id;
206
		}
207
208
		$frm_settings = FrmAppHelper::get_settings( $settings_args );
209
		$invalid_msg = do_shortcode( $frm_settings->invalid_msg );
210
		return apply_filters( 'frm_invalid_error_message', $invalid_msg, $args );
211
	}
212
213
	public static function get_success_message( $atts ) {
214
		$message = apply_filters( 'frm_content', $atts['message'], $atts['form'], $atts['entry_id'] );
215
		$message = FrmAppHelper::use_wpautop( do_shortcode( $message ) );
216
		$message = '<div class="' . esc_attr( $atts['class'] ) . '">' . $message . '</div>';
217
218
		return $message;
219
	}
220
221
	/**
222
	 * Used when a form is created
223
	 */
224
	public static function setup_new_vars( $values = array() ) {
225
		global $wpdb;
226
227
		if ( ! empty( $values ) ) {
228
			$post_values = $values;
229
		} else {
230
			$values      = array();
231
			$post_values = isset( $_POST ) ? $_POST : array();
232
		}
233
234
		$defaults = array(
235
			'name'        => '',
236
			'description' => '',
237
		);
238 View Code Duplication
		foreach ( $defaults as $var => $default ) {
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...
239
			if ( ! isset( $values[ $var ] ) ) {
240
				$values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
241
			}
242
		}
243
244
		$values['description'] = FrmAppHelper::use_wpautop( $values['description'] );
245
246
		$defaults = array(
247
			'form_id'        => '',
248
			'logged_in'      => '',
249
			'editable'       => '',
250
			'is_template'    => 0,
251
			'status'         => 'published',
252
			'parent_form_id' => 0,
253
		);
254 View Code Duplication
		foreach ( $defaults as $var => $default ) {
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...
255
			if ( ! isset( $values[ $var ] ) ) {
256
				$values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
257
			}
258
		}
259
		unset( $defaults );
260
261
		if ( ! isset( $values['form_key'] ) ) {
262
			$values['form_key'] = ( $post_values && isset( $post_values['form_key'] ) ) ? $post_values['form_key'] : FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_forms', 'form_key' );
263
		}
264
265
		$values                 = self::fill_default_opts( $values, false, $post_values );
266
		$values['custom_style'] = FrmAppHelper::custom_style_value( $post_values );
267
268
		return apply_filters( 'frm_setup_new_form_vars', $values );
269
	}
270
271
	/**
272
	 * Used when editing a form
273
	 */
274
	public static function setup_edit_vars( $values, $record, $post_values = array() ) {
275
		if ( empty( $post_values ) ) {
276
			$post_values = wp_unslash( $_POST );
277
		}
278
279
		$values['form_key']    = isset( $post_values['form_key'] ) ? $post_values['form_key'] : $record->form_key;
280
		$values['is_template'] = isset( $post_values['is_template'] ) ? $post_values['is_template'] : $record->is_template;
281
		$values['status']      = $record->status;
282
283
		$values = self::fill_default_opts( $values, $record, $post_values );
284
285
		return apply_filters( 'frm_setup_edit_form_vars', $values );
286
	}
287
288
	public static function fill_default_opts( $values, $record, $post_values ) {
289
290
		$defaults = self::get_default_opts();
291
		foreach ( $defaults as $var => $default ) {
292
			if ( is_array( $default ) ) {
293
				if ( ! isset( $values[ $var ] ) ) {
294
					$values[ $var ] = ( $record && isset( $record->options[ $var ] ) ) ? $record->options[ $var ] : array();
295
				}
296
297
				foreach ( $default as $k => $v ) {
298
					$values[ $var ][ $k ] = ( $post_values && isset( $post_values[ $var ][ $k ] ) ) ? $post_values[ $var ][ $k ] : ( ( $record && isset( $record->options[ $var ] ) && isset( $record->options[ $var ][ $k ] ) ) ? $record->options[ $var ][ $k ] : $v );
299
300
					if ( is_array( $v ) ) {
301
						foreach ( $v as $k1 => $v1 ) {
302
							$values[ $var ][ $k ][ $k1 ] = ( $post_values && isset( $post_values[ $var ][ $k ][ $k1 ] ) ) ? $post_values[ $var ][ $k ][ $k1 ] : ( ( $record && isset( $record->options[ $var ] ) && isset( $record->options[ $var ][ $k ] ) && isset( $record->options[ $var ][ $k ][ $k1 ] ) ) ? $record->options[ $var ][ $k ][ $k1 ] : $v1 );
303
							unset( $k1, $v1 );
304
						}
305
					}
306
307
					unset( $k, $v );
308
				}
309
			} else {
310
				$values[ $var ] = ( $post_values && isset( $post_values['options'][ $var ] ) ) ? $post_values['options'][ $var ] : ( ( $record && isset( $record->options[ $var ] ) ) ? $record->options[ $var ] : $default );
311
			}
312
313
			unset( $var, $default );
314
		}
315
316
		return $values;
317
	}
318
319
	public static function get_default_opts() {
320
		$frm_settings = FrmAppHelper::get_settings();
321
322
		return array(
323
			'submit_value'   => $frm_settings->submit_value,
324
			'success_action' => 'message',
325
			'success_msg'    => $frm_settings->success_msg,
326
			'show_form'      => 0,
327
			'akismet'        => '',
328
			'no_save'        => 0,
329
			'ajax_load'      => 0,
330
			'js_validate'    => 0,
331
			'form_class'     => '',
332
			'custom_style'   => 1,
333
			'before_html'    => self::get_default_html( 'before' ),
334
			'after_html'     => '',
335
			'submit_html'    => self::get_default_html( 'submit' ),
336
		);
337
	}
338
339
	/**
340
	 * @param array $options
341
	 * @param array $values
342
	 *
343
	 * @since 2.0.6
344
	 */
345
	public static function fill_form_options( &$options, $values ) {
346
		$defaults = self::get_default_opts();
347
		foreach ( $defaults as $var => $default ) {
348
			$options[ $var ] = isset( $values['options'][ $var ] ) ? $values['options'][ $var ] : $default;
349
			unset( $var, $default );
350
		}
351
	}
352
353
	/**
354
	 * @param string $loc
355
	 */
356
	public static function get_default_html( $loc ) {
357
		if ( $loc == 'submit' ) {
358
			$draft_link   = self::get_draft_link();
359
			$default_html = <<<SUBMIT_HTML
360
<div class="frm_submit">
361
[if back_button]<button type="submit" name="frm_prev_page" formnovalidate="formnovalidate" class="frm_prev_page" [back_hook]>[back_label]</button>[/if back_button]
362
<button class="frm_button_submit" type="submit"  [button_action]>[button_label]</button>
363
$draft_link
364
</div>
365
SUBMIT_HTML;
366
		} elseif ( $loc == 'before' ) {
367
			$default_html = <<<BEFORE_HTML
368
<legend class="frm_screen_reader">[form_name]</legend>
369
[if form_name]<h3 class="frm_form_title">[form_name]</h3>[/if form_name]
370
[if form_description]<div class="frm_description">[form_description]</div>[/if form_description]
371
BEFORE_HTML;
372
		} else {
373
			$default_html = '';
374
		}
375
376
		return $default_html;
377
	}
378
379
	public static function get_draft_link() {
380
		$link = '[if save_draft]<a href="#" tabindex="0" class="frm_save_draft" [draft_hook]>[draft_label]</a>[/if save_draft]';
381
382
		return $link;
383
	}
384
385
	public static function get_custom_submit( $html, $form, $submit, $form_action, $values ) {
386
		$button = self::replace_shortcodes( $html, $form, $submit, $form_action, $values );
387
		if ( ! strpos( $button, '[button_action]' ) ) {
388
			echo $button; // WPCS: XSS ok.
389
390
			return;
391
		}
392
393
		$button_parts = explode( '[button_action]', $button );
394
395
		$classes = apply_filters( 'frm_submit_button_class', array(), $form );
396
		if ( ! empty( $classes ) ) {
397
			$classes      = implode( ' ', $classes );
398
			$button_class = ' class="frm_button_submit';
399
			if ( strpos( $button_parts[0], $button_class ) !== false ) {
400
				$button_parts[0] = str_replace( $button_class, $button_class . ' ' . esc_attr( $classes ), $button_parts[0] );
401
			} else {
402
				$button_parts[0] .= ' class="' . esc_attr( $classes ) . '"';
403
			}
404
		}
405
406
		echo $button_parts[0]; // WPCS: XSS ok.
407
		do_action( 'frm_submit_button_action', $form, $form_action );
408
		echo $button_parts[1]; // WPCS: XSS ok.
409
	}
410
411
	/**
412
	 * @since 4.0
413
	 */
414
	public static function html_shortcodes() {
415
		$codes = array(
416
			'id'             => array(
417
				'label' => __( 'Field ID', 'formidable' ),
418
				'class' => 'show_field_custom_html',
419
			),
420
			'key'            => array(
421
				'label' => __( 'Field Key', 'formidable' ),
422
				'class' => 'show_field_custom_html',
423
			),
424
			'field_name'     => array(
425
				'label' => __( 'Field Name', 'formidable' ),
426
				'class' => 'show_field_custom_html',
427
			),
428
			'description'    => array(
429
				'label' => __( 'Field Description', 'formidable' ),
430
				'class' => 'show_field_custom_html',
431
			),
432
			'label_position' => array(
433
				'label' => __( 'Label Position', 'formidable' ),
434
				'class' => 'show_field_custom_html',
435
			),
436
			'required_label' => array(
437
				'label' => __( 'Required Label', 'formidable' ),
438
				'class' => 'show_field_custom_html',
439
			),
440
			'input'          => array(
441
				'label' => __( 'Input Field', 'formidable' ),
442
				'class' => 'show_field_custom_html',
443
			),
444
			'input opt=1'    => array(
445
				'label' => __( 'Single Option', 'formidable' ),
446
				'title' => __( 'Show a single radio or checkbox option by replacing 1 with the order of the option', 'formidable' ),
447
				'class' => 'show_field_custom_html',
448
			),
449
			'input label=0'  => array(
450
				'label' => __( 'Hide Option Label', 'formidable' ),
451
				'class' => 'show_field_custom_html',
452
			),
453
			'required_class' => array(
454
				'label' => __( 'Required Class', 'formidable' ),
455
				'title' => __( 'Add class name if field is required', 'formidable' ),
456
				'class' => 'show_field_custom_html',
457
			),
458
			'error_class'    => array(
459
				'label' => __( 'Error Class', 'formidable' ),
460
				'title' => __( 'Add class name if field has an error on form submit', 'formidable' ),
461
				'class' => 'show_field_custom_html',
462
			),
463
464
			'form_name'        => array(
465
				'label' => __( 'Form Name', 'formidable' ),
466
				'class' => 'show_before_html show_after_html',
467
			),
468
			'form_description' => array(
469
				'label' => __( 'Form Description', 'formidable' ),
470
				'class' => 'show_before_html show_after_html',
471
			),
472
			'form_key'         => array(
473
				'label' => __( 'Form Key', 'formidable' ),
474
				'class' => 'show_before_html show_after_html',
475
			),
476
			'deletelink'       => array(
477
				'label' => __( 'Delete Entry Link', 'formidable' ),
478
				'class' => 'show_before_html show_after_html',
479
			),
480
481
			'button_label' => array(
482
				'label' => __( 'Button Label', 'formidable' ),
483
				'class' => 'show_submit_html',
484
			),
485
			'button_action' => array(
486
				'label' => __( 'Button Hook', 'formidable' ),
487
				'class' => 'show_submit_html',
488
			),
489
		);
490
491
		/**
492
		 * @since 4.0
493
		 */
494
		return apply_filters( 'frm_html_codes', $codes );
495
	}
496
497
	/**
498
	 * @since 4.0
499
	 * @param array $args
500
	 */
501
	public static function insert_opt_html( $args ) {
502
		$class  = isset( $args['class'] ) ? $args['class'] : '';
503
		$fields = FrmField::all_field_selection();
504
		$field  = isset( $fields[ $args['type'] ] ) ? $fields[ $args['type'] ] : array();
505
506
		self::prepare_field_type( $field );
507
508
		if ( ! isset( $field['icon'] ) ) {
509
			$field['icon'] = 'frmfont frm_pencil_icon';
510
		}
511
512
		$possible_email_field = FrmFieldFactory::field_has_property( $args['type'], 'holds_email_values' );
513
		if ( $possible_email_field ) {
514
			$class .= ' show_frm_not_email_to';
515
		}
516
		?>
517
		<li class="<?php echo esc_attr( $class ); ?>">
518
			<a href="javascript:void(0)" class="frmids frm_insert_code"
519
				data-code="<?php echo esc_attr( $args['id'] ); ?>">
520
				<span>[<?php echo esc_attr( isset( $args['id_label'] ) ? $args['id_label'] : $args['id'] ); ?>]</span>
521
				<?php FrmAppHelper::icon_by_class( $field['icon'], array( 'aria-hidden' => 'true' ) ); ?>
522
				<?php echo esc_attr( FrmAppHelper::truncate( $args['name'], 60 ) ); ?>
523
			</a>
524
			<a href="javascript:void(0)" class="frmkeys frm_insert_code frm_hidden"
525
				data-code="<?php echo esc_attr( $args['key'] ); ?>">
526
				<span>[<?php echo esc_attr( FrmAppHelper::truncate( isset( $args['key_label'] ) ? $args['key_label'] : $args['key'], 7 ) ); ?>]</span>
527
				<?php if ( isset( $field['icon'] ) ) { ?>
528
					<?php FrmAppHelper::icon_by_class( $field['icon'], array( 'aria-hidden' => 'true' ) ); ?>
529
				<?php } ?>
530
				<?php echo esc_attr( FrmAppHelper::truncate( $args['name'], 60 ) ); ?>
531
			</a>
532
		</li>
533
		<?php
534
	}
535
536
	/**
537
	 * @since 4.0
538
	 * @param array $args
539
	 */
540
	public static function insert_code_html( $args ) {
541
		$defaults = array(
542
			'class' => '',
543
			'code'  => '',
544
			'label' => '',
545
			'title' => '',
546
		);
547
548
		$args        = array_merge( $defaults, $args );
549
		$has_tooltip = ! empty( $args['title'] );
550
551
		?>
552
		<li class="<?php echo esc_attr( $args['class'] ); ?>">
553
			<a href="javascript:void(0)" class="frm_insert_code <?php echo $has_tooltip ? 'frm_help' : ''; ?>"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$has_tooltip'
Loading history...
554
				<?php echo $has_tooltip ? 'title="' . esc_attr( $args['title'] ) . '"' : ''; ?>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$has_tooltip'
Loading history...
555
				data-code="<?php echo esc_attr( $args['code'] ); ?>">
556
				<span>
557
					[<?php echo esc_attr( FrmAppHelper::truncate( $args['code'], 10 ) ); ?>]
558
				</span>
559
				<?php echo esc_attr( FrmAppHelper::truncate( $args['label'], 60 ) ); ?>
560
			</a>
561
		</li>
562
		<?php
563
	}
564
565
	/**
566
	 * Some field types in add-ons may have been added with only
567
	 * a field type and name.
568
	 *
569
	 * @since 4.0
570
	 */
571
	public static function prepare_field_type( &$field ) {
572
		if ( ! is_array( $field ) ) {
573
			$field = array(
574
				'name' => $field,
575
				'icon' => 'frm_icon_font frm_pencil_icon',
576
			);
577
		}
578
	}
579
580
	/**
581
	 * Automatically add end section fields if they don't exist (2.0 migration)
582
	 *
583
	 * @since 2.0
584
	 *
585
	 * @param boolean $reset_fields
586
	 */
587
	public static function auto_add_end_section_fields( $form, $fields, &$reset_fields ) {
588
		if ( empty( $fields ) ) {
589
			return;
590
		}
591
592
		$end_section_values = apply_filters( 'frm_before_field_created', FrmFieldsHelper::setup_new_vars( 'end_divider', $form->id ) );
593
		$open               = false;
594
		$prev_order         = false;
595
		$add_order          = 0;
596
		$last_field         = false;
597
		foreach ( $fields as $field ) {
598
			if ( $prev_order === $field->field_order ) {
599
				$add_order ++;
600
			}
601
602
			if ( $add_order ) {
603
				$reset_fields       = true;
604
				$field->field_order = $field->field_order + $add_order;
605
				FrmField::update( $field->id, array( 'field_order' => $field->field_order ) );
606
			}
607
608
			switch ( $field->type ) {
609
				case 'divider':
610
					// Create an end section if open.
611
					self::maybe_create_end_section( $open, $reset_fields, $add_order, $end_section_values, $field, 'move' );
612
613
					// Mark it open for the next end section.
614
					$open = true;
615
					break;
616
				case 'break':
617
					self::maybe_create_end_section( $open, $reset_fields, $add_order, $end_section_values, $field, 'move' );
618
					break;
619
				case 'end_divider':
620
					if ( ! $open ) {
621
						// The section isn't open, so this is an extra field that needs to be removed.
622
						FrmField::destroy( $field->id );
623
						$reset_fields = true;
624
					}
625
626
					// There is already an end section here, so there is no need to create one.
627
					$open = false;
628
			}
629
			$prev_order = $field->field_order;
630
631
			$last_field = $field;
632
			unset( $field );
633
		}
634
635
		self::maybe_create_end_section( $open, $reset_fields, $add_order, $end_section_values, $last_field );
636
	}
637
638
	/**
639
	 * Create end section field if it doesn't exist. This is for migration from < 2.0
640
	 * Fix any ordering that may be messed up
641
	 */
642
	public static function maybe_create_end_section( &$open, &$reset_fields, &$add_order, $end_section_values, $field, $move = 'no' ) {
643
		if ( ! $open ) {
644
			return;
645
		}
646
647
		$end_section_values['field_order'] = $field->field_order + 1;
648
649
		FrmField::create( $end_section_values );
650
651
		if ( $move == 'move' ) {
652
			// bump the order of current field unless we're at the end of the form
653
			FrmField::update( $field->id, array( 'field_order' => $field->field_order + 2 ) );
654
		}
655
656
		$add_order    += 2;
657
		$open         = false;
658
		$reset_fields = true;
659
	}
660
661
	public static function replace_shortcodes( $html, $form, $title = false, $description = false, $values = array() ) {
662
		$codes = array(
663
			'form_name'        => $title,
664
			'form_description' => $description,
665
			'entry_key'        => true,
666
		);
667
		foreach ( $codes as $code => $show ) {
668
			if ( $code == 'form_name' ) {
669
				$replace_with = $form->name;
670
			} elseif ( $code == 'form_description' ) {
671
				$replace_with = FrmAppHelper::use_wpautop( $form->description );
672
			} elseif ( $code == 'entry_key' && isset( $_GET ) && isset( $_GET['entry'] ) ) {
673
				$replace_with = FrmAppHelper::simple_get( 'entry' );
674
			} else {
675
				$replace_with = '';
676
			}
677
678
			FrmShortcodeHelper::remove_inline_conditions( ( FrmAppHelper::is_true( $show ) && $replace_with != '' ), $code, $replace_with, $html );
679
		}
680
681
		//replace [form_key]
682
		$html = str_replace( '[form_key]', $form->form_key, $html );
683
684
		//replace [frmurl]
685
		$html = str_replace( '[frmurl]', FrmFieldsHelper::dynamic_default_values( 'frmurl' ), $html );
686
687
		if ( strpos( $html, '[button_label]' ) ) {
688
			add_filter( 'frm_submit_button', 'FrmFormsHelper::submit_button_label', 1 );
689
			$submit_label = apply_filters( 'frm_submit_button', $title, $form );
690
			$submit_label = esc_attr( do_shortcode( $submit_label ) );
691
			$html         = str_replace( '[button_label]', $submit_label, $html );
692
		}
693
694
		$html = apply_filters( 'frm_form_replace_shortcodes', $html, $form, $values );
695
696
		if ( strpos( $html, '[if back_button]' ) ) {
697
			$html = preg_replace( '/(\[if\s+back_button\])(.*?)(\[\/if\s+back_button\])/mis', '', $html );
698
		}
699
700
		if ( strpos( $html, '[if save_draft]' ) ) {
701
			$html = preg_replace( '/(\[if\s+save_draft\])(.*?)(\[\/if\s+save_draft\])/mis', '', $html );
702
		}
703
704
		if ( apply_filters( 'frm_do_html_shortcodes', true ) ) {
705
			$html = do_shortcode( $html );
706
		}
707
708
		return $html;
709
	}
710
711
	public static function submit_button_label( $submit ) {
712
		if ( ! $submit || empty( $submit ) ) {
713
			$frm_settings = FrmAppHelper::get_settings();
714
			$submit       = $frm_settings->submit_value;
715
		}
716
717
		return $submit;
718
	}
719
720
	/**
721
	 * If the Formidable styling isn't being loaded,
722
	 * use inline styling to hide the element
723
	 *
724
	 * @since 2.03.05
725
	 */
726
	public static function maybe_hide_inline() {
727
		$frm_settings = FrmAppHelper::get_settings();
728
		if ( $frm_settings->load_style == 'none' ) {
729
			echo ' style="display:none;"';
730
		} elseif ( $frm_settings->load_style == 'dynamic' ) {
731
			FrmStylesController::enqueue_style();
732
		}
733
	}
734
735
	public static function get_form_style_class( $form = false ) {
736
		$style = self::get_form_style( $form );
737
		$class = ' with_frm_style';
738
739
		if ( empty( $style ) ) {
740
			if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) ) {
741
				return $class;
742
			} else {
743
				return;
744
			}
745
		}
746
747
		// If submit button needs to be inline or centered.
748
		if ( is_object( $form ) ) {
749
			$form = $form->options;
750
		}
751
752
		$submit_align = isset( $form['submit_align'] ) ? $form['submit_align'] : '';
753
754
		if ( 'inline' === $submit_align ) {
755
			$class .= ' frm_inline_form';
756
			$class .= self::maybe_align_fields_top( $form );
757
		} elseif ( 'center' === $submit_align ) {
758
			$class .= ' frm_center_submit';
759
		}
760
761
		$class = apply_filters( 'frm_add_form_style_class', $class, $style );
762
763
		return $class;
764
	}
765
766
	/**
767
	 * Returns appropriate class if form has top labels
768
	 *
769
	 * @param $form
770
	 *
771
	 * @return string
772
	 */
773
	private static function maybe_align_fields_top( $form ) {
774
		return self::form_has_top_labels( $form ) ? ' frm_inline_top' : '';
775
	}
776
777
	/**
778
	 * Determine if a form has fields with top labels so submit button can be aligned properly
779
	 *
780
	 * @param $form
781
	 *
782
	 * @return bool
783
	 */
784
	private static function form_has_top_labels( $form ) {
785
		if ( ! isset( $form['fields'] ) ) {
786
			return false;
787
		}
788
789
		$fields = $form['fields'];
790
		if ( count( $fields ) <= 0 ) {
791
			return false;
792
		}
793
794
		$fields = array_reverse( $fields ); // start from the fields closest to the submit button
795
		foreach ( $fields as $field ) {
796
			$type      = isset( $field['original_type'] ) ? $field['original_type'] : $field['type'];
797
			$has_input = FrmFieldFactory::field_has_property( $type, 'has_input' );
798
			if ( $has_input ) {
799
				return self::field_has_top_label( $field, $form );
800
			}
801
		}
802
803
		return false;
804
	}
805
806
	/**
807
	 * Check if a field's label position is set to "top"
808
	 *
809
	 * @param $field
810
	 * @param $form
811
	 *
812
	 * @return bool
813
	 */
814
	private static function field_has_top_label( $field, $form ) {
815
		$label_position = FrmFieldsHelper::label_position( $field['label'], $field, $form );
816
817
		return in_array( $label_position, array( 'top', 'inside', 'hidden' ) );
818
	}
819
820
	/**
821
	 * @param object|string|boolean $form
822
	 *
823
	 * @return string
824
	 */
825
	public static function get_form_style( $form ) {
826
		$style = 1;
827
		if ( empty( $form ) || 'default' == 'form' ) {
828
			return $style;
829
		} elseif ( is_object( $form ) && $form->parent_form_id ) {
830
			// get the parent form if this is a child
831
			$form = $form->parent_form_id;
832
		} elseif ( is_array( $form ) && isset( $form['parent_form_id'] ) && $form['parent_form_id'] ) {
833
			$form = $form['parent_form_id'];
834
		} elseif ( is_array( $form ) && isset( $form['custom_style'] ) ) {
835
			$style = $form['custom_style'];
836
		}
837
838
		if ( $form && is_string( $form ) ) {
839
			$form = FrmForm::getOne( $form );
840
		}
841
842
		$style = ( $form && is_object( $form ) && isset( $form->options['custom_style'] ) ) ? $form->options['custom_style'] : $style;
843
844
		return $style;
845
	}
846
847
	/**
848
	 * Display the validation error messages when an entry is submitted
849
	 *
850
	 * @param array $args - includes img, errors
851
	 *
852
	 * @since 2.0.6
853
	 */
854
	public static function show_errors( $args ) {
855
		$invalid_msg = self::get_invalid_error_message( $args );
856
857
		if ( empty( $invalid_msg ) ) {
858
			$show_img = false;
859
		} else {
860
			echo wp_kses_post( $invalid_msg );
861
			$show_img = true;
862
		}
863
864
		self::show_error(
865
			array(
866
				'img'      => $args['img'],
867
				'errors'   => $args['errors'],
868
				'show_img' => $show_img,
869
			)
870
		);
871
	}
872
873
	/**
874
	 * Display the error message in the front-end along with the image if set
875
	 * The image was removed from the styling settings, but it may still be set with a hook
876
	 * If the message in the global settings is empty, show every validation message in the error box
877
	 *
878
	 * @param array $args - includes img, errors, and show_img
879
	 *
880
	 * @since 2.0.6
881
	 */
882
	public static function show_error( $args ) {
883
		// remove any blank messages
884
		$args['errors'] = array_filter( (array) $args['errors'] );
885
886
		$line_break_first = $args['show_img'];
887
		foreach ( $args['errors'] as $error_key => $error ) {
0 ignored issues
show
Bug introduced by
The expression $args['errors'] of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
888
			if ( $line_break_first && ! is_numeric( $error_key ) && ( $error_key == 'cptch_number' || strpos( $error_key, 'field' ) === 0 ) ) {
889
				continue;
890
			}
891
892
			$id = str_replace( 'field', 'field_', $error_key );
893
			echo '<div id="' . esc_attr( $id ) . '_error">';
894
895
			if ( $args['show_img'] && ! empty( $args['img'] ) ) {
896
				echo '<img src="' . esc_attr( $args['img'] ) . '" alt="" />';
897
			} else {
898
				$args['show_img'] = true;
899
			}
900
901
			echo wp_kses_post( $error );
902
903
			echo '</div>';
904
		}
905
	}
906
907
	public static function maybe_get_scroll_js( $id ) {
908
		$offset = apply_filters( 'frm_scroll_offset', 4, array( 'form_id' => $id ) );
909
		if ( $offset != - 1 ) {
910
			self::get_scroll_js( $id );
911
		}
912
	}
913
914
	public static function get_scroll_js( $form_id ) {
915
		echo '<script type="text/javascript">document.addEventListener(\'DOMContentLoaded\',function(){frmFrontForm.scrollMsg(' . (int) $form_id . ');})</script>';
916
	}
917
918
	/**
919
	 * @since 3.0
920
	 */
921
	public static function actions_dropdown( $atts ) {
922
		if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
923
			$status     = $atts['status'];
924
			$form_id    = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
925
			$trash_link = self::delete_trash_info( $form_id, $status );
926
			$links      = self::get_action_links( $form_id, $status );
927
			include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/actions-dropdown.php' );
928
		}
929
	}
930
931
	/**
932
	 * @since 3.0
933
	 */
934
	public static function get_action_links( $form_id, $form ) {
935
		if ( ! is_object( $form ) ) {
936
			$form = FrmForm::getOne( $form_id );
937
		}
938
939
		$actions     = array();
940
		$trash_links = self::delete_trash_links( $form_id );
941
		if ( 'trash' == $form->status ) {
942
			$actions['restore'] = $trash_links['restore'];
943
944
			if ( current_user_can( 'frm_delete_forms' ) ) {
945
				$actions['trash'] = $trash_links['delete'];
946
			}
947
		} elseif ( current_user_can( 'frm_edit_forms' ) ) {
948
			$duplicate_link = '?page=formidable&frm_action=duplicate&id=' . $form_id;
949
			if ( $form->is_template ) {
950
				$actions['frm_duplicate'] = array(
951
					'url'   => wp_nonce_url( $duplicate_link ),
952
					'label' => __( 'Create Form from Template', 'formidable' ),
953
					'icon'  => 'frm_icon_font frm_clone_icon',
954
				);
955
			} else {
956
				$actions['duplicate'] = array(
957
					'url'   => wp_nonce_url( $duplicate_link ),
958
					'label' => __( 'Duplicate Form', 'formidable' ),
959
					'icon'  => 'frm_icon_font frm_clone_icon',
960
				);
961
			}
962
963
			$actions['trash'] = self::delete_trash_info( $form_id, $form->status );
964
		}
965
966
		return $actions;
967
	}
968
969
	public static function edit_form_link( $form_id ) {
970
		if ( is_object( $form_id ) ) {
971
			$form    = $form_id;
972
			$name    = $form->name;
973
			$form_id = $form->id;
974
		} else {
975
			$name = FrmForm::getName( $form_id );
976
		}
977
978
		if ( $form_id ) {
979
			$val = '<a href="' . esc_url( FrmForm::get_edit_link( $form_id ) ) . '">' . ( '' == $name ? __( '(no title)', 'formidable' ) : FrmAppHelper::truncate( $name, 40 ) ) . '</a>';
980
		} else {
981
			$val = '';
982
		}
983
984
		return $val;
985
	}
986
987
	public static function delete_trash_link( $id, $status, $length = 'label' ) {
988
		$link_details = self::delete_trash_info( $id, $status );
989
990
		return self::format_link_html( $link_details, $length );
991
	}
992
993
	/**
994
	 * @since 3.0
995
	 */
996
	public static function format_link_html( $link_details, $length = 'label' ) {
997
		$link = '';
998
		if ( ! empty( $link_details ) ) {
999
			$link = '<a href="' . esc_url( $link_details['url'] ) . '" class="frm-trash-link"';
1000
			if ( isset( $link_details['data'] ) ) {
1001
				foreach ( $link_details['data'] as $data => $value ) {
1002
					$link .= ' data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '"';
1003
				}
1004
			} elseif ( isset( $link_details['confirm'] ) ) {
1005
				$link .= ' onclick="return confirm(\'' . esc_attr( $link_details['confirm'] ) . '\')"';
1006
			}
1007
1008
			$label = ( isset( $link_details[ $length ] ) ? $link_details[ $length ] : $link_details['label'] );
1009
			if ( $length == 'icon' && isset( $link_details[ $length ] ) ) {
1010
				$label = '<span class="' . $label . '" title="' . esc_attr( $link_details['label'] ) . '" aria-hidden="true"></span>';
1011
				$link  .= ' aria-label="' . esc_attr( $link_details['label'] ) . '"';
1012
			}
1013
1014
			$link .= '>' . $label . '</a>';
1015
		}
1016
1017
		return $link;
1018
	}
1019
1020
	/**
1021
	 * @since 3.0
1022
	 */
1023
	public static function delete_trash_info( $id, $status ) {
1024
		$labels = self::delete_trash_links( $id );
1025
1026
		if ( 'trash' == $status ) {
1027
			$info = $labels['restore'];
1028
		} elseif ( current_user_can( 'frm_delete_forms' ) ) {
1029
			if ( EMPTY_TRASH_DAYS ) {
1030
				$info = $labels['trash'];
1031
			} else {
1032
				$info = $labels['delete'];
1033
			}
1034
		} else {
1035
			$info = array();
1036
		}
1037
1038
		return $info;
1039
	}
1040
1041
	/**
1042
	 * @since 3.0
1043
	 */
1044
	private static function delete_trash_links( $id ) {
1045
		$current_page = FrmAppHelper::get_simple_request( array( 'param' => 'form_type' ) );
1046
		$base_url     = '?page=formidable&form_type=' . $current_page . '&id=' . $id;
1047
1048
		return array(
1049
			'restore' => array(
1050
				'label' => __( 'Restore from Trash', 'formidable' ),
1051
				'short' => __( 'Restore', 'formidable' ),
1052
				'url'   => wp_nonce_url( $base_url . '&frm_action=untrash', 'untrash_form_' . absint( $id ) ),
1053
			),
1054
			'trash'   => array(
1055
				'label' => __( 'Move Form to Trash', 'formidable' ),
1056
				'short' => __( 'Trash', 'formidable' ),
1057
				'url'   => wp_nonce_url( $base_url . '&frm_action=trash', 'trash_form_' . absint( $id ) ),
1058
				'icon'  => 'frm_icon_font frm_delete_icon',
1059
				'data'  => array( 'frmverify' => __( 'Do you want to move this form to the trash?', 'formidable' ) ),
1060
			),
1061
			'delete'  => array(
1062
				'label'   => __( 'Delete Permanently', 'formidable' ),
1063
				'short'   => __( 'Delete', 'formidable' ),
1064
				'url'     => wp_nonce_url( $base_url . '&frm_action=destroy', 'destroy_form_' . absint( $id ) ),
1065
				'confirm' => __( 'Are you sure you want to delete this form and all its entries?', 'formidable' ),
1066
				'icon'    => 'frm_icon_font frm_delete_icon',
1067
				'data'    => array( 'frmverify' => __( 'This will permanently delete the form and all its entries. This is irreversible. Are you sure you want to continue?', 'formidable' ) ),
1068
			),
1069
		);
1070
	}
1071
1072
	/**
1073
	 * @since 3.0
1074
	 */
1075
	public static function css_classes() {
1076
		$classes = array(
1077
			'frm_total'      => array(
1078
				'label' => __( 'Total', 'formidable' ),
1079
				'title' => __( 'Add this to a read-only field to display the text in bold without a border or background.', 'formidable' ),
1080
			),
1081
			'frm_scroll_box' => array(
1082
				'label' => __( 'Scroll Box', 'formidable' ),
1083
				'title' => __( 'If you have many checkbox or radio button options, you may add this class to allow your user to easily scroll through the options. Or add a scrolling area around content in an HTML field.', 'formidable' ),
1084
			),
1085
			'frm_first'      => array(
1086
				'label' => __( 'First', 'formidable' ),
1087
				'title' => __( 'Add this to the first field in each row along with a width. ie frm_first frm4', 'formidable' ),
1088
			),
1089
			'frm_alignright' => __( 'Right', 'formidable' ),
1090
			'frm_grid_first' => __( 'First Grid Row', 'formidable' ),
1091
			'frm_grid'       => __( 'Even Grid Row', 'formidable' ),
1092
			'frm_grid_odd'   => __( 'Odd Grid Row', 'formidable' ),
1093
			'frm_capitalize' => array(
1094
				'label' => __( 'Capitalize', 'formidable' ),
1095
				'title' => __( 'Automatically capitalize the first letter in each word.', 'formidable' ),
1096
			),
1097
		);
1098
1099
		return apply_filters( 'frm_layout_classes', $classes );
1100
	}
1101
1102
	public static function grid_classes() {
1103
		$base = array(
1104
			'frm_half' => '1/2',
1105
1106
			'frm_third'      => '1/3',
1107
			'frm_two_thirds' => '2/3',
1108
1109
			'frm_fourth'        => '1/4',
1110
			'frm_three_fourths' => '3/4',
1111
		);
1112
1113
		$frm_settings = FrmAppHelper::get_settings();
1114
		if ( $frm_settings->old_css ) {
1115
			$classes = array(
1116
				'frm_sixth' => '1/6',
1117
				'frm10'     => '5/6',
1118
1119
				'frm_full' => '100%',
1120
			);
1121
		} else {
1122
			$classes = array(
1123
				'frm_sixth' => '1/6',
1124
				'frm10'     => '5/6',
1125
				'frm12' => '100%',
1126
			);
1127
		}
1128
1129
		return array_merge( $base, $classes );
1130
	}
1131
1132
	/**
1133
	 * @since 3.0
1134
	 */
1135
	public static function style_class_label( $style, $class ) {
1136
		$label = '';
1137
		if ( empty( $style ) ) {
1138
			$label = $class;
1139
		} elseif ( ! is_array( $style ) ) {
1140
			$label = $style;
1141
		} elseif ( isset( $style['label'] ) ) {
1142
			$label = $style['label'];
1143
		}
1144
1145
		return $label;
1146
	}
1147
1148
	public static function status_nice_name( $status ) {
1149
		$nice_names = array(
1150
			'draft'   => __( 'Draft', 'formidable' ),
1151
			'trash'   => __( 'Trash', 'formidable' ),
1152
			'publish' => __( 'Published', 'formidable' ),
1153
		);
1154
1155
		if ( ! in_array( $status, array_keys( $nice_names ) ) ) {
1156
			$status = 'publish';
1157
		}
1158
1159
		$name = $nice_names[ $status ];
1160
1161
		return $name;
1162
	}
1163
1164
	/**
1165
	 * If a template or add-on cannot be installed, show a message
1166
	 * about which plan is required.
1167
	 *
1168
	 * @since 4.0
1169
	 */
1170
	public static function show_plan_required( $requires, $link ) {
1171
		if ( empty( $requires ) ) {
1172
			return;
1173
		}
1174
1175
		?>
1176
		<p>
1177
			<?php esc_html_e( 'License plan required:', 'formidable' ); ?>
1178
			<a href="<?php echo esc_url( $link ); ?>" target="_blank" rel="noopener">
1179
				<?php echo esc_html( $requires ); ?>
1180
			</a>
1181
		</p>
1182
		<?php
1183
	}
1184
1185
	/**
1186
	 * @since 4.0
1187
	 */
1188
	public static function get_plan_required( &$item ) {
1189
		if ( ! isset( $item['categories'] ) || ( isset( $item['url'] ) && ! empty( $item['url'] ) ) ) {
1190
			return false;
1191
		}
1192
1193
		$plans = array( 'free', 'Personal', 'Business', 'Elite' );
1194
1195
		foreach ( $item['categories'] as $k => $category ) {
1196
			if ( in_array( $category, $plans ) ) {
1197
				unset( $item['categories'][ $k ] );
1198
				return $category;
1199
			}
1200
		}
1201
1202
		return false;
1203
	}
1204
}
1205