Completed
Push — master ( 27ca5f...efee04 )
by Stephanie
03:00
created

FrmFormsHelper::setup_edit_vars()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 16
nop 3
dl 0
loc 14
rs 8.8571
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 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 ); ?>" id="<?php echo esc_attr( $args['field_id'] ) ?>" <?php echo implode( ' ', $add_html ); ?>>
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'implode'
Loading history...
50
		<?php if ( $args['blank'] ) { ?>
51
			<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...
52
		<?php } ?>
53
		<?php foreach ( $forms as $form ) { ?>
54
			<option value="<?php echo esc_attr( $form->id ); ?>" <?php selected( $field_value, $form->id ); ?>>
55
				<?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...
56
			</option>
57
		<?php } ?>
58
        </select>
59
        <?php
60
    }
61
62
	/**
63
	 * @param string $class
64
	 * @param string $param
65
	 * @param array $add_html
66
	 *
67
	 * @since 2.0.6
68
	 */
69
	public static function add_html_attr( $class, $param, &$add_html ) {
70
		if ( ! empty( $class ) ) {
71
			$add_html[ $param ] = sanitize_title( $param ) . '="' . esc_attr( trim( sanitize_text_field( $class ) ) ) . '"';
72
		}
73
	}
74
75
    public static function form_switcher() {
76
		$where = apply_filters( 'frm_forms_dropdown', array(), '' );
77
		$forms = FrmForm::get_published_forms( $where );
78
79
		$args = array(
80
			'id'   => 0,
81
			'form' => 0,
82
		);
83
		if ( isset( $_GET['id'] ) && ! isset( $_GET['form'] ) ) {
84
			unset( $args['form'] );
85
		} else if ( isset( $_GET['form']) && ! isset( $_GET['id'] ) ) {
86
			unset( $args['id'] );
87
        }
88
89
		$frm_action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
90
		if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) && in_array( $frm_action, array( 'edit', 'show', 'destroy_all' ) ) ) {
91
            $args['frm_action'] = 'list';
92
            $args['form'] = 0;
93
		} else if ( FrmAppHelper::is_admin_page('formidable' ) && in_array( $frm_action, array( 'new', 'duplicate' ) ) ) {
94
            $args['frm_action'] = 'edit';
95
		} else if ( isset( $_GET['post'] ) ) {
96
            $args['form'] = 0;
97
            $base = admin_url('edit.php?post_type=frm_display');
98
        }
99
100
        ?>
101
		<li id="frm_bs_dropdown" class="dropdown <?php echo esc_attr( is_rtl() ? 'pull-right' : 'pull-left' ) ?>">
102
			<a href="#" id="frm-navbarDrop" class="frm-dropdown-toggle" data-toggle="dropdown"><?php esc_html_e( 'Switch Form', 'formidable' ) ?> <b class="caret"></b></a>
103
		    <ul class="frm-dropdown-menu frm-on-top" role="menu" aria-labelledby="frm-navbarDrop">
104
			<?php
105
			foreach ( $forms as $form ) {
106
				if ( isset( $args['id'] ) ) {
107
			        $args['id'] = $form->id;
108
				}
109
			    if ( isset( $args['form'] ) ) {
110
			        $args['form'] = $form->id;
111
				}
112
                ?>
113
				<li><a href="<?php echo esc_url( isset( $base ) ? add_query_arg( $args, $base ) : add_query_arg( $args ) ); ?>" tabindex="-1"><?php echo esc_html( empty( $form->name ) ? __( '(no title)' ) : FrmAppHelper::truncate( $form->name, 60 ) ); ?></a></li>
114
			<?php
115
				unset( $form );
116
			}
117
			?>
118
			</ul>
119
		</li>
120
        <?php
121
    }
122
123
	public static function get_sortable_classes( $col, $sort_col, $sort_dir ) {
124
		echo ( $sort_col == $col ) ? 'sorted' : 'sortable';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
125
		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...
126
	}
127
128
	/**
129
	 * @since 3.0
130
	 */
131
	public static function get_field_link_name( $field_type ) {
132
		if ( is_array( $field_type ) ) {
133
			$field_label = $field_type['name'];
134
		} else {
135
			$field_label = $field_type;
136
		}
137
		return $field_label;
138
	}
139
140
	/**
141
	 * @since 3.0
142
	 */
