Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,663 @@
<?php
use WPForms\Admin\Education\Helpers;
/**
* Output fields to be used on panels (settings etc).
*
* @since 1.0.0
*
* @param string $option
* @param string $panel
* @param string $field
* @param array $form_data
* @param string $label
* @param array $args
* @param bool $echo
*
* @return string
*/
function wpforms_panel_field( $option, $panel, $field, $form_data, $label, $args = [], $echo = true ) {
// Required params.
if ( empty( $option ) || empty( $panel ) || empty( $field ) ) {
return '';
}
// Setup basic vars.
$panel = esc_attr( $panel );
$field = esc_attr( $field );
$panel_id = sanitize_html_class( $panel );
$parent = ! empty( $args['parent'] ) ? esc_attr( $args['parent'] ) : '';
$subsection = ! empty( $args['subsection'] ) ? esc_attr( $args['subsection'] ) : '';
$index = isset( $args['index'] ) ? esc_attr( $args['index'] ) : '';
$index = is_numeric( $index ) ? absint( $index ) : $index;
$label = ! empty( $label ) ? wp_kses( $label, [ 'span' => [ 'class' => [] ] ] ) : '';
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
$input_class = ! empty( $args['input_class'] ) ? wpforms_sanitize_classes( $args['input_class'] ) : '';
$default = isset( $args['default'] ) ? $args['default'] : '';
$placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : '';
$data_attr = '';
$output = '';
$smarttags_toggle = '';
$input_id = sprintf( 'wpforms-panel-field-%s-%s', sanitize_html_class( $panel_id ), sanitize_html_class( $field ) );
if ( ! empty( $args['input_id'] ) ) {
$input_id = esc_attr( $args['input_id'] );
}
if ( ! empty( $args['smarttags'] ) ) {
$type = ! empty( $args['smarttags']['type'] ) ? esc_attr( $args['smarttags']['type'] ) : 'fields';
$fields = ! empty( $args['smarttags']['fields'] ) ? esc_attr( $args['smarttags']['fields'] ) : '';
$smarttags_toggle = sprintf(
'<a href="#" class="toggle-smart-tag-display toggle-unfoldable-cont" data-type="%s" data-fields="%s">
<i class="fa fa-tags"></i><span>%s</span>
</a>',
esc_attr( $type ),
esc_attr( $fields ),
esc_html__( 'Show Smart Tags', 'wpforms-lite' )
);
}
if ( ! empty( $args['pro_badge'] ) ) {
$label .= Helpers::get_badge( 'Pro', 'sm', 'inline', 'silver' );
}
// Check if we should store values in a parent array.
if ( ! empty( $parent ) ) {
if ( $subsection && ! wpforms_is_empty_string( $index ) ) {
$field_name = sprintf( '%s[%s][%s][%s][%s]', $parent, $panel, $subsection, $index, $field );
$value = isset( $form_data[ $parent ][ $panel ][ $subsection ][ $index ][ $field ] ) ? $form_data[ $parent ][ $panel ][ $subsection ][ $index ][ $field ] : $default;
$input_id = sprintf( 'wpforms-panel-field-%s-%s-%s-%s', sanitize_html_class( $panel_id ), sanitize_html_class( $subsection ), sanitize_html_class( $index ), sanitize_html_class( $field ) );
} elseif ( ! empty( $subsection ) ) {
$field_name = sprintf( '%s[%s][%s][%s]', $parent, $panel, $subsection, $field );
$value = isset( $form_data[ $parent ][ $panel ][ $subsection ][ $field ] ) ? $form_data[ $parent ][ $panel ][ $subsection ][ $field ] : $default;
$input_id = sprintf( 'wpforms-panel-field-%s-%s-%s', sanitize_html_class( $panel_id ), sanitize_html_class( $subsection ), sanitize_html_class( $field ) );
$panel_id = sanitize_html_class( $panel . '-' . $subsection );
} else {
$field_name = sprintf( '%s[%s][%s]', $parent, $panel, $field );
$value = isset( $form_data[ $parent ][ $panel ][ $field ] ) ? $form_data[ $parent ][ $panel ][ $field ] : $default;
}
} else {
$field_name = sprintf( '%s[%s]', $panel, $field );
$value = isset( $form_data[ $panel ][ $field ] ) ? $form_data[ $panel ][ $field ] : $default;
}
if ( isset( $args['field_name'] ) ) {
$field_name = $args['field_name'];
}
if ( isset( $args['value'] ) ) {
$value = $args['value'];
}
// Check for data attributes.
if ( ! empty( $args['data'] ) ) {
foreach ( $args['data'] as $key => $val ) {
if ( is_array( $val ) ) {
$val = wp_json_encode( $val );
}
$data_attr .= ' data-' . $key . '=\'' . $val . '\'';
}
}
// Check for readonly inputs.
if ( ! empty( $args['readonly'] ) ) {
$data_attr .= 'readonly';
}
// Determine what field type to output.
switch ( $option ) {
// Text input.
case 'text':
// Handle min and max attributes for number fields.
if ( ! empty( $args['type'] ) && $args['type'] === 'number' ) {
if ( isset( $args['min'] ) && is_int( $args['min'] ) ) {
$data_attr .= sprintf( ' min="%1$d" oninput="validity.valid||(value=\'%1$d\');" ', esc_attr( $args['min'] ) );
}
if ( isset( $args['max'] ) && is_int( $args['max'] ) ) {
$data_attr .= sprintf( ' max="%1$d" oninput="validity.valid||(value=\'%1$d\');" ', esc_attr( $args['max'] ) );
}
}
$output = sprintf(
'<input type="%s" id="%s" name="%s" value="%s" placeholder="%s" class="%s" %s>',
! empty( $args['type'] ) ? esc_attr( $args['type'] ) : 'text',
$input_id,
$field_name,
esc_attr( $value ),
$placeholder,
$input_class,
$data_attr
);
break;
// Textarea.
case 'textarea':
$output = sprintf(
'<textarea id="%s" name="%s" rows="%d" placeholder="%s" class="%s" %s>%s</textarea>',
$input_id,
$field_name,
! empty( $args['rows'] ) ? (int) $args['rows'] : '3',
$placeholder,
$input_class,
$data_attr,
esc_textarea( $value )
);
break;
// TinyMCE.
case 'tinymce':
$id = str_replace( '-', '_', $input_id );
$args['tinymce']['textarea_name'] = $field_name;
$args['tinymce']['teeny'] = true;
$args['tinymce'] = wp_parse_args(
$args['tinymce'],
[
'media_buttons' => false,
'teeny' => true,
]
);
ob_start();
wp_editor( $value, $id, $args['tinymce'] );
$output = ob_get_clean();
break;
// Checkbox.
case 'checkbox':
$output = sprintf(
'<input type="checkbox" id="%s" name="%s" value="1" class="%s" %s %s>',
$input_id,
$field_name,
$input_class,
checked( '1', $value, false ),
$data_attr
);
$output .= sprintf(
'<label for="%s" class="inline">%s',
$input_id,
$label
);
if ( ! empty( $args['before_tooltip'] ) ) {
$output .= $args['before_tooltip'];
}
if ( ! empty( $args['tooltip'] ) ) {
$output .= sprintf( '<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
$output .= '</label>';
break;
// Toggle.
case 'toggle':
$toggle_args = $args;
$toggle_args['input-class'] = $input_class;
$output = wpforms_panel_field_toggle_control( $toggle_args, $input_id, $field_name, $label, $value, $data_attr );
break;
// Radio.
case 'radio':
$options = $args['options'];
$radio_counter = 1;
$output = '';
foreach ( $options as $key => $item ) {
if ( empty( $item['label'] ) ) {
continue;
}
$item_value = ! empty( $item['value'] ) ? $item['value'] : $key;
$output .= '<span class="row">';
if ( ! empty( $item['pre_label'] ) ) {
$output .= '<label>' . $item['pre_label'];
}
$output .= sprintf(
'<input type="radio" id="%s-%d" name="%s" value="%s" class="%s" %s %s>',
$input_id,
$radio_counter,
$field_name,
$item_value,
$input_class,
checked( $item_value, $value, false ),
$data_attr
);
if ( empty( $item['pre_label'] ) ) {
$output .= sprintf(
'<label for="%s-%d" class="inline">%s',
$input_id,
$radio_counter,
$item['label']
);
} else {
$output .= '<span class="wpforms-panel-field-radio-label">' . $item['label'] . '</span>';
}
if ( ! empty( $item['tooltip'] ) ) {
$output .= sprintf( '<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>', esc_attr( $item['tooltip'] ) );
}
$output .= '</label></span>';
$radio_counter ++;
}
if ( ! empty( $output ) ) {
$output = '<div class="wpforms-panel-field-radio-container">' . $output . '</div>';
}
break;
// Select.
case 'select':
if ( empty( $args['options'] ) && empty( $args['field_map'] ) && empty( $args['multiple'] ) ) {
return '';
}
if ( ! empty( $args['field_map'] ) ) {
$options = [];
$available_fields = wpforms_get_form_fields( $form_data, $args['field_map'] );
if ( ! empty( $available_fields ) ) {
foreach ( $available_fields as $id => $available_field ) {
$options[ $id ] = ! empty( $available_field['label'] )
? esc_attr( $available_field['label'] )
: sprintf( /* translators: %d - field ID. */
esc_html__( 'Field #%d', 'wpforms-lite' ),
absint( $id )
);
}
}
$input_class .= ' wpforms-field-map-select';
$data_attr .= ' data-field-map-allowed="' . implode( ' ', $args['field_map'] ) . '"';
if ( ! empty( $placeholder ) ) {
$data_attr .= ' data-field-map-placeholder="' . esc_attr( $placeholder ) . '"';
}
} else {
$options = $args['options'];
}
if ( array_key_exists( 'choicesjs', $args ) && is_array( $args['choicesjs'] ) ) {
$input_class .= ' choicesjs-select';
$data_attr .= ! empty( $args['choicesjs']['use_ajax'] ) ? ' data-choicesjs-use-ajax=1' : '';
$data_attr .= ! empty( $args['choicesjs']['callback_fn'] ) ? ' data-choicesjs-callback-fn="' . esc_attr( $args['choicesjs']['callback_fn'] ) . '"' : '';
}
if ( ! empty( $args['multiple'] ) ) {
$data_attr .= ' multiple';
}
$output = sprintf(
'<select id="%s" name="%s" class="%s" %s>',
$input_id,
$field_name,
esc_attr( $input_class ),
$data_attr
);
if ( ! empty( $placeholder ) ) {
$output .= '<option value="">' . $placeholder . '</option>';
}
// This argument is used to disable some options, it takes an array of option values.
// For instance, if you want to disable options with value '1' and '2', you should pass array( '1', '2' ).
$disabled_options = ! empty( $args['disabled_options'] ) ? (array) $args['disabled_options'] : [];
foreach ( $options as $key => $item ) {
// If the option is disabled, we add the disabled attribute.
$disabled = in_array( $key, $disabled_options, true ) ? 'disabled' : '';
// Disabled options cannot be selected, so we bail early.
if ( ! empty( $disabled ) ) {
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $key ),
$disabled,
$item
);
continue;
}
if ( is_array( $value ) ) {
$selected = in_array( $key, $value, true ) ? 'selected' : '';
} else {
$selected = selected( $key, $value, false );
}
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $key ),
$selected,
$item
);
}
$output .= '</select>';
break;
case 'color':
$class .= ' wpforms-panel-field-colorpicker';
$input_class .= ' wpforms-color-picker';
$output = sprintf(
'<input type="text" id="%s" name="%s" value="%s" class="%s" %s>',
$input_id,
$field_name,
esc_attr( $value ),
wpforms_sanitize_classes( $input_class, false ),
$data_attr
);
break;
}
// Put the pieces together.
$field_open = sprintf(
'<div id="%s-wrap" class="wpforms-panel-field %s %s">',
$input_id,
$class,
'wpforms-panel-field-' . sanitize_html_class( $option )
);
$field_open .= ! empty( $args['before'] ) ? $args['before'] : '';
if ( $option !== 'toggle' && $option !== 'checkbox' && ! empty( $label ) ) {
$field_label = sprintf(
'<label for="%s">%s',
$input_id,
$label
);
if ( ! empty( $args['tooltip'] ) ) {
$field_label .= sprintf( '<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
if ( ! empty( $args['after_tooltip'] ) ) {
$field_label .= $args['after_tooltip'];
}
if ( $smarttags_toggle && ! ( $option === 'textarea' && ! empty( $args['tinymce'] ) ) ) {
$field_label .= $smarttags_toggle;
}
$field_label .= '</label>';
if ( ! empty( $args['after_label'] ) ) {
$field_label .= $args['after_label'];
}
} else {
$field_label = '';
}
$field_close = '';
if ( $smarttags_toggle && $option === 'textarea' && ! empty( $args['tinymce'] ) ) {
$field_close .= $smarttags_toggle;
}
$field_close .= ! empty( $args['after'] ) ? $args['after'] : '';
$field_close .= '</div>';
$output = $field_open . $field_label . $output . $field_close;
// Wash our hands.
if ( $echo ) {
echo $output;
} else {
return $output;
}
}
/**
* Create toggle control.
*
* It's like a regular checkbox but with a modern visual appearance.
*
* @since 1.6.8
*
* @param array $args Arguments array.
*
* @type bool $status If `true`, control will display the current status next to the toggle.
* @type string $status-on Status `On` text. By default `On`.
* @type string $status-off Status `Off` text. By default `Off`.
* @type bool $label-hide If `true` then label will not display.
* @type string $tooltip Tooltip text.
* @type string $input-class CSS class for the hidden `<input type=checkbox>`.
* @type string $control-class CSS class for the wrapper `<span>`.
*
* @param string $input_id Input ID.
* @param string $field_name Field name.
* @param string $label Label text. Can contain HTML in order to display additional badges.
* @param mixed $value Value.
* @param string $data_attr Attributes.
*
* @return string
*/
function wpforms_panel_field_toggle_control( $args, $input_id, $field_name, $label, $value, $data_attr ) {
$checked = checked( true, (bool) $value, false );
$status = '';
if ( ! empty( $args['status'] ) ) {
$status_on = ! empty( $args['status-on'] ) ? $args['status-on'] : esc_html__( 'On', 'wpforms-lite' );
$status_off = ! empty( $args['status-off'] ) ? $args['status-off'] : esc_html__( 'Off', 'wpforms-lite' );
$status = sprintf(
'<label
for="%s"
class="wpforms-toggle-control-status"
data-on="%s"
data-off="%s">
%s
</label>',
esc_attr( $input_id ),
esc_attr( $status_on ),
esc_attr( $status_off ),
esc_html( $value ? $status_on : $status_off )
);
}
$label_html = empty( $args['label-hide'] ) && ! empty( $label ) ?
sprintf(
'<label for="%s" class="wpforms-toggle-control-label">%s</label>',
esc_attr( $input_id ),
$label
) : '';
$label_html .= isset( $args['tooltip'] ) ?
sprintf(
'<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>',
esc_attr( $args['tooltip'] )
) : '';
$label_left = ! empty( $args['label-left'] ) ? $label_html . $status : '';
$label_right = empty( $args['label-left'] ) ? $status . $label_html : '';
$title = isset( $args['title'] ) ? ' title="' . esc_attr( $args['title'] ) . '"' : '';
$control_class = ! empty( $args['control-class'] ) ? $args['control-class'] : '';
$input_class = ! empty( $args['input-class'] ) ? $args['input-class'] : '';
return sprintf(
'<span class="wpforms-toggle-control %8$s" %9$s>
%1$s
<input type="checkbox" id="%2$s" name="%3$s" class="%7$s" value="1" %4$s %5$s>
<label class="wpforms-toggle-control-icon" for="%2$s"></label>
%6$s
</span>',
$label_left,
esc_attr( $input_id ),
esc_attr( $field_name ),
$checked,
$data_attr,
$label_right,
wpforms_sanitize_classes( $input_class ),
wpforms_sanitize_classes( $control_class ),
$title
);
}
/**
* Get settings block state, whether it's opened or closed.
*
* @since 1.4.8
*
* @param int $form_id
* @param int $block_id
* @param string $block_type
*
* @return string
*/
function wpforms_builder_settings_block_get_state( $form_id, $block_id, $block_type ) {
$form_id = absint( $form_id );
$block_id = absint( $block_id );
$block_type = sanitize_key( $block_type );
$state = 'opened';
$all_states = get_user_meta( get_current_user_id(), 'wpforms_builder_settings_collapsable_block_states', true );
if ( empty( $all_states ) ) {
return $state;
}
if (
is_array( $all_states ) &&
! empty( $all_states[ $form_id ][ $block_type ][ $block_id ] ) &&
'closed' === $all_states[ $form_id ][ $block_type ][ $block_id ]
) {
$state = 'closed';
}
// Backward compatibility for notifications.
if ( 'notification' === $block_type && 'closed' !== $state ) {
$notification_states = get_user_meta( get_current_user_id(), 'wpforms_builder_notification_states', true );
}
if (
! empty( $notification_states[ $form_id ][ $block_id ] ) &&
'closed' === $notification_states[ $form_id ][ $block_id ]
) {
$state = 'closed';
}
if ( 'notification' === $block_type ) {
// Backward compatibility for notifications.
return apply_filters( 'wpforms_builder_notification_get_state', $state, $form_id, $block_id );
}
return apply_filters( 'wpforms_builder_settings_block_get_state', $state, $form_id, $block_id, $block_type );
}
/**
* Get the list of allowed tags, used in pair with wp_kses() function.
* This allows getting rid of all potentially harmful HTML tags and attributes.
*
* @since 1.5.9
*
* @return array Allowed Tags.
*/
function wpforms_builder_preview_get_allowed_tags() {
static $allowed_tags;
if ( ! empty( $allowed_tags ) ) {
return $allowed_tags;
}
$atts = [ 'align', 'class', 'type', 'id', 'for', 'style', 'src', 'rel', 'href', 'target', 'value', 'width', 'height' ];
$tags = [ 'label', 'iframe', 'style', 'button', 'strong', 'small', 'table', 'span', 'abbr', 'code', 'pre', 'div', 'img', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'li', 'em', 'hr', 'br', 'th', 'tr', 'td', 'p', 'a', 'b', 'i' ];
$allowed_atts = array_fill_keys( $atts, [] );
$allowed_tags = array_fill_keys( $tags, $allowed_atts );
return $allowed_tags;
}
/**
* Output builder panel fields group wrapper.
*
* @since 1.6.6
*
* @param string $inner Inner HTML to wrap.
* @param array $args Array of arguments.
* @param bool $echo Flag to display.
*
* @return string
*/
function wpforms_panel_fields_group( $inner, $args = [], $echo = true ) {
$group = ! empty( $args['group'] ) ? $args['group'] : '';
$unfoldable = ! empty( $args['unfoldable'] );
$default = ( ! empty( $args['default'] ) && $args['default'] === 'opened' ) ? ' opened' : '';
$opened = ! empty( $_COOKIE[ 'wpforms_fields_group_' . $group ] ) && $_COOKIE[ 'wpforms_fields_group_' . $group ] === 'true' ? ' opened' : $default;
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
$output = sprintf(
'<div class="wpforms-panel-fields-group %1$s%2$s"%3$s>',
$class,
$unfoldable ? ' unfoldable' . $opened : '',
$unfoldable ? ' data-group="' . $group . '"' : ''
);
if ( ! empty( $args['borders'] ) && in_array( 'top', $args['borders'], true ) ) {
$output .= '<div class="wpforms-panel-fields-group-border-top"></div>';
}
if ( ! empty( $args['title'] ) ) {
$chevron = $unfoldable ? '<i class="fa fa-chevron-circle-right"></i>' : '';
$output .= '<div class="wpforms-panel-fields-group-title">' . esc_html( $args['title'] ) . $chevron . '</div>';
}
if ( ! empty( $args['description'] ) ) {
$output .= '<div class="wpforms-panel-fields-group-description">' . wp_kses_post( $args['description'] ) . '</div>';
}
$output .= sprintf(
'<div class="wpforms-panel-fields-group-inner"%s>%s</div>',
empty( $opened ) && $unfoldable ? ' style="display: none;"' : '',
$inner
);
if ( ! empty( $args['borders'] ) && in_array( 'bottom', $args['borders'], true ) ) {
$output .= '<div class="wpforms-panel-fields-group-border-bottom"></div>';
}
$output .= '</div>';
if ( ! $echo ) {
return $output;
}
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Get the pages for the "Show Page" dropdown selection in Confirmations Settings in Builder.
*
* @since 1.7.9
*
* @param array $form_data Form data.
* @param int $confirmation_id Confirmation ID.
*
* @return array
*/
function wpforms_builder_form_settings_confirmation_get_pages( $form_data, $confirmation_id ) {
$pre_selected_page_id = empty( $form_data['settings']['confirmations'][ $confirmation_id ]['page'] ) ? 0 : absint( $form_data['settings']['confirmations'][ $confirmation_id ]['page'] );
$pages = wp_list_pluck( wpforms_search_posts(), 'post_title', 'ID' );
if ( empty( $pre_selected_page_id ) || isset( $pages[ $pre_selected_page_id ] ) ) {
return $pages;
}
// If the pre-selected page isn't in `$pages`, we manually fetch it include it in `$pages`.
$pre_selected_page = get_post( $pre_selected_page_id );
if ( empty( $pre_selected_page ) ) {
return $pages;
}
$pages[ $pre_selected_page->ID ] = wpforms_get_post_title( $pre_selected_page );
return $pages;
}

View File

@@ -0,0 +1,300 @@
<?php
/**
* Base panel class.
*
* @since 1.0.0
*/
abstract class WPForms_Builder_Panel {
/**
* Full name of the panel.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Slug.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Font Awesome Icon used for the editor button, eg "fa-list".
*
* @since 1.0.0
*
* @var mixed
*/
public $icon = false;
/**
* Priority order the field button should show inside the "Add Fields" tab.
*
* @since 1.0.0
*
* @var int
*/
public $order = 50;
/**
* If panel contains a sidebar element or is full width.
*
* @since 1.0.0
*
* @var bool
*/
public $sidebar = false;
/**
* Contain form object if we have one.
*
* @since 1.0.0
*
* @var object
*/
public $form;
/**
* Contain array of the form data (post_content).
*
* @since 1.0.0
*
* @var array
*/
public $form_data;
/**
* Class instance.
*
* @since 1.7.7
*
* @var static
*/
private static $instance;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Load form if found.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
$this->form = wpforms()->get( 'form' )->get( $form_id );
$this->form_data = $this->form ? wpforms_decode( $this->form->post_content ) : false;
// Get current revision, if available.
$revision = wpforms()->get( 'revisions' )->get_revision();
// If we're viewing a valid revision, replace the form data so the Form Builder shows correct state.
if ( $revision && isset( $revision->post_content ) ) {
$this->form_data = wpforms_decode( $revision->post_content );
}
// Bootstrap.
$this->init();
// Load panel specific enqueues.
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ], 15 );
// Primary panel button.
add_action( 'wpforms_builder_panel_buttons', [ $this, 'button' ], $this->order, 2 );
// Output.
add_action( 'wpforms_builder_panels', [ $this, 'panel_output' ], $this->order, 2 );
// Save instance.
self::$instance = $this;
}
/**
* Get class instance.
*
* @since 1.7.7
*
* @return static
*/
public static function instance() {
if ( self::$instance === null || ! self::$instance instanceof static ) {
self::$instance = new static();
}
return self::$instance;
}
/**
* All systems go. Used by children.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Enqueue assets for the builder. Used by children.
*
* @since 1.0.0
*/
public function enqueues() {
}
/**
* Primary panel button in the left panel navigation.
*
* @since 1.0.0
*
* @param mixed $form
* @param string $view
*/
public function button( $form, $view ) {
$active = $view === $this->slug ? 'active' : '';
?>
<button class="wpforms-panel-<?php echo esc_attr( $this->slug ); ?>-button <?php echo $active; ?>" data-panel="<?php echo esc_attr( $this->slug ); ?>">
<i class="fa <?php echo esc_attr( $this->icon ); ?>"></i>
<span><?php echo esc_html( $this->name ); ?></span>
</button>
<?php
}
/**
* Output the contents of the panel.
*
* @since 1.0.0
*
* @param object $form Current form object.
* @param string $view Active Form Builder view (panel).
*/
public function panel_output( $form, $view ) {
$wrap = $this->sidebar ? 'wpforms-panel-sidebar-content' : 'wpforms-panel-full-content';
$classes = [ 'wpforms-panel' ];
if ( in_array( $this->slug, [ 'fields', 'revisions' ], true ) ) {
$classes[] = 'wpforms-panel-fields';
}
if ( $view === $this->slug ) {
$classes[] = 'active';
}
printf( '<div class="%s" id="wpforms-panel-%s">', wpforms_sanitize_classes( $classes, true ), esc_attr( $this->slug ) );
printf( '<div class="%s">', $wrap );
if ( true === $this->sidebar ) {
if ( $this->slug === 'fields' ) {
echo '<div class="wpforms-panel-sidebar-toggle"><div class="wpforms-panel-sidebar-toggle-vertical-line"></div><div class="wpforms-panel-sidebar-toggle-icon"><i class="fa fa-angle-left"></i></div></div>';
}
echo '<div class="wpforms-panel-sidebar">';
do_action( 'wpforms_builder_before_panel_sidebar', $this->form, $this->slug );
$this->panel_sidebar();
do_action( 'wpforms_builder_after_panel_sidebar', $this->form, $this->slug );
echo '</div>';
}
echo '<div class="wpforms-panel-content-wrap">';
echo '<div class="wpforms-panel-content">';
do_action( 'wpforms_builder_before_panel_content', $this->form, $this->slug );
$this->panel_content();
do_action( 'wpforms_builder_after_panel_content', $this->form, $this->slug );
echo '</div>';
echo '</div>';
echo '</div>';
echo '</div>';
}
/**
* Output the panel's sidebar if we have one.
*
* @since 1.0.0
*/
public function panel_sidebar() {
}
/**
* Output panel sidebar sections.
*
* @since 1.0.0
*
* @param string $name Sidebar section name.
* @param string $slug Sidebar section slug.
* @param string $icon Sidebar section icon.
*/
public function panel_sidebar_section( $name, $slug, $icon = '' ) {
$default_classes = [
'wpforms-panel-sidebar-section',
'wpforms-panel-sidebar-section-' . $slug,
];
if ( $slug === 'default' ) {
$default_classes[] = 'default';
}
if ( ! empty( $icon ) ) {
$default_classes[] = 'icon';
}
/**
* Allow adding custom CSS classes to a sidebar section in the Form Builder.
*
* @since 1.7.7.2
*
* @param array $classes Sidebar section classes.
* @param string $name Sidebar section name.
* @param string $slug Sidebar section slug.
* @param string $icon Sidebar section icon.
*/
$classes = (array) apply_filters( 'wpforms_builder_panel_sidebar_section_classes', [], $name, $slug, $icon );
$classes = array_merge( $default_classes, $classes );
echo '<a href="#" class="' . wpforms_sanitize_classes( $classes, true ) . '" data-section="' . esc_attr( $slug ) . '">';
if ( ! empty( $icon ) ) {
echo '<img src="' . esc_url( $icon ) . '">';
}
echo esc_html( $name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
echo '</a>';
}
/**
* Output the panel's primary content.
*
* @since 1.0.0
*/
public function panel_content() {
}
}