143
	public static function get_field_link_icon( $field_type ) {
144
		if ( is_array( $field_type ) && isset( $field_type['icon'] ) ) {
145
			$icon = $field_type['icon'];
146
		} else {
147
			$icon = 'frm_icon_font frm_pencil_icon';
148
		}
149
		return $icon;
150
	}
151
152
	/**
153
	 * Get the invalid form error message
154
	 *
155
	 * @since 2.02.07
156
	 * @param array $args
157
	 * @return string
158
	 */
159
	public static function get_invalid_error_message( $args ) {
160
		$frm_settings = FrmAppHelper::get_settings();
161
162
		$invalid_msg = apply_filters( 'frm_invalid_error_message', $frm_settings->invalid_msg, $args );
163
164
		return $invalid_msg;
165
	}
166
167
	public static function get_success_message( $atts ) {
168
		$message = apply_filters( 'frm_content', $atts['message'], $atts['form'], $atts['entry_id'] );
169
		$message = FrmAppHelper::use_wpautop( do_shortcode( $message ) );
170
		$message = '<div class="' . esc_attr( $atts['class'] ) . '">' . $message . '</div>';
171
		return $message;
172
	}
173
174
    /**
175
     * Used when a form is created
176
     */
177
    public static function setup_new_vars( $values = array() ) {
178
        global $wpdb;
179
180
        if ( ! empty( $values ) ) {
181
            $post_values = $values;
182
        } else {
183
            $values = array();
184
            $post_values = isset($_POST) ? $_POST : array();
185
        }
186
187
		$defaults = array(
188
			'name' => '',
189
			'description' => '',
190
		);
191 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...
192
			if ( ! isset( $values[ $var ] ) ) {
193
				$values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
194
            }
195
        }
196
197
        $values['description'] = FrmAppHelper::use_wpautop($values['description']);
198
199
		$defaults = array(
200
			'form_id'        => '',
201
			'logged_in'      => '',
202
			'editable'       => '',
203
			'default_template' => 0,
204
			'is_template'    => 0,
205
			'status'         => 'draft',
206
			'parent_form_id' => 0,
207
		);
208 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...
209
			if ( ! isset( $values[ $var ] ) ) {
210
				$values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
211
			}
212
		}
213
		unset( $defaults );
214
215
        if ( ! isset( $values['form_key'] ) ) {
216
			$values['form_key'] = ( $post_values && isset( $post_values['form_key'] ) ) ? $post_values['form_key'] : FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_forms', 'form_key' );
217
        }
218
219
		$values = self::fill_default_opts( $values, false, $post_values );
220
		$values['custom_style'] = FrmAppHelper::custom_style_value( $post_values );
221
222
        return apply_filters('frm_setup_new_form_vars', $values);
223
    }
224
225
    /**
226
     * Used when editing a form
227
     */
228
    public static function setup_edit_vars( $values, $record, $post_values = array() ) {
229
		if ( empty( $post_values ) ) {
230
			$post_values = stripslashes_deep( $_POST );
231
		}
232
233
        $values['form_key'] = isset($post_values['form_key']) ? $post_values['form_key'] : $record->form_key;
234
        $values['default_template'] = isset($post_values['default_template']) ? $post_values['default_template'] : $record->default_template;
235
        $values['is_template'] = isset($post_values['is_template']) ? $post_values['is_template'] : $record->is_template;
236
        $values['status'] = $record->status;
237
238
        $values = self::fill_default_opts($values, $record, $post_values);
239
240
        return apply_filters('frm_setup_edit_form_vars', $values);
241
    }
242
243
	public static function fill_default_opts( $values, $record, $post_values ) {
244
245
        $defaults = self::get_default_opts();
246
		foreach ( $defaults as $var => $default ) {
247
            if ( is_array($default) ) {
248
                if ( ! isset( $values[ $var ] ) ) {
249
					$values[ $var ] = ( $record && isset( $record->options[ $var ] ) ) ? $record->options[ $var ] : array();
250
                }
251
252
                foreach ( $default as $k => $v ) {
253
					$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 );
254
255
                    if ( is_array( $v ) ) {
256
                        foreach ( $v as $k1 => $v1 ) {
257
							$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 );
258
                            unset( $k1, $v1 );
259
                        }
260
                    }
261
262
                    unset($k, $v);
263
                }
264
            } else {
265
				$values[ $var ] = ( $post_values && isset( $post_values['options'][ $var ] ) ) ? $post_values['options'][ $var ] : ( ( $record && isset( $record->options[ $var ] ) ) ? $record->options[ $var ] : $default );
266
            }