View File

@@ -0,0 +1,716 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Fields management panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Fields extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Fields', 'wpforms-lite' );
$this->slug = 'fields';
$this->icon = 'fa-list-alt';
$this->order = 10;
$this->sidebar = true;
if ( $this->form ) {
add_action( 'wpforms_builder_fields', [ $this, 'search' ], 5 );
add_action( 'wpforms_builder_fields', [ $this, 'fields' ] );
add_action( 'wpforms_builder_fields_options', [ $this, 'fields_options' ] );
add_action( 'wpforms_builder_preview', [ $this, 'preview' ] );
// Template for form builder previews.
add_action( 'wpforms_builder_print_footer_scripts', [ $this, 'field_preview_templates' ] );
add_action( 'wpforms_builder_print_footer_scripts', [ $this, 'choices_limit_message_template' ] );
add_action( 'wpforms_builder_print_footer_scripts', [ $this, 'choices_empty_message_template' ] );
}
}
/**
* Enqueue assets for the Fields panel.
*
* @since 1.0.0
* @since 1.6.8 All the builder stylesheets enqueues moved to the `\WPForms_Builder::enqueues()`.
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-drag-fields',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/drag-fields{$min}.js",
[ 'wpforms-builder' ],
WPFORMS_VERSION,
true
);
wp_enqueue_script(
'wpforms-builder-search-fields',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/search-fields{$min}.js",
[ 'wpforms-builder' ],
WPFORMS_VERSION,
true
);
}
/**
* Output the Field panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
?>
<ul class="wpforms-tabs wpforms-clear">
<li class="wpforms-tab" id="add-fields">
<a href="#" class="active">
<i class="fa fa-list-alt"></i><?php esc_html_e( 'Add Fields', 'wpforms-lite' ); ?>
</a>
</li>
<li class="wpforms-tab" id="field-options">
<a href="#">
<i class="fa fa-sliders"></i><?php esc_html_e( 'Field Options', 'wpforms-lite' ); ?>
</a>
</li>
</ul>
<div class="wpforms-add-fields wpforms-tab-content">
<?php do_action( 'wpforms_builder_fields', $this->form ); ?>
</div>
<div id="wpforms-field-options" class="wpforms-field-options wpforms-tab-content">
<?php do_action( 'wpforms_builder_fields_options', $this->form ); ?>
</div>
<?php
}
/**
* Output the Field panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
// Check if there is a form created.
if ( ! $this->form ) {
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage the fields.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
?>
<div class="wpforms-preview-wrap">
<div class="wpforms-preview">
<div class="wpforms-title-desc">
<div class="wpforms-title-desc-inner">
<h2 class="wpforms-form-name">
<?php echo esc_html( isset( $this->form_data['settings']['form_title'] ) ? $this->form_data['settings']['form_title'] : $this->form->post_title ); ?>
</h2>
<span class="wpforms-form-desc">
<?php
echo wp_kses(
isset( $this->form_data['settings']['form_desc'] ) ? $this->form_data['settings']['form_desc'] : $this->form->post_excerpt,
wpforms_builder_preview_get_allowed_tags()
);
?>
</span>
</div>
</div>
<div class="wpforms-no-fields-holder wpforms-hidden">
<?php $this->no_fields_options(); ?>
<?php $this->no_fields_preview(); ?>
</div>
<div class="wpforms-field-wrap">
<?php do_action( 'wpforms_builder_preview', $this->form ); ?>
</div>
<?php
$captcha_settings = wpforms_get_captcha_settings();
$extra_class = 'is-' . $captcha_settings['provider'];
?>
<div class="wpforms-field-recaptcha <?php echo sanitize_html_class( $extra_class ); ?>">
<div class="wpforms-field-recaptcha-wrap">
<div class="wpforms-field-recaptcha-wrap-l">
<svg class="wpforms-field-hcaptcha-icon" fill="none" viewBox="0 0 83 90"><path opacity=".5" d="M60.012 69.998H50.01V80h10.002V69.998z" fill="#0074BF"/><path opacity=".7" d="M50.01 69.998H40.008V80H50.01V69.998zM40.008 69.998H30.006V80h10.002V69.998z" fill="#0074BF"/><path opacity=".5" d="M30.006 69.998H20.004V80h10.002V69.998z" fill="#0074BF"/><path opacity=".7" d="M70.014 60.013H60.014v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".8" d="M60.012 60.013H50.01v10.002h10.002V60.012z" fill="#0082BF"/><path d="M50.01 60.013H40.008v10.002H50.01V60.012zM40.008 60.013H30.006v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".8" d="M30.006 60.013H20.004v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".7" d="M20.004 60.013H10.002v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".5" d="M80 50.01H69.998v10.002H80V50.01z" fill="#008FBF"/><path opacity=".8" d="M70.014 50.01H60.014v10.002h10.002V50.01z" fill="#008FBF"/><path d="M60.012 50.01H50.01v10.002h10.002V50.01zM50.01 50.01H40.008v10.002H50.01V50.01zM40.008 50.01H30.006v10.002h10.002V50.01zM30.006 50.01H20.004v10.002h10.002V50.01z" fill="#008FBF"/><path opacity=".8" d="M20.004 50.01H10.002v10.002h10.002V50.01z" fill="#008FBF"/><path opacity=".5" d="M10.002 50.01H0v10.002h10.002V50.01z" fill="#008FBF"/><path opacity=".7" d="M80 40.008H69.998V50.01H80V40.008z" fill="#009DBF"/><path d="M70.014 40.008H60.014V50.01h10.002V40.008zM60.012 40.008H50.01V50.01h10.002V40.008zM50.01 40.008H40.008V50.01H50.01V40.008zM40.008 40.008H30.006V50.01h10.002V40.008zM30.006 40.008H20.004V50.01h10.002V40.008zM20.004 40.008H10.002V50.01h10.002V40.008z" fill="#009DBF"/><path opacity=".7" d="M10.002 40.008H0V50.01h10.002V40.008z" fill="#009DBF"/><path opacity=".7" d="M80 30.006H69.998v10.002H80V30.006z" fill="#00ABBF"/><path d="M70.014 30.006H60.014v10.002h10.002V30.006zM60.012 30.006H50.01v10.002h10.002V30.006zM50.01 30.006H40.008v10.002H50.01V30.006zM40.008 30.006H30.006v10.002h10.002V30.006zM30.006 30.006H20.004v10.002h10.002V30.006zM20.004 30.006H10.002v10.002h10.002V30.006z" fill="#00ABBF"/><path opacity=".7" d="M10.002 30.006H0v10.002h10.002V30.006z" fill="#00ABBF"/><path opacity=".5" d="M80 20.004H69.998v10.002H80V20.004z" fill="#00B9BF"/><path opacity=".8" d="M70.014 20.004H60.014v10.002h10.002V20.004z" fill="#00B9BF"/><path d="M60.012 20.004H50.01v10.002h10.002V20.004zM50.01 20.004H40.008v10.002H50.01V20.004zM40.008 20.004H30.006v10.002h10.002V20.004zM30.006 20.004H20.004v10.002h10.002V20.004z" fill="#00B9BF"/><path opacity=".8" d="M20.004 20.004H10.002v10.002h10.002V20.004z" fill="#00B9BF"/><path opacity=".5" d="M10.002 20.004H0v10.002h10.002V20.004z" fill="#00B9BF"/><path opacity=".7" d="M70.014 10.002H60.014v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".8" d="M60.012 10.002H50.01v10.002h10.002V10.002z" fill="#00C6BF"/><path d="M50.01 10.002H40.008v10.002H50.01V10.002zM40.008 10.002H30.006v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".8" d="M30.006 10.002H20.004v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".7" d="M20.004 10.002H10.002v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".5" d="M60.012 0H50.01v10.002h10.002V0z" fill="#00D4BF"/><path opacity=".7" d="M50.01 0H40.008v10.002H50.01V0zM40.008 0H30.006v10.002h10.002V0z" fill="#00D4BF"/><path opacity=".5" d="M30.006 0H20.004v10.002h10.002V0z" fill="#00D4BF"/><path d="M26.34 36.84l2.787-6.237c1.012-1.592.88-3.55-.232-4.66a3.6 3.6 0 00-.481-.399 3.053 3.053 0 00-2.571-.298 4.246 4.246 0 00-2.322 1.791s-3.816 8.907-5.242 12.905c-1.426 3.998-.863 11.346 4.611 16.836 5.806 5.806 14.215 7.132 19.573 3.102.232-.116.431-.25.63-.415l16.521-13.8c.797-.664 1.99-2.024.93-3.583-1.046-1.526-3.003-.481-3.816.033l-9.504 6.917a.421.421 0 01-.597-.05s0-.017-.017-.017c-.249-.298-.282-1.078.1-1.393l14.58-12.374c1.26-1.128 1.426-2.787.414-3.915-.995-1.11-2.57-1.078-3.848.067l-13.12 10.267a.578.578 0 01-.813-.083c0-.016-.017-.016-.017-.033-.265-.298-.365-.78-.066-1.078l14.862-14.414c1.178-1.095 1.244-2.936.15-4.097a2.824 2.824 0 00-2.024-.863 2.905 2.905 0 00-2.09.83L39.544 36.144c-.365.364-1.078 0-1.161-.432a.474.474 0 01.132-.431l11.628-13.237a2.86 2.86 0 00.15-4.047 2.86 2.86 0 00-4.048-.15c-.05.05-.1.084-.133.133L28.447 37.47c-.63.63-1.56.664-2.007.299a.657.657 0 01-.1-.929z" fill="#fff"/></svg>
<svg class="wpforms-field-recaptcha-icon" viewBox="0 0 28 27.918"><path d="M28 13.943l-.016-.607V2l-3.133 3.134a13.983 13.983 0 00-21.964.394l5.134 5.183a6.766 6.766 0 012.083-2.329A6.171 6.171 0 0114.025 7.1a1.778 1.778 0 01.492.066 6.719 6.719 0 015.17 3.119l-3.625 3.641 11.941.016" fill="#1c3aa9"/><path d="M13.943 0l-.607.016H2.018l3.133 3.133a13.969 13.969 0 00.377 21.964l5.183-5.134A6.766 6.766 0 018.382 17.9 6.171 6.171 0 017.1 13.975a1.778 1.778 0 01.066-.492 6.719 6.719 0 013.117-5.167l3.641 3.641L13.943 0" fill="#4285f4"/><path d="M0 13.975l.016.607v11.334l3.133-3.133a13.983 13.983 0 0021.964-.394l-5.134-5.183a6.766 6.766 0 01-2.079 2.33 6.171 6.171 0 01-3.92 1.279 1.778 1.778 0 01-.492-.066 6.719 6.719 0 01-5.167-3.117l3.641-3.641c-4.626 0-9.825.016-11.958-.016" fill="#ababab"/></svg>
<svg class="wpforms-field-turnstile-icon" fill="none" viewBox="0 0 106 106"> <g clip-path="url(#a)"> <path fill="#F4801F" d="m72.375 76.265.541-1.877c.643-2.231.405-4.29-.678-5.808-1.011-1.397-2.66-2.216-4.68-2.312l-38.213-.486a.743.743 0 0 1-.683-1.012 1.012 1.012 0 0 1 .885-.678l38.583-.506c4.554-.207 9.532-3.92 11.267-8.454l2.196-5.748a1.354 1.354 0 0 0 .061-.779 25.13 25.13 0 0 0-48.312-2.6 11.307 11.307 0 0 0-17.708 11.849A16.054 16.054 0 0 0 .172 76.28a.744.744 0 0 0 .734.643H71.48a.927.927 0 0 0 .895-.658Z"/> <path fill="#F9AB41" d="M85.11 49.82c-.338 0-.692.01-1.063.03a.444.444 0 0 0-.162.035.59.59 0 0 0-.384.405l-1.518 5.191c-.648 2.231-.41 4.29.678 5.808a5.895 5.895 0 0 0 4.675 2.313l8.15.505a.728.728 0 0 1 .577.314.759.759 0 0 1 .086.693 1.012 1.012 0 0 1-.885.678l-8.465.506c-4.599.213-9.552 3.921-11.287 8.45l-.612 1.598a.455.455 0 0 0 .4.617h29.157a.782.782 0 0 0 .779-.592 20.92 20.92 0 0 0-10.822-24.36 20.916 20.916 0 0 0-9.294-2.191h-.01Z"/> </g> <defs> <clipPath id="a"> <path fill="#fff" d="M0 0h106v106H0z"/> </clipPath> </defs> </svg>
</div>
<div class="wpforms-field-recaptcha-wrap-r">
<p class="wpforms-field-hcaptcha-title">hCaptcha</p>
<p class="wpforms-field-recaptcha-title">reCAPTCHA</p>
<p class="wpforms-field-turnstile-title">Turnstile</p>
<p class="wpforms-field-recaptcha-desc">
<span class="wpforms-field-recaptcha-desc-txt"><?php esc_html_e( 'Enabled', 'wpforms-lite' ); ?></span><svg class="wpforms-field-recaptcha-desc-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M512 256c0-37.7-23.7-69.9-57.1-82.4 14.7-32.4 8.8-71.9-17.9-98.6-26.7-26.7-66.2-32.6-98.6-17.9C325.9 23.7 293.7 0 256 0s-69.9 23.7-82.4 57.1c-32.4-14.7-72-8.8-98.6 17.9-26.7 26.7-32.6 66.2-17.9 98.6C23.7 186.1 0 218.3 0 256s23.7 69.9 57.1 82.4c-14.7 32.4-8.8 72 17.9 98.6 26.6 26.6 66.1 32.7 98.6 17.9 12.5 33.3 44.7 57.1 82.4 57.1s69.9-23.7 82.4-57.1c32.6 14.8 72 8.7 98.6-17.9 26.7-26.7 32.6-66.2 17.9-98.6 33.4-12.5 57.1-44.7 57.1-82.4zm-144.8-44.25L236.16 341.74c-4.31 4.28-11.28 4.25-15.55-.06l-75.72-76.33c-4.28-4.31-4.25-11.28.06-15.56l26.03-25.82c4.31-4.28 11.28-4.25 15.56.06l42.15 42.49 97.2-96.42c4.31-4.28 11.28-4.25 15.55.06l25.82 26.03c4.28 4.32 4.26 11.29-.06 15.56z"></path></svg>
</p>
</div>
</div>
</div>
<?php
$submit = ! empty( $this->form_data['settings']['submit_text'] ) ? $this->form_data['settings']['submit_text'] : esc_html__( 'Submit', 'wpforms-lite' );
$submit_style = empty( $this->form_data['fields'] ) ? 'display: none;' : '';
printf( '<p class="wpforms-field-submit" style="%1$s"><input type="submit" value="%2$s" class="wpforms-field-submit-button"></p>', esc_attr( $submit_style ), esc_attr( $submit ) );
/** This action is documented in includes/class-frontend.php. */
do_action( 'wpforms_display_submit_after', $this->form_data, 'submit' ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
?>
<?php wpforms_debug_data( $this->form_data ); ?>
</div>
</div>
<?php
}
/**
* Builder field buttons.
*
* @since 1.0.0
*/
public function fields() {
$fields = wpforms_get_builder_fields();
// Output the buttons.
foreach ( $fields as $id => $group ) {
usort( $group['fields'], [ $this, 'field_order' ] );
echo '<div class="wpforms-add-fields-group">';
echo '<a href="#" class="wpforms-add-fields-heading" data-group="' . esc_attr( $id ) . '">';
echo '<span>' . esc_html( $group['group_name'] ) . '</span>';
echo '<i class="fa fa-angle-down"></i>';
echo '</a>';
echo '<div class="wpforms-add-fields-buttons">';
foreach ( $group['fields'] as $field ) {
/**
* Attributes of the form field button on the Add Fields tab in the Form Builder.
*
* @since 1.5.1
*
* @param array $attributes Field attributes.
* @param array $field Field data.
* @param array $form_data Form data.
*/
$atts = apply_filters(
'wpforms_builder_field_button_attributes',
[
'id' => 'wpforms-add-fields-' . $field['type'],
'class' => [ 'wpforms-add-fields-button' ],
'data' => [
'field-type' => $field['type'],
],
'atts' => [],
],
$field,
$this->form_data
);
if ( ! empty( $field['keywords'] ) ) {
$atts['data']['field-keywords'] = $field['keywords'];
}
if ( ! empty( $field['class'] ) ) {
$atts['class'][] = $field['class'];
}
echo '<button ' . wpforms_html_attributes( $atts['id'], $atts['class'], $atts['data'], $atts['atts'] ) . '>';
if ( $field['icon'] ) {
echo '<i class="fa ' . esc_attr( $field['icon'] ) . '"></i> ';
}
echo esc_html( $field['name'] );
echo '</button>';
}
echo '</div>';
echo '</div>';
}
}
/**
* Editor Field Options.
*
* @since 1.0.0
*/
public function fields_options() {
// Check to make sure the form actually has fields created already.
if ( empty( $this->form_data['fields'] ) ) {
$this->no_fields_options();
return;
}
$fields = $this->form_data['fields'];
foreach ( $fields as $field ) {
$class = apply_filters( 'wpforms_builder_field_option_class', '', $field );
printf( '<div class="wpforms-field-option wpforms-field-option-%s %s" id="wpforms-field-option-%d" data-field-id="%d">', sanitize_html_class( $field['type'] ), wpforms_sanitize_classes( $class ), (int) $field['id'], (int) $field['id'] );
printf( '<input type="hidden" name="fields[%d][id]" value="%d" class="wpforms-field-option-hidden-id">', (int) $field['id'], (int) $field['id'] );
printf( '<input type="hidden" name="fields[%d][type]" value="%s" class="wpforms-field-option-hidden-type">', (int) $field['id'], esc_attr( $field['type'] ) );
do_action( "wpforms_builder_fields_options_{$field['type']}", $field );
echo '</div>';
}
}
/**
* Editor preview (right pane).
*
* @since 1.0.0
*/
public function preview() {
// Check to make sure the form actually has fields created already.
if ( empty( $this->form_data['fields'] ) ) {
$this->no_fields_preview();
return;
}
/**
* Filters the fields which must be displayed on the base level on the preview panel in the Form Builder.
*
* @since 1.7.7
*
* @param array $fields Form fields data.
*/
$fields = (array) apply_filters( 'wpforms_builder_panel_fields_preview_fields', $this->form_data['fields'] );
foreach ( $fields as $field ) {
$this->preview_single_field(
$field,
[]
);
}
}
/**
* Preview single field.
*
* @since 1.7.7
*
* @param array $field Field data.
* @param array $args Additional arguments.
*/
public function preview_single_field( $field, $args ) {
$class = ! empty( $field['size'] ) ? 'size-' . esc_attr( $field['size'] ) : '';
$class .= ! empty( $field['label_hide'] ) ? ' label_hide' : '';
$class .= isset( $field['label'] ) && empty( $field['label'] ) && $field['type'] !== 'html' ? ' label_empty' : '';
$class .= ! empty( $field['sublabel_hide'] ) ? ' sublabel_hide' : '';
$class .= ! empty( $field['required'] ) ? ' required' : '';
$class .= isset( $field['meta']['delete'] ) && $field['meta']['delete'] === false ? ' no-delete' : '';
$class .= isset( $field['meta']['duplicate'] ) && $field['meta']['duplicate'] === false ? ' no-duplicate' : '';
if ( ! empty( $field['input_columns'] ) ) {
$class .= $field['input_columns'] === '2' ? ' wpforms-list-2-columns' : '';
$class .= $field['input_columns'] === '3' ? ' wpforms-list-3-columns' : '';
$class .= $field['input_columns'] === 'inline' ? ' wpforms-list-inline' : '';
}
/**
* Filters class attribute of the field preview container in the Form Builder.
*
* @since 1.4.0
*
* @param string $css Field preview class.
* @param array $field Field data.
*/
$class = apply_filters( 'wpforms_field_preview_class', $class, $field ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
if ( ! has_action( "wpforms_display_field_{$field['type']}" ) ) {
$this->unavailable_fields_preview( $field );
return;
}
printf(
'<div class="wpforms-field wpforms-field-%1$s %2$s" id="wpforms-field-%3$d" data-field-id="%3$d" data-field-type="%1$s">',
esc_attr( $field['type'] ),
esc_attr( $class ),
absint( $field['id'] )
);
/**
* Filters display field duplicate button flag.
*
* @since 1.5.6.2
*
* @param bool $display_duplicate_button Display field duplicate button flag.
* @param array $field Field data.
* @param array $form_data Form data.
*/
if ( apply_filters( 'wpforms_field_preview_display_duplicate_button', true, $field, $this->form_data ) ) { // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
printf(
'<a href="#" class="wpforms-field-duplicate" title="%s"><i class="fa fa-files-o" aria-hidden="true"></i></a>',
esc_attr__( 'Duplicate Field', 'wpforms-lite' )
);
}
printf(
'<a href="#" class="wpforms-field-delete" title="%s"><i class="fa fa-trash-o" aria-hidden="true"></i></a>',
esc_attr__( 'Delete Field', 'wpforms-lite' )
);
if ( empty( $_COOKIE['wpforms_field_helper_hide'] ) ) {
printf(
'<div class="wpforms-field-helper">
<span class="wpforms-field-helper-edit">%s</span>
<span class="wpforms-field-helper-drag">%s</span>
<span class="wpforms-field-helper-hide" title="%s">
<i class="fa fa-times-circle" aria-hidden="true"></i>
</span>
</div>',
esc_html__( 'Click to Edit', 'wpforms-lite' ),
esc_html__( 'Drag to Reorder', 'wpforms-lite' ),
esc_attr__( 'Hide Helper', 'wpforms-lite' )
);
}
/**
* Fires after the field preview output in the Form Builder.
*
* @since 1.0.0
*
* @param array $field Field data.
*/
do_action( "wpforms_builder_fields_previews_{$field['type']}", $field ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
echo '</div>';
}
/**
* Generate HTML for hidden inputs from given data.
*
* @since 1.6.7
*
* @param array $data Field array data.
* @param string $name Input name prefix.
*/
private function generate_hidden_inputs( $data = [], $name = '' ) {
if ( ! is_array( $data ) || empty( $data ) ) {
return;
}
foreach ( $data as $key => $value ) {
if ( $key === 'id' ) {
continue;
}
$key = ! empty( $data['id'] ) ? sprintf( '[%s][%s]', $data['id'], $key ) : sprintf( '[%s]', $key );
if ( ! empty( $name ) ) {
$key = trim( $name ) . $key;
}
if ( is_array( $value ) ) {
$this->generate_hidden_inputs( $value, $key );
} else {
printf( "<input type='hidden' name='%s' value='%s' />", esc_attr( $key ), esc_attr( $value ) );
}
}
}
/**
* Unavailable builder field display.
*
* @since 1.6.7
*
* @param array $field Field array data.
*/
public function unavailable_fields_preview( $field ) {
// Using ucwords() for certain fields may generate incorrect words.
switch ( $field['type'] ) {
case 'url':
$field_type = 'URL';
break;
case 'html':
$field_type = 'HTML';
break;
case 'gdpr-checkbox':
$field_type = 'GDPR Checkbox';
break;
default:
$field_type = ucwords( preg_replace( '/[_-]/', ' ', $field['type'] ) );
}
$warning_message = sprintf( /* translators: %s - unavailable field name. */
esc_html__( 'Unfortunately, the %s field is not available and will be ignored on the front end.', 'wpforms-lite' ),
'<b>' . $field_type . '</b>'
);
$field_id = isset( $field['id'] ) ? $field['id'] : 0;
printf(
'<div class="wpforms-alert wpforms-alert-warning wpforms-alert-dismissible wpforms-alert-field-not-available" data-field-id="%d" data-field-type="unavailable">',
absint( $field_id )
);
printf(
'<div class="wpforms-alert-message">
<p>%1$s</p>
</div>
<div class="wpforms-alert-buttons">
<a href="%2$s" target="_blank" rel="noopener noreferrer" class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey">%3$s</a>
<button type="button" class="wpforms-dismiss-button" title="%4$s" data-field-id="%5$d" />
</div>',
$warning_message, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'https://wpforms.com/docs/how-to-import-and-export-wpforms/#field-missing',
esc_html__( 'Learn More', 'wpforms-lite' ),
esc_attr__( 'Dismiss this message. The field will be deleted as well.', 'wpforms-lite' ),
absint( $field_id )
);
// Save unavailable fields data in hidden inputs.
$this->generate_hidden_inputs( $field, 'fields' );
echo '</div>';
}
/**
* No fields options markup.
*
* @since 1.6.0
*/
public function no_fields_options() {
printf(
'<p class="no-fields wpforms-alert wpforms-alert-warning">%s</p>',
esc_html__( 'You don\'t have any fields yet.', 'wpforms-lite' )
);
}
/**
* No fields preview placeholder markup.
*
* @since 1.6.0
*/
public function no_fields_preview() {
printf(
'<div class="no-fields-preview">
<h4>%1$s</h4>
<p>%2$s</p>
</div>',
esc_html__( 'You don\'t have any fields yet. Add some!', 'wpforms-lite' ),
esc_html__( 'Take your pick from our wide variety of fields and start building out your form!', 'wpforms-lite' )
);
}
/**
* Sort Add Field buttons by order provided.
*
* @since 1.0.0
*
* @param array $a First item.
* @param array $b Second item.
*
* @return array
*/
public function field_order( $a, $b ) {
return $a['order'] - $b['order'];
}
/**
* Template for form builder preview.
*
* @since 1.4.5
*/
public function field_preview_templates() {
// Checkbox, Radio, and Payment Multiple/Checkbox field choices.
?>
<script type="text/html" id="tmpl-wpforms-field-preview-checkbox-radio-payment-multiple">
<# if ( data.settings.choices_images ) { #>
<ul class="primary-input wpforms-image-choices wpforms-image-choices-{{ data.settings.choices_images_style }}">
<# _.each( data.order, function( choiceID, key ) { #>
<li class="wpforms-image-choices-item<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' wpforms-selected' ); } #>">
<label>
<span class="wpforms-image-choices-image">
<# if ( ! _.isEmpty( data.settings.choices[choiceID].image ) ) { #>
<img src="{{ data.settings.choices[choiceID].image }}" alt="{{ data.settings.choices[choiceID].label }}" title="{{ data.settings.choices[choiceID].label }}">
<# } else { #>
<img src="{{ wpforms_builder.image_placeholder }}" alt="{{ data.settings.choices[choiceID].label }}" title="{{ data.settings.choices[choiceID].label }}">
<# } #>
</span>
<# if ( 'none' === data.settings.choices_images_style ) { #>
<br>
<input type="{{ data.type }}" readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } else { #>
<input class="wpforms-screen-reader-element" type="{{ data.type }}" readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } #>
<span class="wpforms-image-choices-label">
{{{ WPFormsBuilder.fieldChoiceLabel( data, choiceID ) }}}
</span>
</label>
</li>
<# }) #>
</ul>
<# } else if ( data.settings.choices_icons ) { #>
<ul class='primary-input wpforms-icon-choices wpforms-icon-choices-{{ data.settings.choices_icons_style }} wpforms-icon-choices-{{ data.settings.choices_icons_size }}' style="--wpforms-icon-choices-color: {{ data.settings.choices_icons_color }};">
<# _.each( data.order, function( choiceID, key ) { #>
<li class="wpforms-icon-choices-item<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' wpforms-selected' ); } #>">
<label>
<span class="wpforms-icon-choices-icon">
<i class="ic-fa-{{ data.settings.choices[choiceID].icon_style }} ic-fa-{{ data.settings.choices[choiceID].icon }}"></i>
<span class="wpforms-icon-choices-icon-bg"></span>
</span>
<# if ( 'none' === data.settings.choices_icons_style ) { #>
<input type='{{ data.type }}' readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } else { #>
<input class='wpforms-screen-reader-element' type='{{ data.type }}' readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } #>
<span class='wpforms-icon-choices-label'>
{{{ WPFormsBuilder.fieldChoiceLabel( data, choiceID ) }}}
</span>
</label>
</li>
<# }) #>
</ul>
<# } else { #>
<ul class="primary-input">
<# _.each( data.order, function( choiceID, key ) { #>
<li>
<input type="{{ data.type }}" readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
{{{ WPFormsBuilder.fieldChoiceLabel( data, choiceID ) }}}
</li>
<# }) #>
</ul>
<# } #>
</script>
<?php
}
/**
* Template for form builder preview.
*
* @since 1.6.9
*/
public function choices_limit_message_template() {
?>
<script type="text/html" id="tmpl-wpforms-choices-limit-message">
<div class="wpforms-alert-dynamic wpforms-alert wpforms-alert-warning">
<?php
printf(
wp_kses( /* translators: %s - total amount of choices. */
__( 'Showing the first 20 choices.<br> All %s choices will be displayed when viewing the form.', 'wpforms-lite' ),
[
'br' => [],
]
),
'{{ data.total }}'
);
?>
</div>
</script>
<?php
}
/**
* Template for empty choices message.
*
* @since 1.8.2
*
* @return void
*/
public function choices_empty_message_template() {
?>
<script type="text/html" id="tmpl-wpforms-empty-choice-message">
<div class="wpforms-notice-dynamic-empty wpforms-alert wpforms-alert-warning">
{{ data.message }}
</div>
</script>
<?php
}
/**
* Builder fields search.
*
* @since 1.8.3
*/
public function search() {
?>
<div class="wpforms-search-fields-wrapper">
<div class="wpforms-search-fields-input-wrapper">
<label for="wpforms-search-fields-input" class="wpforms-screen-reader-element"><?php esc_html_e( 'Search fields:', 'wpforms-lite' ); ?></label>
<input type="search" id="wpforms-search-fields-input" placeholder="<?php echo esc_attr__( 'Search fields...', 'wpforms-lite' ); ?>" autocomplete="off">
<i class="fa fa-times wpforms-search-fields-input-close" aria-hidden="true"></i>
</div>
<div class="wpforms-search-fields-list">
<div class="wpforms-add-fields-group">
<div class="wpforms-add-fields-buttons"></div>
</div>
</div>
<div class="wpforms-search-fields-no-results">
<p>
<?php esc_html_e( 'Sorry, we didn\'t find any fields that match your criteria.', 'wpforms-lite' ); ?>
</p>
</div>
</div>
<?php
}
}
new WPForms_Builder_Panel_Fields();