267
268
            unset($var, $default);
269
        }
270
271
        return $values;
272
    }
273
274
	public static function get_default_opts() {
275
		$frm_settings = FrmAppHelper::get_settings();
276
277
		return array(
278
			'submit_value'   => $frm_settings->submit_value,
279
			'success_action' => 'message',
280
			'success_msg'    => $frm_settings->success_msg,
281
			'show_form'      => 0,
282
			'akismet'        => '',
283
			'no_save'        => 0,
284
			'ajax_load'      => 0,
285
			'js_validate'    => 0,
286
			'form_class'     => '',
287
			'custom_style'   => 1,
288
			'before_html'    => self::get_default_html( 'before' ),
289
			'after_html'     => '',
290
			'submit_html'    => self::get_default_html( 'submit' ),
291
		);
292
	}
293
294
	/**
295
	 * @param array $options
296
	 * @param array $values
297
	 * @since 2.0.6
298
	 */
299
	public static function fill_form_options( &$options, $values ) {
300
		$defaults = self::get_default_opts();
301
		foreach ( $defaults as $var => $default ) {
302
			$options[ $var ] = isset( $values['options'][ $var ] ) ? $values['options'][ $var ] : $default;
303
			unset( $var, $default );
304
		}
305
	}
306
307
    /**
308
     * @param string $loc
309
     */
310
	public static function get_default_html( $loc ) {
311
		if ( $loc == 'submit' ) {
312
            $draft_link = self::get_draft_link();
313
            $default_html = <<<SUBMIT_HTML
314
<div class="frm_submit">
315
[if back_button]<button type="submit" name="frm_prev_page" formnovalidate="formnovalidate" class="frm_prev_page" [back_hook]>[back_label]</button>[/if back_button]
316
<button class="frm_button_submit" type="submit"  [button_action]>[button_label]</button>
317
$draft_link
318
</div>
319
SUBMIT_HTML;
320
		} else if ( $loc == 'before' ) {
321
            $default_html = <<<BEFORE_HTML
322
<legend class="frm_screen_reader">[form_name]</legend>
323
[if form_name]<h3 class="frm_form_title">[form_name]</h3>[/if form_name]
324
[if form_description]<div class="frm_description">[form_description]</div>[/if form_description]
325
BEFORE_HTML;
326
		} else {
327
            $default_html = '';
328
        }
329
330
        return $default_html;
331
    }
332
333
    public static function get_draft_link() {
334
        $link = '[if save_draft]<a href="#" class="frm_save_draft" [draft_hook]>[draft_label]</a>[/if save_draft]';
335
        return $link;
336
    }
337
338
	public static function get_custom_submit( $html, $form, $submit, $form_action, $values ) {
339
		$button = self::replace_shortcodes( $html, $form, $submit, $form_action, $values );
340
		if ( ! strpos( $button, '[button_action]' ) ) {
341
			echo $button;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$button'
Loading history...
342
			return;
343
		}
344
345
		$button_parts = explode( '[button_action]', $button );
346
347
		$classes = apply_filters( 'frm_submit_button_class', array(), $form );
348
		if ( ! empty( $classes ) ) {
349
			$classes = implode( ' ', $classes );
350
			$button_class = ' class="frm_button_submit';
351
			if ( strpos( $button_parts[0], $button_class ) !== false ) {
352
				$button_parts[0] = str_replace( $button_class, $button_class . ' ' . esc_attr( $classes ), $button_parts[0] );
353
			} else {
354
				$button_parts[0] .= ' class="' . esc_attr( $classes ) . '"';
355
			}
356
		}
357
358
		echo $button_parts[0];
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$button_parts'
Loading history...
359
		do_action( 'frm_submit_button_action', $form, $form_action );
360
		echo $button_parts[1];
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$button_parts'
Loading history...
361
	}
362
363
    /**
364
     * Automatically add end section fields if they don't exist (2.0 migration)
365
     * @since 2.0
366
     *
367
     * @param boolean $reset_fields
368
     */