View File

@@ -0,0 +1,112 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Payments panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Payments extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Payments', 'wpforms-lite' );
$this->slug = 'payments';
$this->icon = 'fa-usd';
$this->order = 10;
$this->sidebar = true;
}
/**
* Output the Payments panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
$this->panel_sidebar_section( esc_html__( 'Default', 'wpforms-lite' ), 'default' );
do_action( 'wpforms_payments_panel_sidebar', $this->form );
}
/**
* Output the Payments panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
// An array of all the active provider addons.
$payments_active = apply_filters( 'wpforms_payments_available', [] );
if ( ! $this->form ) {
// Check if there is a form created. When no form has been created
// yet let the user know we need a form to setup a payment.
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage these settings.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
if ( empty( $payments_active ) ) {
// Check for active payment addons. When no payment addons are
// activated let the user know they need to install/activate an
// addon to setup a payment.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-default">
<div class="illustration illustration-payments"></div>
<h5>' . esc_html__( 'Install Your Payment Integration', 'wpforms-lite' ) . '</h5>
<p>' . sprintf(
wp_kses(
/* translators: %s - addons page URL. */
__( 'It seems you do not have any payment addons activated. You can head over to the <a href="%s">Addons page</a> to install and activate the addon for your payment service.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
],
]
),
esc_url( admin_url( 'admin.php?page=wpforms-addons' ) )
) .
'</p>
</div>';
} else {
// Everything is good - display default instructions.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-default">
<div class="illustration illustration-payments"></div>
<h5>' . esc_html__( 'Install Your Payment Integration', 'wpforms-lite' ) . '</h5>
<p>' . esc_html__( 'It seems you don\'t have any payment addons activated. Click one of the available addons and start accepting payments today!', 'wpforms-lite' ) . '</p>
</div>';
}
do_action( 'wpforms_payments_panel_content', $this->form );
}
}
new WPForms_Builder_Panel_Payments();