369
    public static function auto_add_end_section_fields( $form, $fields, &$reset_fields ) {
370
		if ( empty( $fields ) ) {
371
			return;
372
		}
373
374
		$end_section_values = apply_filters( 'frm_before_field_created', FrmFieldsHelper::setup_new_vars( 'end_divider', $form->id ) );
375
		$open = false;
376
		$prev_order = false;
377
		$add_order = 0;
378
		$last_field = false;
379
        foreach ( $fields as $field ) {
380
			if ( $prev_order === $field->field_order ) {
381
				$add_order++;
382
			}
383
384
			if ( $add_order ) {
385
				$reset_fields = true;
386
				$field->field_order = $field->field_order + $add_order;
387
				FrmField::update( $field->id, array( 'field_order' => $field->field_order ) );
388
			}
389
390
            switch ( $field->type ) {
391
                case 'divider':
392
                    // create an end section if open
393
					self::maybe_create_end_section( $open, $reset_fields, $add_order, $end_section_values, $field, 'move' );
394
395
                    // mark it open for the next end section
396
                    $open = true;
397
					break;
398
                case 'break':
399
					self::maybe_create_end_section( $open, $reset_fields, $add_order, $end_section_values, $field, 'move' );
400
					break;
401
                case 'end_divider':
402
                    if ( ! $open ) {
403
                        // the section isn't open, so this is an extra field that needs to be removed
404
                        FrmField::destroy( $field->id );
405
                        $reset_fields = true;
406
                    }
407
408
                    // There is already an end section here, so there is no need to create one
409
                    $open = false;
410
            }
411
			$prev_order = $field->field_order;
412
413
			$last_field = $field;
414
			unset( $field );
415
        }
416
417
		self::maybe_create_end_section( $open, $reset_fields, $add_order, $end_section_values, $last_field );
418
    }
419
420
	/**
421
	 * Create end section field if it doesn't exist. This is for migration from < 2.0
422
	 * Fix any ordering that may be messed up
423
	 */
424
	public static function maybe_create_end_section( &$open, &$reset_fields, &$add_order, $end_section_values, $field, $move = 'no' ) {
425
        if ( ! $open ) {
426
            return;
427
        }
428
429
		$end_section_values['field_order'] = $field->field_order + 1;
430
431
        FrmField::create( $end_section_values );
432
433
		if ( $move == 'move' ) {
434
			// bump the order of current field unless we're at the end of the form
435
			FrmField::update( $field->id, array( 'field_order' => $field->field_order + 2 ) );
436
		}
437
438
		$add_order += 2;
439
        $open = false;
440
        $reset_fields = true;
441
    }
442
443
	public static function replace_shortcodes( $html, $form, $title = false, $description = false, $values = array() ) {
444
		$codes = array(
445
			'form_name' => $title,
446
			'form_description' => $description,
447
			'entry_key' => true,
448
		);
449
		foreach ( $codes as $code => $show ) {
450
            if ( $code == 'form_name' ) {
451
                $replace_with = $form->name;
452
            } else if ( $code == 'form_description' ) {
453
                $replace_with = FrmAppHelper::use_wpautop($form->description);
454
            } else if ( $code == 'entry_key' && isset($_GET) && isset($_GET['entry']) ) {
455
                $replace_with = FrmAppHelper::simple_get( 'entry' );
456
            } else {
457
                $replace_with = '';
458
            }
459
460
			FrmShortcodeHelper::remove_inline_conditions( ( FrmAppHelper::is_true( $show ) && $replace_with != '' ), $code, $replace_with, $html );
461
        }
462
463
        //replace [form_key]
464
        $html = str_replace('[form_key]', $form->form_key, $html);
465
466
        //replace [frmurl]
467
        $html = str_replace('[frmurl]', FrmFieldsHelper::dynamic_default_values( 'frmurl' ), $html);
468
469
		if ( strpos( $html, '[button_label]' ) ) {
470
			add_filter( 'frm_submit_button', 'FrmFormsHelper::submit_button_label', 1 );
471
			$submit_label = apply_filters( 'frm_submit_button', $title, $form );
472
			$submit_label = esc_attr( do_shortcode( $submit_label ) );
473
			$html = str_replace( '[button_label]', $submit_label, $html );
474
        }
475
476
        $html = apply_filters('frm_form_replace_shortcodes', $html, $form, $values);
477
478
		if ( strpos( $html, '[if back_button]' ) ) {
479
			$html = preg_replace( '/(\[if\s+back_button\])(.*?)(\[\/if\s+back_button\])/mis', '', $html );
480
		}
481
482
		if ( strpos( $html, '[if save_draft]' ) ) {
483
			$html = preg_replace( '/(\[if\s+save_draft\])(.*?)(\[\/if\s+save_draft\])/mis', '', $html );
484
		}
485
486
		if ( apply_filters( 'frm_do_html_shortcodes', true ) ) {
487
			$html = do_shortcode( $html );
488
		}
489
490
        return $html;
491
    }
492
493
	public static function submit_button_label( $submit ) {
494
        if ( ! $submit || empty($submit) ) {
495
            $frm_settings = FrmAppHelper::get_settings();
496
            $submit = $frm_settings->submit_value;
497
        }
498
499
        return $submit;
500
    }
501
502
	/**
503
	 * If the Formidable styling isn't being loaded,
504
	 * use inline styling to hide the element
505
	 * @since 2.03.05
506
	 */
507
	public static function maybe_hide_inline() {
508
		$frm_settings = FrmAppHelper::get_settings();
509
		if ( $frm_settings->load_style == 'none' ) {
510
			echo ' style="display:none;"';
511
		} elseif ( $frm_settings->load_style == 'dynamic' ) {
512
			FrmStylesController::enqueue_style();
513
		}
514
	}
515
516
	public static function get_form_style_class( $form = false ) {
517
        $style = self::get_form_style($form);
518
        $class = ' with_frm_style';
519
520
        if ( empty($style) ) {
521
            if ( FrmAppHelper::is_admin_page('formidable-entries') ) {
522
                return $class;
523
            } else {
524
                return;
525
            }
526
        }
527
528
        //If submit button needs to be inline or centered
529
        if ( is_object($form) ) {
530
			$form = $form->options;
531
		}
532
533
		$submit_align = isset( $form['submit_align'] ) ? $form['submit_align'] : '';
534
535
		if ( 'inline' === $submit_align ) {
536
			$class .= ' frm_inline_form';
537
			$class .= self::maybe_align_fields_top( $form );
538
		} elseif ( 'center' === $submit_align ) {
539
			$class .= ' frm_center_submit';
540
		}
541
542
        $class = apply_filters('frm_add_form_style_class', $class, $style);
543
544
        return $class;
545
    }
546
547
	/**
548
	 * Returns appropriate class if form has top labels
549
	 *
550
	 * @param $form
551
	 *
552
	 * @return string
553
	 */
554
	private static function maybe_align_fields_top( $form ) {
555
		return self::form_has_top_labels( $form ) ? ' frm_inline_top' : '';
556
	}
557
558
	/**
559
	 * Determine if a form has fields with top labels so submit button can be aligned properly
560
	 *
561
	 * @param $form
562
	 *
563
	 * @return bool
564
	 */
565
	private static function form_has_top_labels( $form ) {
566
		$fields = $form['fields'];
567
		if ( count( $fields ) <= 0 ) {
568
			return false;
569
		}
570
571
		$fields = array_reverse( $fields ); // start from the fields closest to the submit button
572
		foreach ( $fields as $field ) {
573
			$type = isset( $field['original_type'] ) ? $field['original_type'] : $field['type'];
574
			$has_input = FrmFieldFactory::field_has_property( $type, 'has_input' );
575
			if ( $has_input ) {
576
				return self::field_has_top_label( $field, $form );
577
			}
578
		}
579
580
		return false;
581
	}
582
583
	/**
584
	 * Check if a field's label position is set to "top"
585
	 *
586
	 * @param $field
587
	 * @param $form
588
	 *
589
	 * @return bool
590
	 */
591
	private static function field_has_top_label( $field, $form ) {
592
		$label_position = FrmFieldsHelper::label_position( $field['label'], $field, $form );
593
		return in_array( $label_position, array( 'top', 'inside', 'hidden' ) );
594
	}
595
596
    /**
597
     * @param string|boolean $form
598
     *
599
     * @return string
600
     */
601
    public static function get_form_style( $form ) {
602
		$style = 1;
603
		if ( empty( $form ) || 'default' == 'form' ) {
604
			return $style;
605
		} else if ( is_object( $form ) && $form->parent_form_id ) {
606
			// get the parent form if this is a child
607
			$form = $form->parent_form_id;
608
		} else if ( is_array( $form ) && isset( $form['parent_form_id'] ) && $form['parent_form_id'] ) {
609
			$form = $form['parent_form_id'];
610
		} else if ( is_array( $form ) && isset( $form['custom_style'] ) ) {
611
			$style = $form['custom_style'];
612
		}
613
614
		if ( $form && is_string( $form ) ) {
615
			$form = FrmForm::getOne( $form );
616
		}
617
618
		$style = ( $form && is_object( $form ) && isset( $form->options['custom_style'] ) ) ? $form->options['custom_style'] : $style;
619
620
		return $style;
621
    }