View File

@@ -0,0 +1,146 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Providers panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Providers extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Marketing', 'wpforms-lite' );
$this->slug = 'providers';
$this->icon = 'fa-bullhorn';
$this->order = 10;
$this->sidebar = true;
}
/**
* Enqueue assets for the Providers panel.
*
* @since 1.0.0
* @since 1.6.8 All the builder stylesheets enqueues moved to the `\WPForms_Builder::enqueues()`.
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-providers',
WPFORMS_PLUGIN_URL . "assets/js/admin-builder-providers{$min}.js",
[ 'jquery' ],
WPFORMS_VERSION,
false
);
wp_localize_script(
'wpforms-builder-providers',
'wpforms_builder_providers',
[
'url' => esc_url( remove_query_arg( 'newform', add_query_arg( [ 'view' => 'providers' ] ) ) ),
'confirm_save' => esc_html__( 'We need to save your progress to continue to the Marketing panel. Is that OK?', 'wpforms-lite' ),
'confirm_connection' => esc_html__( 'Are you sure you want to delete this connection?', 'wpforms-lite' ),
/* translators: %s - connection type. */
'prompt_connection' => esc_html( sprintf( __( 'Enter a %s nickname', 'wpforms-lite' ), '%type%' ) ),
'prompt_placeholder' => esc_html__( 'Eg: Newsletter Optin', 'wpforms-lite' ),
'error_name' => esc_html__( 'You must provide a connection nickname.', 'wpforms-lite' ),
'required_field' => esc_html__( 'Field required', 'wpforms-lite' ),
]
);
}
/**
* Output the Provider panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
$this->panel_sidebar_section( esc_html__( 'Default', 'wpforms-lite' ), 'default' );
do_action( 'wpforms_providers_panel_sidebar', $this->form );
}
/**
* Output the Provider panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
if ( ! $this->form ) {
// Check if there is a form created. When no form has been created
// yet let the user know we need a form to setup a provider.
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage these settings.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
// An array of all the active provider addons.
$providers_active = wpforms_get_providers_available();
if ( empty( $providers_active ) ) {
// Check for active provider addons. When no provider addons are
// activated let the user know they need to install/activate an
// addon to setup a provider.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-info">';
echo '<h5>' . esc_html__( 'Install Your Marketing Integration', 'wpforms-lite' ) . '</h5>';
echo '<p>' .
sprintf(
wp_kses(
/* translators: %s - plugin admin area Addons page. */
__( 'It seems you do not have any marketing addons activated. You can head over to the <a href="%s">Addons page</a> to install and activate the addon for your provider.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
],
]
),
esc_url( admin_url( 'admin.php?page=wpforms-addons' ) )
) .
'</p>';
echo '</div>';
} else {
// Everything is good - display default instructions.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-default">
<div class="illustration illustration-marketing"></div>
<h5>' . esc_html__( 'Select Your Marketing Integration', 'wpforms-lite' ) . '</h5>
<p>' . esc_html__( 'Select your email marketing service provider or CRM from the options on the left. If you don\'t see your email marketing service listed, then let us know and we\'ll do our best to get it added as fast as possible.', 'wpforms-lite' ) . '</p>
</div>';
}
do_action( 'wpforms_providers_panel_content', $this->form );
}
}
new WPForms_Builder_Panel_Providers();

View File

@@ -0,0 +1,192 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Revisions management panel.
*
* @since 1.7.3
*/
class WPForms_Builder_Panel_Revisions extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.7.3
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Revisions', 'wpforms-lite' );
$this->slug = 'revisions';
$this->icon = 'fa-history';
$this->order = 10;
$this->sidebar = true;
$this->hooks();
}
/**
* Hook into WordPress lifecycle.
*
* @since 1.7.3
*/
private function hooks() {
// Add a notice above all panels if revision is loaded.
add_action( 'wpforms_builder_panels', [ $this, 'panel_notice' ], 100, 2 );
}
/**
* Primary panel button in the left panel navigation.
*
* @since 1.7.3
*
* @param mixed $form The form object.
* @param string $view Current view/panel.
*/
public function button( $form, $view ) {
$classes = 'wpforms-panel-revisions-button';
if ( $view === $this->slug ) {
$classes .= ' active';
}
$badge = '';
if ( $this->form && ! wp_revisions_enabled( $this->form ) && ! wpforms()->get( 'revisions' )->panel_viewed() ) {
$badge = '
<span class="badge-exclamation">
<svg width="4" height="10" fill="none">
<path fill="#fff" fill-rule="evenodd" d="M3.5 8.1c0-.8-.7-1.5-1.5-1.5S.5 7.3.5 8.1 1.2 9.6 2 9.6 3.5 8.9 3.5 8ZM1 .9c-.3 0-.5.2-.4.4l.2 4.4c0 .2.2.3.4.3h1.6c.2 0 .3-.1.4-.3l.2-4.4c0-.2-.2-.4-.4-.4H1Z" clip-rule="evenodd"/>
</svg>
</span>';
}
printf(
'<div class="wpforms-panel-revisions-button-spacer"></div>
<button class="%1$s" data-panel="%2$s" title="%6$s">
%3$s
<i class="fa %4$s"></i>
<span class="screen-reader-text">%5$s</span>
</button>',
esc_attr( $classes ),
esc_attr( $this->slug ),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$badge,
esc_attr( $this->icon ),
esc_html( $this->name ),
esc_html__( 'Form Revisions', 'wpforms-lite' )
);
}
/**
* Output the Settings panel sidebar.
*
* @since 1.7.3
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
printf(
'<div class="wpforms-revisions-header">
<h3>%s</h3>
<p>%s</p>
</div>',
esc_html__( 'Form Revisions', 'wpforms-lite' ),
esc_html__( 'Select a revision to roll back to that version. All changes, including settings, will be reverted.', 'wpforms-lite' )
);
// Render a list of form revisions, including current version. All data is safe, escaped in the template.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo wpforms()->get( 'revisions' )->render_revisions_list();
$revisions_to_keep = wp_revisions_to_keep( $this->form );
if ( $revisions_to_keep === 0 ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo wpforms_render( 'builder/revisions/notice-disabled' );
}
if ( $revisions_to_keep > 0 ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo wpforms_render(
'builder/revisions/notice-limited',
[
'revisions_to_keep' => $revisions_to_keep,
],
true
);
}
}
/**
* Output revision notice above the panels.
*
* @since 1.7.3
*
* @return void
*/
public function panel_notice() {
$revision = wpforms()->get( 'revisions' )->get_revision();
if ( ! $revision ) {
return;
}
$restore_link = sprintf(
'<a href="%1$s">%2$s</a>',
esc_url(
wp_nonce_url(
wpforms()->get( 'revisions' )->get_url(
[
'revision_id' => $revision->ID,
'action' => 'restore_revision',
]
),
'restore_revision',
'wpforms_nonce'
)
),
__( 'Restore this revision', 'wpforms-lite' )
);
$back_link = sprintf(
'<a href="%1$s">%2$s</a>',
esc_url( wpforms()->get( 'revisions' )->get_url() ),
__( 'go back to the current version', 'wpforms-lite' )
);
$message = sprintf( /* translators: %1$s - revision date, %2$s - revision time, %3$s - "Restore this revision" link, %4$s - "go back to the current version" link. */
__( 'Youre currently viewing a form revision from %1$s at %2$s. %3$s or %4$s.', 'wpforms-lite' ),
wpforms()->get( 'revisions' )->get_formatted_datetime( $revision->post_modified_gmt ),
wpforms()->get( 'revisions' )->get_formatted_datetime( $revision->post_modified_gmt, 'time' ),
$restore_link,
$back_link
);
printf(
'<div class="wpforms-revision-notice">
<p><i class="fa fa-history"></i>%s</p>
</div>',
wp_kses(
$message,
[
'a' => [
'href' => [],
],
]
)
);
}
}
new WPForms_Builder_Panel_Revisions();