622
623
	/**
624
	 * Display the validation error messages when an entry is submitted
625
	 *
626
	 * @param array $args - includes img, errors
627
	 * @since 2.0.6
628
	 */
629
	public static function show_errors( $args ) {
630
		$invalid_msg = self::get_invalid_error_message( $args );
631
632
		if ( empty( $invalid_msg ) ) {
633
			$show_img = false;
634
		} else {
635
			echo wp_kses_post( $invalid_msg );
636
			$show_img = true;
637
		}
638
639
		self::show_error( array(
640
			'img' => $args['img'],
641
			'errors' => $args['errors'],
642
			'show_img' => $show_img,
643
		) );
644
	}
645
646
	/**
647
	 * Display the error message in the front-end along with the image if set
648
	 * The image was removed from the styling settings, but it may still be set with a hook
649
	 * If the message in the global settings is empty, show every validation message in the error box
650
	 *
651
	 * @param array $args - includes img, errors, and show_img
652
	 * @since 2.0.6
653
	 */
654
	public static function show_error( $args ) {
655
		// remove any blank messages
656
		$args['errors'] = array_filter( (array) $args['errors'] );
657
658
		$line_break_first = $args['show_img'];
659
		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...
660
			if ( $line_break_first && ! is_numeric( $error_key ) && ( $error_key == 'cptch_number' || strpos( $error_key, 'field' ) === 0 ) ) {
661
				continue;
662
			}
663
664
			if ( $line_break_first ) {
665
				echo '<br/>';
666
			}
667
668
			if ( $args['show_img'] && ! empty( $args['img'] ) ) {
669
				echo '<img src="' . esc_attr( $args['img'] ) . '" alt="" />';
670
			} else {
671
				$args['show_img'] = true;
672
			}
673
674
			echo wp_kses_post( $error );
675
676
			if ( ! $line_break_first ) {
677
				echo '<br/>';
678
			}
679
		}
680
	}
681
682
	public static function maybe_get_scroll_js( $id ) {
683
		$offset = apply_filters( 'frm_scroll_offset', 4, array( 'form_id' => $id ) );
684
		if ( $offset != -1 ) {
685
			self::get_scroll_js( $id );
686
		}
687
	}
688
689
	public static function get_scroll_js( $form_id ) {
690
        echo '<script type="text/javascript">document.addEventListener(\'DOMContentLoaded\',function(){frmFrontForm.scrollMsg(' . (int) $form_id . ');})</script>';
691
    }
692
693
	/**
694
	 * @since 3.0
695
	 */
696
	public static function actions_dropdown( $atts ) {
697
		if ( FrmAppHelper::is_admin_page('formidable' ) ) {
698
			$status = $atts['status'];
699
			$form_id = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
700
			$trash_link = self::delete_trash_info( $form_id, $status );
701
			$links = self::get_action_links( $form_id, $status );
702
			include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/actions-dropdown.php' );
703
		}
704
	}
705
706
	/**
707
	 * @since 3.0
708
	 */
709
	public static function get_action_links( $form_id, $form ) {
710
		if ( ! is_object( $form ) ) {
711
			$form = FrmForm::getOne( $form_id );
712
		}
713
714
		$actions = array();
715
		$trash_links = self::delete_trash_links( $form_id );
716
		if ( 'trash' == $form->status ) {
717
			$actions['restore'] = $trash_links['restore'];
718
719
			if ( current_user_can('frm_delete_forms') ) {
720
				$actions['trash'] = $trash_links['delete'];
721
			}
722
		} else {
723
			$duplicate_link = '?page=formidable&frm_action=duplicate&id=' . $form_id;
724
			if ( $form->is_template ) {
725
				$actions['frm_duplicate'] = array(
726
					'url'   => wp_nonce_url( $duplicate_link ),
727
					'label' => __( 'Create Form from Template', 'formidable' ),
728
					'icon'  => 'frm_icon_font frm_duplicate_icon',
729
				);
730
			} elseif ( FrmAppHelper::pro_is_installed() ) {
731
				$actions['duplicate'] = array(
732
					'url'   => wp_nonce_url( $duplicate_link ),
733
					'label' => __( 'Duplicate Form', 'formidable' ),
734
					'icon'  => 'frm_icon_font frm_duplicate_icon',
735
				);
736
			}
737
738
			$actions['trash'] = self::delete_trash_info( $form_id, $form->status );
739
		}
740
741
		return $actions;
742
	}
743
744
	public static function edit_form_link( $form_id ) {
745
        if ( is_object($form_id) ) {
746
            $form = $form_id;
747
            $name = $form->name;
748
            $form_id = $form->id;
749
        } else {
750
            $name = FrmForm::getName($form_id);
751
        }
752
753
        if ( $form_id ) {
754
			$val = '<a href="' . esc_url( admin_url( 'admin.php?page=formidable&frm_action=edit&id=' . $form_id ) ) . '">' . ( '' == $name ? __( '(no title)' ) : FrmAppHelper::truncate( $name, 40 ) ) . '</a>';
755
	    } else {
756
	        $val = '';
757
	    }
758
759
	    return $val;
760
	}
761
762
	public static function delete_trash_link( $id, $status, $length = 'label' ) {
763
		$link_details = self::delete_trash_info( $id, $status );
764
765
		return self::format_link_html( $link_details, $length );
766
	}
767
768
	/**
769
	 * @since 3.0
770
	 */
771
	public static function format_link_html( $link_details, $length = 'label' ) {
772
		$link = '';
773
		if ( ! empty( $link_details ) ) {
774
			$link = '<a href="' . esc_url( $link_details['url'] ) . '"';
775
			if ( isset( $link_details['data'] ) ) {
776
				foreach ( $link_details['data'] as $data => $value ) {
777
					$link .= ' data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '"';
778
				}
779
			} elseif ( isset( $link_details['confirm'] ) ) {
780
				$link .= ' onclick="return confirm(\'' . esc_attr( $link_details['confirm'] ) . '\')"';
781
			}
782
			$label = ( isset( $link_details[ $length ] ) ? $link_details[ $length ] : $link_details['label'] );
783
			$link .= '>' . $label . '</a>';
784
		}
785
		return $link;
786
	}
787
788
	/**
789
	 * @since 3.0
790
	 */
791
	public static function delete_trash_info( $id, $status ) {
792
		$labels = self::delete_trash_links( $id );
793
794
		if ( 'trash' == $status ) {
795
			$info = $labels['restore'];
796
		} elseif ( current_user_can('frm_delete_forms') ) {
797
			if ( EMPTY_TRASH_DAYS ) {
798
				$info = $labels['trash'];
799
			} else {
800
				$info = $labels['delete'];
801
			}
802
		} else {
803
			$info = array();
804
		}
805
806
		return $info;
807
	}
808
809
	/**
810
	 * @since 3.0
811
	 */
812
	private static function delete_trash_links( $id ) {
813
		$current_page = FrmAppHelper::get_simple_request( array( 'param' => 'form_type' ) );
814
		$base_url = '?page=formidable&form_type=' . $current_page . '&id=' . $id;
815
816
		return array(
817
			'restore' => array(
818
				'label' => __( 'Restore from Trash', 'formidable' ),
819
				'short' => __( 'Restore', 'formidable' ),
820
				'url'   => wp_nonce_url( $base_url . '&frm_action=untrash', 'untrash_form_' . absint( $id ) ),
821
			),
822
			'trash' => array(
823
				'label' => __( 'Move Form to Trash', 'formidable' ),
824
				'short' => __( 'Trash', 'formidable' ),
825
				'url'   => wp_nonce_url( $base_url . '&frm_action=trash', 'trash_form_' . absint( $id ) ),
826
				'icon'  => 'frm_icon_font frm_delete_icon',
827
				'data'  => array( 'frmverify' => __( 'Are you sure?', 'formidable' ) ),
828
			),
829
			'delete' => array(
830
				'label' => __( 'Delete Permanently', 'formidable' ),
831
				'short' => __( 'Delete', 'formidable' ),
832
				'url'   => wp_nonce_url( $base_url . '&frm_action=destroy', 'destroy_form_' . absint( $id ) ),
833
				'confirm' => __( 'Are you sure you want to delete this form and all its entries?', 'formidable' ),
834
				'icon'  => 'frm_icon_font frm_delete_icon',
835
				'data'  => array( 'frmverify' => __( 'Delete form & entries?', 'formidable' ) ),
836
			),
837
		);
838
	}