View File

@@ -0,0 +1,313 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use WPForms\Admin\Forms\Tags;
use WPForms\Forms\Akismet;
/**
* Settings management panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Settings extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Settings', 'wpforms-lite' );
$this->slug = 'settings';
$this->icon = 'fa-sliders';
$this->order = 10;
$this->sidebar = true;
}
/**
* Output the Settings panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
$sections = [
'general' => esc_html__( 'General', 'wpforms-lite' ),
'anti_spam' => esc_html__( 'Spam Protection and Security', 'wpforms-lite' ),
'notifications' => esc_html__( 'Notifications', 'wpforms-lite' ),
'confirmation' => esc_html__( 'Confirmations', 'wpforms-lite' ),
];
$sections = apply_filters( 'wpforms_builder_settings_sections', $sections, $this->form_data );
foreach ( $sections as $slug => $section ) {
$this->panel_sidebar_section( $section, $slug );
}
}
/**
* Enqueue assets.
*
* @since 1.7.5
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-settings',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/settings{$min}.js",
[ 'wpforms-builder' ],
WPFORMS_VERSION,
true
);
wp_localize_script(
'wpforms-builder-settings',
'wpforms_builder_settings',
[
'choicesjs_config' => $this->get_choicesjs_config(),
'all_tags_choices' => Tags::get_all_tags_choices(),
]
);
}
/**
* Get Choices.js configuration.
*
* @since 1.7.5
*
* @return array
*/
private function get_choicesjs_config() {
$config = Tags::get_choicesjs_config();
$config['noResultsText'] = esc_html__( 'Press Enter or "," key to add new tag', 'wpforms-lite' );
return $config;
}
/**
* Output the Settings panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
// Check if there is a form created.
if ( ! $this->form ) {
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage the settings.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
/*
* General.
*/
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-general">';
echo '<div class="wpforms-panel-content-section-title">';
esc_html_e( 'General', 'wpforms-lite' );
echo '</div>';
wpforms_panel_field(
'text',
'settings',
'form_title',
$this->form_data,
esc_html__( 'Form Name', 'wpforms-lite' ),
[
'default' => $this->form->post_title,
]
);
wpforms_panel_field(
'textarea',
'settings',
'form_desc',
$this->form_data,
esc_html__( 'Form Description', 'wpforms-lite' )
);
$this->general_setting_tags();
wpforms_panel_field(
'text',
'settings',
'submit_text',
$this->form_data,
esc_html__( 'Submit Button Text', 'wpforms-lite' ),
[
'default' => esc_html__( 'Submit', 'wpforms-lite' ),
]
);
wpforms_panel_field(
'text',
'settings',
'submit_text_processing',
$this->form_data,
esc_html__( 'Submit Button Processing Text', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enter the submit button text you would like the button display while the form submit is processing.', 'wpforms-lite' ),
]
);
$this->general_setting_advanced();
echo '</div>';
/*
* Notifications.
*/
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-notifications" data-panel="notifications">';
do_action( 'wpforms_form_settings_notifications', $this );
echo '</div>';
/*
* Confirmations.
*/
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-confirmation" data-panel="confirmations">';
do_action( 'wpforms_form_settings_confirmations', $this );
echo '</div>';
/*
* Custom panels can be added below.
*/
do_action( 'wpforms_form_settings_panel_content', $this );
}
/**
* Output the Tags setting.
*
* @since 1.7.5
*/
private function general_setting_tags() {
$form_tags = [];
if ( ! empty( $this->form_data['settings']['form_tags'] ) ) {
$form_tags = get_terms(
[
'taxonomy' => WPForms_Form_Handler::TAGS_TAXONOMY,
'name' => $this->form_data['settings']['form_tags'],
'hide_empty' => false,
]
);
$form_tags = is_wp_error( $form_tags ) ? [] : (array) $form_tags;
}
$tags_value = wp_list_pluck( $form_tags, 'term_id' );
$tags_options = wp_list_pluck( $form_tags, 'name', 'term_id' );
wpforms_panel_field(
'select',
'settings',
'form_tags',
$this->form_data,
esc_html__( 'Tags', 'wpforms-lite' ),
[
'options' => $tags_options,
'value' => $tags_value,
'multiple' => true,
'tooltip' => esc_html__( 'Mark form with the tags. To create a new tag, simply type it and press Enter.', 'wpforms-lite' ),
]
);
}
/**
* Output the *CAPTCHA settings.
*
* @since 1.6.8
*/
private function general_setting_advanced() {
ob_start();
wpforms_panel_field(
'text',
'settings',
'form_class',
$this->form_data,
esc_html__( 'Form CSS Class', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enter CSS class names for the form wrapper. Multiple class names should be separated with spaces.', 'wpforms-lite' ),
]
);
wpforms_panel_field(
'text',
'settings',
'submit_class',
$this->form_data,
esc_html__( 'Submit Button CSS Class', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enter CSS class names for the form submit button. Multiple names should be separated with spaces.', 'wpforms-lite' ),
]
);
wpforms_panel_field(
'toggle',
'settings',
'dynamic_population',
$this->form_data,
esc_html__( 'Enable Prefill by URL', 'wpforms-lite' ),
[
'tooltip' => sprintf(
'<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
wpforms_utm_link( 'https://wpforms.com/developers/how-to-enable-dynamic-field-population/', 'Builder Settings', 'Prefill by URL Tooltip' ),
esc_html__( 'How to use Prefill by URL', 'wpforms-lite' )
),
]
);
wpforms_panel_field(
'toggle',
'settings',
'ajax_submit',
$this->form_data,
esc_html__( 'Enable AJAX form submission', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enables form submission without page reload.', 'wpforms-lite' ),
]
);
do_action( 'wpforms_form_settings_general', $this );
// Wrap advanced settings to the unfoldable group.
wpforms_panel_fields_group(
ob_get_clean(),
[
'borders' => [ 'top' ],
'unfoldable' => true,
'group' => 'settings_advanced',
'title' => esc_html__( 'Advanced', 'wpforms-lite' ),
],
true
);
}
}
new WPForms_Builder_Panel_Settings();