839
840
	/**
841
	 * @since 3.0
842
	 */
843
	public static function css_classes() {
844
		$classes = array(
845
			'frm_first'      => array(
846
				'label'      => __( 'First', 'formidable' ),
847
				'title'      => __( 'Add this to the first field in each row along with a width. ie frm_first frm4', 'formidable' ),
848
			),
849
			'frm_alignright' => __( 'Right', 'formidable' ),
850
			'frm_total'      => array(
851
				'label'      => __( 'Total', 'formidable' ),
852
				'title'      => __( 'Add this to a read-only field to display the text in bold without a border or background.', 'formidable' ),
853
			),
854
			'frm_grid_first' => __( 'First Grid Row', 'formidable' ),
855
			'frm_grid'       => __( 'Even Grid Row', 'formidable' ),
856
			'frm_grid_odd'   => __( 'Odd Grid Row', 'formidable' ),
857
			'frm_two_col'    => array(
858
				'label'      => __( '2 Col Options', 'formidable' ),
859
				'title'      => __( 'Put your radio button or checkbox options into two columns.', 'formidable' ),
860
			),
861
			'frm_three_col'  => array(
862
				'label'      => __( '3 Col Options', 'formidable' ),
863
				'title'      => __( 'Put your radio button or checkbox options into three columns.', 'formidable' ),
864
			),
865
			'frm_four_col'   => array(
866
				'label'      => __( '4 Col Options', 'formidable' ),
867
				'title'      => __( 'Put your radio button or checkbox options into four columns.', 'formidable' ),
868
			),
869
			'frm_scroll_box' => array(
870
				'label'      => __( 'Scroll Box', 'formidable' ),
871
				'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.', 'formidable' ),
872
			),
873
			'frm_capitalize' => array(
874
				'label'      => __( 'Capitalize', 'formidable' ),
875
				'title'      => __( 'Automatically capitalize the first letter in each word.', 'formidable' ),
876
			),
877
		);
878
879
		return apply_filters( 'frm_layout_classes', $classes );
880
	}
881
882
	public static function grid_classes() {
883
		$base = array(
884
			'frm_half'          => '1/2',
885
886
			'frm_third'         => '1/3',
887
			'frm_two_thirds'    => '2/3',
888
889
			'frm_fourth'        => '1/4',
890
			'frm_three_fourths' => '3/4',
891
		);
892
893
		$frm_settings = FrmAppHelper::get_settings();
894
		if ( $frm_settings->old_css ) {
895
			$classes = array(
896
				'frm_fifth'        => '1/5',
897
				'frm_four_fifths'  => '4/5',
898
899
				'frm_two_fifths'   => '2/5',
900
				'frm_three_fifths' => '3/5',
901
902
				'frm_sixth'         => '1/6',
903
904
				'frm_full'          => '100%',
905
			);
906
		} else {
907
			$classes = array(
908
				'frm_sixth'         => '1/6',
909
				'frm10'             => '5/6',
910
911
				'frm11'             => '11/12',
912
				'frm1'              => '1/12',
913
914
				'frm5'              => '5/12',
915
				'frm7'              => '7/12',
916
917
				'frm12'             => '100%',
918
			);
919
		}
920
921
		return array_merge( $base, $classes );
922
	}
923
924
	/**
925
	 * @since 3.0
926
	 */
927
	public static function style_class_label( $style, $class ) {
928
		$label = '';
929
		if ( empty( $style ) ) {
930
			$label = $class;
931
		} elseif ( ! is_array( $style ) ) {
932
			$label = $style;
933
		} else if ( isset( $style['label'] ) ) {
934
			$label = $style['label'];
935
		}
936
		return $label;
937
	}
938
939
	public static function status_nice_name( $status ) {
940
        $nice_names = array(
941
            'draft'     => __( 'Draft', 'formidable' ),
942
            'trash'     => __( 'Trash', 'formidable' ),
943
            'publish'   => __( 'Published', 'formidable' ),
944
        );
945
946
        if ( ! in_array($status, array_keys($nice_names)) ) {
947
            $status = 'publish';
948
        }
949
950
		$name = $nice_names[ $status ];
951
952
        return $name;
953
    }
954
}
955