View File

@@ -0,0 +1,103 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Setup panel.
*
* @since 1.0.0
* @since 1.6.8 Form Builder Refresh.
*/
class WPForms_Builder_Panel_Setup extends WPForms_Builder_Panel {
use \WPForms\Admin\Traits\FormTemplates;
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Setup', 'wpforms-lite' );
$this->slug = 'setup';
$this->icon = 'fa-cog';
$this->order = 5;
$this->addons_obj = wpforms()->get( 'addons' );
}
/**
* Enqueue assets for the Setup panel.
*
* @since 1.0.0
* @since 1.6.8 All the builder stylesheets enqueues moved to the `\WPForms_Builder::enqueues()`.
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-setup',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/setup{$min}.js",
[ 'wpforms-builder', 'listjs' ],
WPFORMS_VERSION,
true
);
}
/**
* Output the Settings panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
?>
<div id="wpforms-setup-form-name">
<label for="wpforms-setup-name"><?php esc_html_e( 'Name Your Form', 'wpforms-lite' ); ?></label>
<input type="text" id="wpforms-setup-name" placeholder="<?php esc_attr_e( 'Enter your form name here&hellip;', 'wpforms-lite' ); ?>">
</div>
<div class="wpforms-setup-title">
<?php esc_html_e( 'Select a Template', 'wpforms-lite' ); ?>
<span class="wpforms-setup-title-after"></span>
</div>
<p class="wpforms-setup-desc secondary-text">
<?php
printf(
wp_kses( /* translators: %1$s - create template doc link, %2$s - Contact us page link. */
__( 'To speed up the process you can select from one of our pre-made templates, start with a <a href="#" class="wpforms-trigger-blank">blank form</a> or <a href="%1$s" target="_blank" rel="noopener noreferrer">create your own</a>. Have a suggestion for a new template? <a href="%2$s" target="_blank" rel="noopener noreferrer">Wed love to hear it</a>!', 'wpforms-lite' ),
[
'strong' => [],
'a' => [
'href' => [],
'class' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-create-a-custom-form-template/', 'builder-templates', 'Create Your Own Template Documentation' ) ),
esc_url( wpforms_utm_link( 'https://wpforms.com/form-template-suggestion/', 'builder-templates', 'Suggest a Template' ) )
);
?>
</p>
<?php
$this->output_templates_content();
/**
* Fires after WPForms builder setup panel.
*
* @since 1.0.6
*/
do_action( 'wpforms_setup_panel_after' ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
}
}
new WPForms_Builder_Panel_Setup();