| Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/ |
| Current File : /home/x/b/o/xbodynamge/namtation/wp-content/class-base.php.tar |
home/xbodynamge/crosstraining/wp-content/plugins/wpforms-lite/includes/providers/class-base.php 0000604 00000101206 15112643566 0027303 0 ustar 00 <?php
/**
* Provider class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Provider {
/**
* Provider addon version.
*
* @since 1.0.0
*
* @var string
*/
protected $version;
/**
* Provider name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Provider name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Holds the API connections.
*
* @since 1.0.0
*
* @var mixed
*/
public $api = false;
/**
* Service icon.
*
* @since 1.0.0
*
* @var string
*/
public $icon;
/**
* Service icon.
*
* @since 1.2.3
*
* @var string
*/
public $type;
/**
* Form data and settings.
*
* @since 1.2.3
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->type = esc_html__( 'Connection', 'wpforms-lite' );
$this->init();
// Add to list of available providers.
add_filter( 'wpforms_providers_available', array( $this, 'register_provider' ), $this->priority, 1 );
// Process builder AJAX requests.
add_action( "wp_ajax_wpforms_provider_ajax_{$this->slug}", array( $this, 'process_ajax' ) );
// Process entry.
add_action( 'wpforms_process_complete', array( $this, 'process_entry' ), 5, 4 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_providers_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_providers_panel_content', array( $this, 'builder_output' ), $this->priority );
// Remove provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_disconnect', array( $this, 'integrations_tab_disconnect' ) );
// Add new provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_add', array( $this, 'integrations_tab_add' ) );
// Add providers sections to the Settings Integrations tab.
add_action( 'wpforms_settings_providers', array( $this, 'integrations_tab_options' ), $this->priority, 2 );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered providers.
*
* @since 1.0.0
*
* @param array $providers Array of all active providers.
*
* @return array
*/
public function register_provider( $providers = array() ) {
$providers[ $this->slug ] = $this->name;
return $providers;
}
/**
* Process the Builder AJAX requests.
*
* @since 1.0.0
*/
public function process_ajax() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
/*
* Create new connection.
*/
if ( 'new_connection' === $_POST['task'] ) {
$connection = $this->output_connection(
'',
array(
'connection_name' => stripslashes( $_POST['name'] ),
),
$_POST['id']
);
wp_send_json_success(
array(
'html' => $connection,
)
);
}
/*
* Create new Provider account.
*/
if ( 'new_account' === $_POST['task'] ) {
$auth = $this->api_auth( stripslashes_deep( wp_parse_args( $_POST['data'], array() ) ), $_POST['id'] );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => $auth->get_error_message(),
)
);
} else {
$accounts = $this->output_accounts(
$_POST['connection_id'],
array(
'account_id' => $auth,
)
);
wp_send_json_success(
array(
'html' => $accounts,
)
);
}
}
/*
* Select/Toggle Provider accounts.
*/
if ( 'select_account' === $_POST['task'] ) {
$lists = $this->output_lists(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
)
);
if ( is_wp_error( $lists ) ) {
wp_send_json_error(
array(
'error' => $lists->get_error_message(),
)
);
} else {
wp_send_json_success(
array(
'html' => $lists,
)
);
}
}
/*
* Select/Toggle Provider account lists.
*/
if ( 'select_list' === $_POST['task'] ) {
$fields = $this->output_fields( $_POST['connection_id'], array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
), $_POST['id'] );
if ( is_wp_error( $fields ) ) {
wp_send_json_error(
array(
'error' => $fields->get_error_message(),
)
);
} else {
$groups = $this->output_groups(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
)
);
$conditionals = $this->output_conditionals(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
),
array(
'id' => absint( $_POST['form_id'] ),
)
);
$options = $this->output_options(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
)
);
wp_send_json_success(
array(
'html' => $groups . $fields . $conditionals . $options,
)
);
}
}
die();
}
/**
* Process and submit entry to provider.
*
* @since 1.0.0
*
* @param array $fields List of fields in a form.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param int $entry_id Saved entry ID.
*/
public function process_entry( $fields, $entry, $form_data, $entry_id ) {
}
/**
* Process conditional fields.
*
* @since 1.0.0
*
* @param array $fields List of fields with their data and settings.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param array $connection List of connection settings.
*
* @return bool
*/
public function process_conditionals( $fields, $entry, $form_data, $connection ) {
if ( empty( $connection['conditional_logic'] ) || empty( $connection['conditionals'] ) ) {
return true;
}
$process = wpforms_conditional_logic()->process( $fields, $form_data, $connection['conditionals'] );
if ( ! empty( $connection['conditional_type'] ) && 'stop' === $connection['conditional_type'] ) {
$process = ! $process;
}
return $process;
}
/**
* Retrieve all available forms in a field.
*
* Not all fields should be available for merge tags so we compare against a
* white-list. Also some fields, such as Name, should have additional
* variations.
*
* @since 1.0.0
*
* @param object|bool $form
* @param array $whitelist
*
* @return bool|array
*/
public function get_form_fields( $form = false, $whitelist = array() ) {
// Accept form (post) object or form ID.
if ( is_object( $form ) ) {
$form = wpforms_decode( $form->post_content );
} elseif ( is_numeric( $form ) ) {
$form = wpforms()->form->get(
$form,
array(
'content_only' => true,
)
);
}
if ( ! is_array( $form ) || empty( $form['fields'] ) ) {
return false;
}
// White list of field types to allow.
$allowed_form_fields = array(
'text',
'textarea',
'select',
'radio',
'checkbox',
'email',
'address',
'url',
'name',
'hidden',
'date-time',
'phone',
'number',
);
$allowed_form_fields = apply_filters( 'wpforms_providers_fields', $allowed_form_fields );
$whitelist = ! empty( $whitelist ) ? $whitelist : $allowed_form_fields;
$form_fields = $form['fields'];
foreach ( $form_fields as $id => $form_field ) {
if ( ! in_array( $form_field['type'], $whitelist, true ) ) {
unset( $form_fields[ $id ] );
}
}
return $form_fields;
}
/**
* Get form fields ready for select list options.
*
* In this function we also do the logic to limit certain fields to certain
* provider field types.
*
* @since 1.0.0
*
* @param array $form_fields
* @param string $form_field_type
*
* @return array
*/
public function get_form_field_select( $form_fields = array(), $form_field_type = '' ) {
if ( empty( $form_fields ) || empty( $form_field_type ) ) {
return array();
}
$formatted = array();
// Include only specific field types.
foreach ( $form_fields as $id => $form_field ) {
// Email.
if (
'email' === $form_field_type &&
! in_array( $form_field['type'], array( 'text', 'email' ), true )
) {
unset( $form_fields[ $id ] );
}
// Address.
if (
'address' === $form_field_type &&
! in_array( $form_field['type'], array( 'address' ), true )
) {
unset( $form_fields[ $id ] );
}
}
// Format.
foreach ( $form_fields as $id => $form_field ) {
// Complex Name field.
if ( 'name' === $form_field['type'] ) {
// Full Name.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Full)', 'wpforms-lite' ),
$form_field['label']
),
);
// First Name.
if ( strpos( $form_field['format'], 'first' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'first',
'type' => $form_field['type'],
'subtype' => 'first',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (First)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Middle Name.
if ( strpos( $form_field['format'], 'middle' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'middle',
'type' => $form_field['type'],
'subtype' => 'middle',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Middle)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Last Name.
if ( strpos( $form_field['format'], 'last' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'last',
'type' => $form_field['type'],
'subtype' => 'last',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Last)', 'wpforms-lite' ),
$form_field['label']
),
);
}
} else {
// All other fields.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => $form_field['label'],
);
}
}
return $formatted;
}
/************************************************************************
* API methods - these methods interact directly with the provider API. *
************************************************************************/
/**
* Authenticate with the provider API.
*
* @since 1.0.0
*
* @param array $data
* @param string $form_id
*
* @return mixed id or error object
*/
public function api_auth( $data = array(), $form_id = '' ) {
}
/**
* Establish connection object to provider API.
*
* @since 1.0.0
*
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_connect( $account_id ) {
}
/**
* Retrieve provider account lists.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_lists( $connection_id = '', $account_id = '' ) {
}
/**
* Retrieve provider account list groups.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_groups( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/**
* Retrieve provider account list fields.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_fields( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/*************************************************************************
* Output methods - these methods generally return HTML for the builder. *
*************************************************************************/
/**
* Connection HTML.
*
* This method compiles all the HTML necessary for a connection to a provider.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form Form id or form data.
*
* @return string
*/
public function output_connection( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) ) {
$connection_id = 'connection_' . uniqid();
}
if ( empty( $connection ) || empty( $form ) ) {
return '';
}
$output = sprintf( '<div class="wpforms-provider-connection" data-provider="%s" data-connection_id="%s">', $this->slug, $connection_id );
$output .= $this->output_connection_header( $connection_id, $connection );
$output .= $this->output_auth();
$output .= $this->output_accounts( $connection_id, $connection );
$lists = $this->output_lists( $connection_id, $connection );
$output .= ! is_wp_error( $lists ) ? $lists : '';
$output .= $this->output_groups( $connection_id, $connection );
$fields = $this->output_fields( $connection_id, $connection, $form );
$output .= ! is_wp_error( $fields ) ? $fields : '';
$output .= $this->output_conditionals( $connection_id, $connection, $form );
$output .= $this->output_options( $connection_id, $connection );
$output .= '</div>';
return $output;
}
/**
* Connection header HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_connection_header( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$output = '<div class="wpforms-provider-connection-header">';
$output .= sprintf( '<span>%s</span>', sanitize_text_field( $connection['connection_name'] ) );
$output .= '<button class="wpforms-provider-connection-delete"><i class="fa fa-times-circle"></i></button>';
$output .= sprintf( '<input type="hidden" name="providers[%s][%s][connection_name]" value="%s">', $this->slug, $connection_id, esc_attr( $connection['connection_name'] ) );
$output .= '</div>';
return $output;
}
/**
* Provider account authorize fields HTML.
*
* @since 1.0.0
*
* @return mixed
*/
public function output_auth() {
}
/**
* Provider account select HTML.
*
* @since 1.0.0
*
* @param string $connection_id Unique connection ID.
* @param array $connection Array of connection data.
*
* @return string
*/
public function output_accounts( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$providers = wpforms_get_providers_options();
if ( empty( $providers[ $this->slug ] ) ) {
return '';
}
$output = '<div class="wpforms-provider-accounts wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Account', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][account_id]">', $this->slug, $connection_id );
foreach ( $providers[ $this->slug ] as $key => $provider_details ) {
$selected = ! empty( $connection['account_id'] ) ? $connection['account_id'] : '';
$output .= sprintf(
'<option value="%s" %s>%s</option>',
$key,
selected( $selected, $key, false ),
esc_html( $provider_details['label'] )
);
}
$output .= sprintf( '<option value="">%s</a>', esc_html__( 'Add New Account', 'wpforms-lite' ) );
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account lists HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return WP_Error|string
*/
public function output_lists( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) ) {
return '';
}
$lists = $this->api_lists( $connection_id, $connection['account_id'] );
$selected = ! empty( $connection['list_id'] ) ? $connection['list_id'] : '';
if ( is_wp_error( $lists ) ) {
return $lists;
}
$output = '<div class="wpforms-provider-lists wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select List', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][list_id]">', $this->slug, $connection_id );
if ( ! empty( $lists ) ) {
foreach ( $lists as $list ) {
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $list['id'] ),
selected( $selected, $list['id'], false ),
esc_attr( $list['name'] )
);
}
}
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account list groups HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_groups( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) ) {
return '';
}
$groupsets = $this->api_groups( $connection_id, $connection['account_id'], $connection['list_id'] );
if ( is_wp_error( $groupsets ) ) {
return '';
}
$output = '<div class="wpforms-provider-groups wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Groups', 'wpforms-lite' ) );
$output .= sprintf( '<p>%s</p>', esc_html__( 'We also noticed that you have some segments in your list. You can select specific list segments below if needed. This is optional.', 'wpforms-lite' ) );
$output .= '<div class="wpforms-provider-groups-list">';
foreach ( $groupsets as $groupset ) {
$output .= sprintf( '<p>%s</p>', esc_html( $groupset['name'] ) );
foreach ( $groupset['groups'] as $group ) {
$selected = ! empty( $connection['groups'] ) && ! empty( $connection['groups'][ $groupset['id'] ] ) ? in_array( $group['name'], $connection['groups'][ $groupset['id'] ], true ) : false;
$output .= sprintf(
'<span><input id="group_%s" type="checkbox" value="%s" name="providers[%s][%s][groups][%s][%s]" %s><label for="group_%s">%s</label></span>',
esc_attr( $group['id'] ),
esc_attr( $group['name'] ),
$this->slug,
$connection_id,
$groupset['id'],
$group['id'],
checked( $selected, true, false ),
esc_attr( $group['id'] ),
esc_attr( $group['name'] )
);
}
}
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* Provider account list fields HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form
*
* @return WP_Error|string
*/
public function output_fields( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) || empty( $form ) ) {
return '';
}
$provider_fields = $this->api_fields( $connection_id, $connection['account_id'], $connection['list_id'] );
$form_fields = $this->get_form_fields( $form );
if ( is_wp_error( $provider_fields ) ) {
return $provider_fields;
}
$output = '<div class="wpforms-provider-fields wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'List Fields', 'wpforms-lite' ) );
// Table with all the fields.
$output .= '<table>';
$output .= sprintf( '<thead><tr><th>%s</th><th>%s</th></thead>', esc_html__( 'List Fields', 'wpforms-lite' ), esc_html__( 'Available Form Fields', 'wpforms-lite' ) );
$output .= '<tbody>';
foreach ( $provider_fields as $provider_field ) :
$output .= '<tr>';
$output .= '<td>';
$output .= esc_html( $provider_field['name'] );
if (
! empty( $provider_field['req'] ) &&
$provider_field['req'] == '1'
) {
$output .= '<span class="required">*</span>';
}
$output .= '<td>';
$output .= sprintf( '<select name="providers[%s][%s][fields][%s]">', $this->slug, $connection_id, esc_attr( $provider_field['tag'] ) );
$output .= '<option value=""></option>';
$options = $this->get_form_field_select( $form_fields, $provider_field['field_type'] );
foreach ( $options as $option ) {
$value = sprintf( '%d.%s.%s', $option['id'], $option['key'], $option['provider_type'] );
$selected = ! empty( $connection['fields'][ $provider_field['tag'] ] ) ? selected( $connection['fields'][ $provider_field['tag'] ], $value, false ) : '';
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $value ), $selected, esc_html( $option['label'] ) );
}
$output .= '</select>';
$output .= '</td>';
$output .= '</tr>';
endforeach;
$output .= '</tbody>';
$output .= '</table>';
$output .= '</div>';
return $output;
}
/**
* Provider connection conditional options HTML
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param string|array $form
*
* @return string
*/
public function output_conditionals( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection['account_id'] ) ) {
return '';
}
return wpforms_conditional_logic()->builder_block(
array(
'form' => $this->form_data,
'type' => 'panel',
'panel' => $this->slug,
'parent' => 'providers',
'subsection' => $connection_id,
'reference' => esc_html__( 'Marketing provider connection', 'wpforms-lite' ),
),
false
);
}
/**
* Provider account list options HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_options( $connection_id = '', $connection = array() ) {
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.2.3
*/
public function builder_form_data() {
if ( ! empty( $_GET['form_id'] ) && empty( $this->form_data ) ) {
$this->form_data = wpforms()->form->get(
absint( $_GET['form_id'] ),
array(
'content_only' => true,
)
);
}
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
$form_data = $this->form_data;
$providers = wpforms_get_providers_options();
if ( ! empty( $form_data['providers'][ $this->slug ] ) && ! empty( $providers[ $this->slug ] ) ) {
foreach ( $form_data['providers'][ $this->slug ] as $connection_id => $connection ) {
foreach ( $providers[ $this->slug ] as $account_id => $connections ) {
if (
! empty( $connection['account_id'] ) &&
$connection['account_id'] === $account_id
) {
echo $this->output_connection( $connection_id, $connection, $form_data );
}
}
}
}
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$form_data = $this->form_data;
$configured = ! empty( $form_data['providers'][ $this->slug ] ) ? 'configured' : '';
$configured = apply_filters( 'wpforms_providers_' . $this->slug . '_configured', $configured );
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . esc_attr( $configured ) . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<?php $this->builder_output_before(); ?>
<div class="wpforms-panel-content-section-title">
<?php echo $this->name; ?>
<button class="wpforms-provider-connections-add" data-form_id="<?php echo absint( $_GET['form_id'] ); ?>"
data-provider="<?php echo esc_attr( $this->slug ); ?>"
data-type="<?php echo esc_attr( strtolower( $this->type ) ); ?>">
<?php
printf(
/* translators: %s - Provider type. */
esc_html__( 'Add New %s', 'wpforms-lite' ),
esc_html( $this->type )
);
?>
</button>
</div>
<div class="wpforms-provider-connections-wrap wpforms-clear">
<div class="wpforms-provider-connections">
<?php $this->builder_content(); ?>
</div>
</div>
<?php $this->builder_output_after(); ?>
</div>
<?php
}
/**
* Optionally output content before the main builder output.
*
* @since 1.3.6
*/
public function builder_output_before() {
}
/**
* Optionally output content after the main builder output.
*
* @since 1.3.6
*/
public function builder_output_after() {
}
/*************************************************************************
* Integrations tab methods - these methods relate to the settings page. *
*************************************************************************/
/**
* Form fields to add a new provider account.
*
* @since 1.0.0
*/
public function integrations_tab_new_form() {
}
/**
* AJAX to disconnect a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_disconnect() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['provider'] ) || empty( $_POST['key'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$providers = wpforms_get_providers_options();
if ( ! empty( $providers[ $_POST['provider'] ][ $_POST['key'] ] ) ) {
unset( $providers[ $_POST['provider'] ][ $_POST['key'] ] );
update_option( 'wpforms_providers', $providers );
wp_send_json_success();
} else {
wp_send_json_error(
array(
'error' => esc_html__( 'Connection missing', 'wpforms-lite' ),
)
);
}
}
/**
* AJAX to add a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_add() {
if ( $_POST['provider'] !== $this->slug ) { //phpcs:ignore
return;
}
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['data'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$data = wp_parse_args( $_POST['data'], array() );
$auth = $this->api_auth( $data, '' );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Could not connect to the provider.', 'wpforms-lite' ),
'error_msg' => $auth->get_error_message(),
)
);
} else {
$account = '<li>';
$account .= '<span class="label">' . sanitize_text_field( $data['label'] ) . '</span>';
/* translators: %s - Connection date. */
$account .= '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format', time() ) ) ) . '</span>';
$account .= '<a href="#" data-provider="' . $this->slug . '" data-key="' . esc_attr( $auth ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a>';
$account .= '</li>';
wp_send_json_success(
array(
'html' => $account,
)
);
}
}
/**
* Add provider to the Settings Integrations tab.
*
* @since 1.0.0
*
* @param array $active Array of active connections.
* @param array $settings Array of all connections settings.
*/
public function integrations_tab_options( $active, $settings ) {
$connected = ! empty( $active[ $this->slug ] );
$accounts = ! empty( $settings[ $this->slug ] ) ? $settings[ $this->slug ] : array();
$class = $connected && $accounts ? 'connected' : '';
$arrow = 'right';
/* translators: %s - provider name. */
$title_connect_to = sprintf( esc_html__( 'Connect to %s', 'wpforms-lite' ), esc_html( $this->name ) );
// This lets us highlight a specific service by a special link.
if ( ! empty( $_GET['wpforms-integration'] ) ) { //phpcs:ignore
if ( $this->slug === $_GET['wpforms-integration'] ) { //phpcs:ignore
$class .= ' focus-in';
$arrow = 'down';
} else {
$class .= ' focus-out';
}
}
?>
<div id="wpforms-integration-<?php echo esc_attr( $this->slug ); ?>" class="wpforms-settings-provider wpforms-clear <?php echo esc_attr( $this->slug ); ?> <?php echo esc_attr( $class ); ?>">
<div class="wpforms-settings-provider-header wpforms-clear" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-logo">
<i title="<?php esc_attr_e( 'Show Accounts', 'wpforms-lite' ); ?>" class="fa fa-chevron-<?php echo esc_attr( $arrow ); ?>"></i>
<img src="<?php echo esc_url( $this->icon ); ?>">
</div>
<div class="wpforms-settings-provider-info">
<h3><?php echo esc_html( $this->name ); ?></h3>
<p>
<?php
/* translators: %s - provider name. */
printf( esc_html__( 'Integrate %s with WPForms', 'wpforms-lite' ), esc_html( $this->name ) );
?>
</p>
<span class="connected-indicator green"><i class="fa fa-check-circle-o"></i> <?php esc_html_e( 'Connected', 'wpforms-lite' ); ?></span>
</div>
</div>
<div class="wpforms-settings-provider-accounts" id="provider-<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-accounts-list">
<ul>
<?php
if ( ! empty( $accounts ) ) {
foreach ( $accounts as $key => $account ) {
echo '<li class="wpforms-clear">';
echo '<span class="label">' . esc_html( $account['label'] ) . '</span>';
/* translators: %s - Connection date. */
echo '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format' ), intval( $account['date'] ) ) ) . '</span>';
echo '<span class="remove"><a href="#" data-provider="' . esc_attr( $this->slug ) . '" data-key="' . esc_attr( $key ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a></span>';
echo '</li>';
}
}
?>
</ul>
</div>
<p class="wpforms-settings-provider-accounts-toggle">
<a class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey" href="#" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<i class="fa fa-plus"></i> <?php esc_html_e( 'Add New Account', 'wpforms-lite' ); ?>
</a>
</p>
<div class="wpforms-settings-provider-accounts-connect">
<form>
<p><?php esc_html_e( 'Please fill out all of the fields below to add your new provider account.', 'wpforms-lite' ); ?></span></p>
<p class="wpforms-settings-provider-accounts-connect-fields">
<?php $this->integrations_tab_new_form(); ?>
</p>
<button type="submit" class="wpforms-btn wpforms-btn-md wpforms-btn-orange wpforms-settings-provider-connect"
data-provider="<?php echo esc_attr( $this->slug ); ?>" title="<?php echo esc_attr( $title_connect_to ); ?>">
<?php echo esc_html( $title_connect_to ); ?>
</button>
</form>
</div>
</div>
</div>
<?php
}
/**
* Error wrapper for WP_Error.
*
* @since 1.0.0
*
* @param string $message
* @param string $parent
*
* @return WP_Error
*/
public function error( $message = '', $parent = '0' ) {
return new WP_Error( $this->slug . '-error', $message );
}
}
home/xbodynamge/crosstraining/wp-content/plugins/wpforms-lite/includes/templates/class-base.php 0000604 00000010547 15112644131 0027260 0 ustar 00 <?php
/**
* Base form template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Template {
/**
* Full name of the template, eg "Contact Form".
*
* @since 1.0.0
* @var string
*/
public $name;
/**
* Slug of the template, eg "contact-form" - no spaces.
*
* @since 1.0.0
* @var string
*/
public $slug;
/**
* Short description the template.
*
* @since 1.0.0
* @var string
*/
public $description = '';
/**
* Short description of the fields included with the template.
*
* @since 1.0.0
* @var string
*/
public $includes = '';
/**
* URL of the icon to display in the admin area.
*
* @since 1.0.0
* @var string
*/
public $icon = '';
/**
* Array of data that is assigned to the post_content on form creation.
*
* @since 1.0.0
* @var array
*/
public $data;
/**
* Priority to show in the list of available templates.
*
* @since 1.0.0
* @var int
*/
public $priority = 20;
/**
* Core or additional template.
*
* @since 1.4.0
* @var bool
*/
public $core = false;
/**
* Modal message to display when the template is applied.
*
* @since 1.0.0
* @var array
*/
public $modal = '';
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Bootstrap.
$this->init();
$type = $this->core ? '_core' : '';
add_filter( "wpforms_form_templates{$type}", array( $this, 'template_details' ), $this->priority );
add_filter( 'wpforms_create_form_args', array( $this, 'template_data' ), 10, 2 );
add_filter( 'wpforms_save_form_args', array( $this, 'template_replace' ), 10, 3 );
add_filter( 'wpforms_builder_template_active', array( $this, 'template_active' ), 10, 2 );
}
/**
* Let's get started.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add basic template details to the Add New Form admin screen.
*
* @since 1.0.0
*
* @param array $templates
*
* @return array
*/
public function template_details( $templates ) {
$templates[] = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
);
return $templates;
}
/**
* Add template data when form is created.
*
* @since 1.0.0
*
* @param array $args
* @param array $data
*
* @return array
*/
public function template_data( $args, $data ) {
if ( ! empty( $data ) && ! empty( $data['template'] ) ) {
if ( $data['template'] === $this->slug ) {
$args['post_content'] = wpforms_encode( $this->data );
}
}
return $args;
}
/**
* Replace template on post update if triggered.
*
* @since 1.0.0
*
* @param array $form
* @param array $data
* @param array $args
*
* @return array
*/
public function template_replace( $form, $data, $args ) {
if ( ! empty( $args['template'] ) ) {
if ( $args['template'] === $this->slug ) {
$new = $this->data;
$new['settings'] = ! empty( $form['post_content']['settings'] ) ? $form['post_content']['settings'] : array();
$form['post_content'] = wpforms_encode( $new );
}
}
return $form;
}
/**
* Pass information about the active template back to the builder.
*
* @since 1.0.0
*
* @param array $details
* @param object $form
*
* @return array
*/
public function template_active( $details, $form ) {
if ( empty( $form ) ) {
return;
}
$form_data = wpforms_decode( $form->post_content );
if ( empty( $this->modal ) || empty( $form_data['meta']['template'] ) || $this->slug !== $form_data['meta']['template'] ) {
return $details;
} else {
$display = $this->template_modal_conditional( $form_data );
}
$template = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
'modal' => $this->modal,
'modal_display' => $display,
);
return $template;
}
/**
* Conditional to determine if the template informational modal screens
* should display.
*
* @since 1.0.0
*
* @param array $form_data Form data and settings.
*
* @return boolean
*/
public function template_modal_conditional( $form_data ) {
return false;
}
}
home/xbodynamge/crosstraining/wp-content/plugins/wpforms-lite/includes/fields/class-base.php 0000604 00000161025 15112661670 0026535 0 ustar 00 <?php
/**
* Base field template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Field {
/**
* Full name of the field type, eg "Paragraph Text".
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Type of the field, eg "textarea".
*
* @since 1.0.0
*
* @var string
*/
public $type;
/**
* 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 integer
*/
public $order = 1;
/**
* Field group the field belongs to.
*
* @since 1.0.0
*
* @var string
*/
public $group = 'standard';
/**
* Placeholder to hold default value(s) for some field types.
*
* @since 1.0.0
*
* @var mixed
*/
public $defaults;
/**
* Current form ID in the admin builder.
*
* @since 1.1.1
*
* @var int|bool
*/
public $form_id;
/**
* Current form data in.
*
* @since 1.1.1
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*
* @param bool $init Pass false to allow to shortcut the whole initialization, if needed.
*/
public function __construct( $init = true ) {
if ( ! $init ) {
return;
}
// The form ID is to be accessed in the builder.
$this->form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
// Bootstrap.
$this->init();
// Add fields tab.
add_filter( 'wpforms_builder_fields_buttons', array( $this, 'field_button' ), 15 );
// Field options tab.
add_action( "wpforms_builder_fields_options_{$this->type}", array( $this, 'field_options' ), 10 );
// Preview fields.
add_action( "wpforms_builder_fields_previews_{$this->type}", array( $this, 'field_preview' ), 10 );
// AJAX Add new field.
add_action( "wp_ajax_wpforms_new_field_{$this->type}", array( $this, 'field_new' ) );
// Display field input elements on front-end.
add_action( "wpforms_display_field_{$this->type}", array( $this, 'field_display' ), 10, 3 );
// Validation on submit.
add_action( "wpforms_process_validate_{$this->type}", array( $this, 'validate' ), 10, 3 );
// Format.
add_action( "wpforms_process_format_{$this->type}", array( $this, 'format' ), 10, 3 );
// Prefill.
add_filter( 'wpforms_field_properties', array( $this, 'field_prefill_value_property' ), 10, 3 );
}
/**
* All systems go. Used by subclasses. Required.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*/
abstract public function init();
/**
* Prefill field value with either fallback or dynamic data.
* Needs to be public (although internal) to be used in WordPress hooks.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
* @param array $form_data Prepared form data/settings.
*
* @return array Modified field properties.
*/
public function field_prefill_value_property( $properties, $field, $form_data ) {
// Process only for current field.
if ( $this->type !== $field['type'] ) {
return $properties;
}
// Set the form data, so we can reuse it later, even on front-end.
$this->form_data = $form_data;
// Dynamic data.
if ( ! empty( $this->form_data['settings']['dynamic_population'] ) ) {
$properties = $this->field_prefill_value_property_dynamic( $properties, $field );
}
// Fallback data, rewrites dynamic because user-submitted data is more important.
$properties = $this->field_prefill_value_property_fallback( $properties, $field );
return $properties;
}
/**
* As we are processing user submitted data - ignore all admin-defined defaults.
* Preprocess choices-related fields only.
*
* @since 1.5.0
*
* @param array $field Field data and settings.
* @param array $properties Properties we are modifying.
*/
protected function field_prefill_remove_choices_defaults( $field, &$properties ) {
if (
! empty( $field['dynamic_choices'] ) ||
! empty( $field['choices'] )
) {
array_walk_recursive(
$properties['inputs'],
function ( &$value, $key ) {
if ( 'default' === $key ) {
$value = false;
}
}
);
}
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_dynamic_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
// For dynamic population we require $_GET.
if ( empty( $_GET ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_dynamic_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a dynamic value, that we get from $_GET.
* The pattern is: wpf4_12_primary, where:
* 4 - form_id,
* 12 - field_id,
* first - input key.
* As 'primary' is our default input key, "wpf4_12_primary" and "wpf4_12" are the same.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_dynamic( $properties, $field ) {
if ( ! $this->is_dynamic_population_allowed( $properties, $field ) ) {
return $properties;
}
// Iterate over each GET key, parse, and scrap data from there.
foreach ( $_GET as $key => $raw_value ) { // phpcs:ignore
preg_match( '/wpf(\d+)_(\d+)(.*)/i', $key, $matches );
if ( empty( $matches ) || ! is_array( $matches ) ) {
continue;
}
// Required.
$form_id = absint( $matches[1] );
$field_id = absint( $matches[2] );
$input = 'primary';
// Optional.
if ( ! empty( $matches[3] ) ) {
$input = sanitize_key( trim( $matches[3], '_' ) );
}
// Both form and field IDs should be the same as current form/field.
if (
(int) $this->form_data['id'] !== $form_id ||
(int) $field['id'] !== $field_id
) {
// Go to the next GET param.
continue;
}
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* Some fields (like checkboxes) support multiple selection.
* We do not support nested values, so omit them.
* Example: ?wpf771_19_wpforms[fields][19][address1]=test
* In this case:
* $input = wpforms
* $raw_value = [fields=>[]]
* $single_value = [19=>[]]
* There is no reliable way to clean those things out.
* So we will ignore the value altogether if it's an array.
* We support only single value numeric arrays, like these:
* ?wpf771_19[]=test1&wpf771_19[]=test2
* ?wpf771_19_value[]=test1&wpf771_19_value[]=test2
* ?wpf771_41_r3_c2[]=1&wpf771_41_r1_c4[]=1
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, $input, $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, $input, $properties, $field );
}
}
return $properties;
}
/**
* Get the value, that is used to prefill via dynamic or fallback population.
* Based on field data and current properties.
*
* @since 1.5.0
*
* @param string $raw_value Value from a GET param, always a string.
* @param string $input Represent a subfield inside the field. May be empty.
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function get_field_populated_single_property_value( $raw_value, $input, $properties, $field ) {
if ( ! is_string( $raw_value ) ) {
return $properties;
}
$get_value = stripslashes( sanitize_text_field( $raw_value ) );
// For fields that have dynamic choices we need to add extra logic.
if ( ! empty( $field['dynamic_choices'] ) ) {
$default_key = null;
foreach ( $properties['inputs'] as $input_key => $input_arr ) {
// Dynamic choices support only integers in its values.
if ( absint( $get_value ) === $input_arr['attr']['value'] ) {
$default_key = $input_key;
// Stop iterating over choices.
break;
}
}
// Redefine default choice only if dynamic value has changed anything.
if ( null !== $default_key ) {
foreach ( $properties['inputs'] as $input_key => $choice_arr ) {
if ( $input_key === $default_key ) {
$properties['inputs'][ $input_key ]['default'] = true;
// Stop iterating over choices.
break;
}
}
}
} elseif ( ! empty( $field['choices'] ) && is_array( $field['choices'] ) ) {
$default_key = null;
// For fields that have normal choices we need to add extra logic.
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( isset( $field['show_values'] ) ) {
if (
isset( $choice_arr['value'] ) &&
strtoupper( $choice_arr['value'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
} else {
if (
isset( $choice_arr['label'] ) &&
strtoupper( $choice_arr['label'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
}
}
// Redefine default choice only if population value has changed anything.
if ( null !== $default_key ) {
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( $choice_key === $default_key ) {
$properties['inputs'][ $choice_key ]['default'] = true;
break;
}
}
}
} else {
/*
* For other types of fields we need to check that
* the key is registered for the defined field in inputs array.
*/
if (
! empty( $input ) &&
isset( $properties['inputs'][ $input ] )
) {
$properties['inputs'][ $input ]['attr']['value'] = $get_value;
}
}
return $properties;
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_fallback_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
/*
* Commented out to allow partial fail for complex multi-inputs fields.
* Example: name field with first/last format and being required, filled out only first.
* On submit we will preserve those sub-inputs that are not empty and display an error for an empty.
*/
// Do not populate if there are errors for that field.
/*
$errors = wpforms()->process->errors;
if ( ! empty( $errors[ $this->form_data['id'] ][ $field['id'] ] ) ) {
$allowed = false;
}
*/
// Require form id being the same for submitted and currently rendered form.
if (
! empty( $_POST['wpforms']['id'] ) && // phpcs:ignore
(int) $_POST['wpforms']['id'] !== (int) $this->form_data['id'] // phpcs:ignore
) {
$allowed = false;
}
// Require $_POST of submitted field.
if ( empty( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
$allowed = false;
}
// Require field (processed and rendered) being the same.
if ( ! isset( $_POST['wpforms']['fields'][ $field['id'] ] ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_fallback_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a fallback value from form submission (in case of JS validation failed), that we get from $_POST.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_fallback( $properties, $field ) {
if ( ! $this->is_fallback_population_allowed( $properties, $field ) ) {
return $properties;
}
if ( empty( $_POST['wpforms']['fields'] ) || ! is_array( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
return $properties;
}
// We got user submitted raw data (not processed, will be done later).
$raw_value = $_POST['wpforms']['fields'][ $field['id'] ]; // phpcs:ignore
$input = 'primary';
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* For this particular field this value may be either array or a string.
* In array - this is a complex field, like address.
* The key in array will be a sub-input (address1, state), and its appropriate value.
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $input => $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, sanitize_key( $input ), $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, sanitize_key( $input ), $properties, $field );
}
return $properties;
}
/**
* Create the button for the 'Add Fields' tab, inside the form editor.
*
* @since 1.0.0
*
* @param array $fields List of form fields with their data.
*
* @return array
*/
public function field_button( $fields ) {
// Add field information to fields array.
$fields[ $this->group ]['fields'][] = array(
'order' => $this->order,
'name' => $this->name,
'type' => $this->type,
'icon' => $this->icon,
);
// Wipe hands clean.
return $fields;
}
/**
* Creates the field options panel. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_options( $field );
/**
* Creates the field preview. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_preview( $field );
/**
* Helper function to create field option elements.
*
* Field option elements are pieces that help create a field option.
* They are used to quickly build field options.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_element( $option, $field, $args = array(), $echo = true ) {
$id = (int) $field['id'];
$class = ! empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
$slug = ! empty( $args['slug'] ) ? sanitize_title( $args['slug'] ) : '';
$data = '';
$output = '';
if ( ! empty( $args['data'] ) ) {
foreach ( $args['data'] as $arg_key => $val ) {
if ( is_array( $val ) ) {
$val = wp_json_encode( $val );
}
$data .= ' data-' . $arg_key . '=\'' . $val . '\'';
}
}
switch ( $option ) {
// Row.
case 'row':
$output = sprintf(
'<div class="wpforms-field-option-row wpforms-field-option-row-%s %s" id="wpforms-field-option-row-%d-%s" data-field-id="%d">%s</div>',
$slug,
$class,
$id,
$slug,
$id,
$args['content']
);
break;
// Label.
case 'label':
$output = sprintf( '<label for="wpforms-field-option-%d-%s">%s', $id, $slug, esc_html( $args['value'] ) );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
if ( isset( $args['after_tooltip'] ) && ! empty( $args['after_tooltip'] ) ) {
$output .= $args['after_tooltip'];
}
$output .= '</label>';
break;
// Text input.
case 'text':
$type = ! empty( $args['type'] ) ? esc_attr( $args['type'] ) : 'text';
$placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : '';
$before = ! empty( $args['before'] ) ? '<span class="before-input">' . esc_html( $args['before'] ) . '</span>' : '';
if ( ! empty( $before ) ) {
$class .= ' has-before';
}
$output = sprintf( '%s<input type="%s" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="%s" placeholder="%s" %s>', $before, $type, $class, $id, $slug, $id, $slug, esc_attr( $args['value'] ), $placeholder, $data );
break;
// Textarea.
case 'textarea':
$rows = ! empty( $args['rows'] ) ? (int) $args['rows'] : '3';
$output = sprintf( '<textarea class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" rows="%d" %s>%s</textarea>', $class, $id, $slug, $id, $slug, $rows, $data, $args['value'] );
break;
// Checkbox.
case 'checkbox':
$checked = checked( '1', $args['value'], false );
$output = sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s>', $class, $id, $slug, $id, $slug, $checked, $data );
$output .= sprintf( '<label for="wpforms-field-option-%d-%s" class="inline">%s', $id, $slug, $args['desc'] );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
$output .= '</label>';
break;
// Toggle.
case 'toggle':
$checked = checked( '1', $args['value'], false );
$icon = $args['value'] ? 'fa-toggle-on' : 'fa-toggle-off';
$cls = $args['value'] ? 'wpforms-on' : 'wpforms-off';
$status = $args['value'] ? esc_html__( 'On', 'wpforms-lite' ) : esc_html__( 'Off', 'wpforms-lite' );
$output = sprintf( '<span class="wpforms-toggle-icon %s"><i class="fa %s" aria-hidden="true"></i> <span class="wpforms-toggle-icon-label">%s</span>', $cls, $icon, $status );
$output .= sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s></span>', $class, $id, $slug, $id, $slug, $checked, $data );
break;
// Select.
case 'select':
$options = $args['options'];
$value = isset( $args['value'] ) ? $args['value'] : '';
$output = sprintf( '<select class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" %s>', $class, $id, $slug, $id, $slug, $data );
foreach ( $options as $arg_key => $arg_option ) {
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $arg_key ), selected( $arg_key, $value, false ), $arg_option );
}
$output .= '</select>';
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Helper function to create common field options that are used frequently.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_option( $option, $field, $args = array(), $echo = true ) {
switch ( $option ) {
/**
* Basic Fields.
*/
/*
* Basic Options markup.
*/
case 'basic-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
if ( 'open' === $markup ) {
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-basic" id="wpforms-field-option-basic-%d">', $field['id'] );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <span>(ID #%d)</span> <i class="fa fa-angle-down"></i></a>', $this->name, $field['id'] );
$output .= sprintf( '<div class="wpforms-field-option-group-inner %s">', $class );
} else {
$output = '</div></div>';
}
break;
/*
* Field Label.
*/
case 'label':
$value = ! empty( $field['label'] ) ? esc_attr( $field['label'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field label. Field labels are recommended and can be hidden in the Advanced Settings.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'label', 'value' => esc_html__( 'Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'label', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label', 'content' => $output ), false );
break;
/*
* Field Description.
*/
case 'description':
$value = ! empty( $field['description'] ) ? esc_attr( $field['description'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field description.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'description', 'value' => esc_html__( 'Description', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'description', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'description', 'content' => $output ), false );
break;
/*
* Field Required toggle.
*/
case 'required':
$default = ! empty( $args['default'] ) ? $args['default'] : '0';
$value = isset( $field['required'] ) ? $field['required'] : $default;
$tooltip = esc_html__( 'Check this option to mark the field required. A form will not submit unless all required fields are provided.', 'wpforms-lite' );
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'required', 'value' => $value, 'desc' => esc_html__( 'Required', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'required', 'content' => $output ), false );
break;
/*
* Field Meta (field type and ID).
*/
case 'meta':
$output = sprintf( '<label>%s</label>', 'Type' );
$output .= sprintf( '<p class="meta">%s <span class="id">(ID #%d)</span></p>', $this->name, $field['id'] );
$output = $this->field_element( 'row', $field, array( 'slug' => 'meta', 'content' => $output ), false );
break;
/*
* Code Block.
*/
case 'code':
$value = ! empty( $field['code'] ) ? esc_textarea( $field['code'] ) : '';
$tooltip = esc_html__( 'Enter code for the form field.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'code', 'value' => esc_html__( 'Code', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'code', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'code', 'content' => $output ), false );
break;
/*
* Choices.
*/
case 'choices':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$label = ! empty( $args['label'] ) ? esc_html( $args['label'] ) : esc_html__( 'Choices', 'wpforms-lite' );
$class = array();
if ( ! empty( $field['show_values'] ) ) {
$class[] = 'show-values';
}
if ( ! empty( $field['dynamic_choices'] ) ) {
$class[] = 'wpforms-hidden';
}
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => $label,
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
'after_tooltip' => '<a href="#" class="toggle-bulk-add-display"><i class="fa fa-download"></i> <span>' . esc_html__( 'Bulk Add', 'wpforms-lite' ) . '</span></a>',
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="%s" name="%s[default]" class="default" value="1" %s>',
'checkbox' === $this->type ? 'checkbox' : 'radio',
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value">',
$base,
esc_attr( $value['value'] )
);
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Field note: dynamic status.
$source = '';
$type = '';
$dynamic = ! empty( $field['dynamic_choices'] ) ? esc_html( $field['dynamic_choices'] ) : '';
if ( 'post_type' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'post type', 'wpforms-lite' );
$pt = get_post_type_object( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( null !== $pt ) {
$source = $pt->labels->name;
}
} elseif ( 'taxonomy' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'taxonomy', 'wpforms-lite' );
$tax = get_taxonomy( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( false !== $tax ) {
$source = $tax->labels->name;
}
}
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
empty( $dynamic ) && ! empty( $field[ 'dynamic_' . $dynamic ] ) ? '' : 'wpforms-hidden'
);
$note .= sprintf(
/* translators: %1$s - source name; %2$s - type name. */
esc_html__( 'Choices are dynamically populated from the %1$s %2$s.', 'wpforms' ),
'<span class="dynamic-name">' . $source . '</span>',
'<span class="dynamic-type">' . $type . '</span>'
);
$note .= '</div>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld . $note,
),
false
);
break;
/*
* Choices for payments.
*/
case 'choices_payments':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$class = array();
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => esc_html__( 'Items', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="radio" name="%s[default]" class="default" value="1" %s>',
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value value wpforms-money-input" placeholder="%s">',
$base,
esc_attr( $value['value'] ),
wpforms_format_amount( 0 )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld,
),
false
);
break;
/*
* Choices Images.
*/
case 'choices_images':
// Field note: Image tips.
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden'
);
$note .= esc_html__( 'Images are not cropped or resized. For best results, they should be the same size and 250x250 pixels or smaller.', 'wpforms-lite' );
$note .= '</div>';
// Field contents.
$fld = $this->field_element(
'checkbox',
$field,
array(
'slug' => 'choices_images',
'value' => isset( $field['choices_images'] ) ? '1' : '0',
'desc' => esc_html__( 'Use image choices', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Check this option to enable using images with the choices.', 'wpforms-lite' ),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images',
'class' => ! empty( $field['dynamic_choices'] ) ? 'wpforms-hidden' : '',
'content' => $note . $fld,
),
false
);
break;
/*
* Choices Images Style.
*/
case 'choices_images_style':
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices_images_style',
'value' => esc_html__( 'Image Choice Style', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Select the style for the image choices.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = $this->field_element(
'select',
$field,
array(
'slug' => 'choices_images_style',
'value' => ! empty( $field['choices_images_style'] ) ? esc_attr( $field['choices_images_style'] ) : 'modern',
'options' => array(
'modern' => esc_html__( 'Modern', 'wpforms-lite' ),
'classic' => esc_html__( 'Classic', 'wpforms-lite' ),
'none' => esc_html__( 'None', 'wpforms-lite' ),
),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images_style',
'content' => $lbl . $fld,
'class' => ! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden',
),
false
);
break;
/**
* Advanced Fields.
*/
/*
* Default value.
*/
case 'default_value':
$value = ! empty( $field['default_value'] ) ? esc_attr( $field['default_value'] ) : '';
$tooltip = esc_html__( 'Enter text for the default form field value.', 'wpforms-lite' );
$toggle = '<a href="#" class="toggle-smart-tag-display" data-type="other"><i class="fa fa-tags"></i> <span>' . esc_html__( 'Show Smart Tags', 'wpforms-lite' ) . '</span></a>';
$output = $this->field_element( 'label', $field, array( 'slug' => 'default_value', 'value' => esc_html__( 'Default Value', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'default_value', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'default_value', 'content' => $output ), false );
break;
/*
* Size.
*/
case 'size':
$value = ! empty( $field['size'] ) ? esc_attr( $field['size'] ) : 'medium';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
$tooltip = esc_html__( 'Select the default form field size.', 'wpforms-lite' );
$options = array(
'small' => esc_html__( 'Small', 'wpforms-lite' ),
'medium' => esc_html__( 'Medium', 'wpforms-lite' ),
'large' => esc_html__( 'Large', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'size', 'value' => esc_html__( 'Field Size', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'size', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'size', 'content' => $output, 'class' => $class ), false );
break;
/*
* Advanced Options markup.
*/
case 'advanced-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
if ( 'open' === $markup ) {
$override = apply_filters( 'wpforms_advanced_options_override', false );
$override = ! empty( $override ) ? 'style="display:' . $override . ';"' : '';
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-advanced wpforms-hide" id="wpforms-field-option-advanced-%d" %s>', $field['id'], $override );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <i class="fa fa-angle-right"></i></a>', esc_html__( 'Advanced Options', 'wpforms-lite' ) );
$output .= '<div class="wpforms-field-option-group-inner">';
} else {
$output = '</div></div>';
}
break;
/*
* Placeholder.
*/
case 'placeholder':
$value = ! empty( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field placeholder.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'placeholder', 'value' => esc_html__( 'Placeholder Text', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'placeholder', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'placeholder', 'content' => $output ), false );
break;
/*
* CSS classes.
*/
case 'css':
$toggle = '';
$value = ! empty( $field['css'] ) ? esc_attr( $field['css'] ) : '';
$tooltip = esc_html__( 'Enter CSS class names for the form field container. Class names should be separated with spaces.', 'wpforms-lite' );
if ( 'pagebreak' !== $field['type'] ) {
$toggle = '<a href="#" class="toggle-layout-selector-display"><i class="fa fa-th-large"></i> <span>' . esc_html__( 'Show Layouts', 'wpforms-lite' ) . '</span></a>';
}
// Build output.
$output = $this->field_element( 'label', $field, array( 'slug' => 'css', 'value' => esc_html__( 'CSS Classes', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'css', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'css', 'content' => $output ), false );
break;
/*
* Hide Label.
*/
case 'label_hide':
$value = isset( $field['label_hide'] ) ? $field['label_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'label_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label_hide', 'content' => $output ), false );
break;
/*
* Hide Sub-Labels.
*/
case 'sublabel_hide':
$value = isset( $field['sublabel_hide'] ) ? $field['sublabel_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field sub-label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'sublabel_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Sub-Labels', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'sublabel_hide', 'content' => $output ), false );
break;
/*
* Input Columns.
*/
case 'input_columns':
$value = ! empty( $field['input_columns'] ) ? esc_attr( $field['input_columns'] ) : '';
$tooltip = esc_html__( 'Select the layout for displaying field choices.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'One Column', 'wpforms-lite' ),
'2' => esc_html__( 'Two Columns', 'wpforms-lite' ),
'3' => esc_html__( 'Three Columns', 'wpforms-lite' ),
'inline' => esc_html__( 'Inline', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'input_columns', 'value' => esc_html__( 'Choice Layout', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'input_columns', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'input_columns', 'content' => $output ), false );
break;
/*
* Dynamic Choices.
*/
case 'dynamic_choices':
$value = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
$tooltip = esc_html__( 'Select auto-populate method to use.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'Off', 'wpforms-lite' ),
'post_type' => esc_html__( 'Post Type', 'wpforms-lite' ),
'taxonomy' => esc_html__( 'Taxonomy', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'dynamic_choices', 'value' => esc_html__( 'Dynamic Choices', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'dynamic_choices', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'dynamic_choices', 'content' => $output ), false );
break;
/*
* Dynamic Choices Source.
*/
case 'dynamic_choices_source':
$output = '';
$type = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
if ( ! empty( $type ) ) {
$type_name = '';
$items = array();
if ( 'post_type' === $type ) {
$type_name = esc_html__( 'Post Type', 'wpforms-lite' );
$items = get_post_types(
array(
'public' => true,
),
'objects'
);
unset( $items['attachment'] );
} elseif ( 'taxonomy' === $type ) {
$type_name = esc_html__( 'Taxonomy', 'wpforms-lite' );
$items = get_taxonomies(
array(
'public' => true,
),
'objects'
);
unset( $items['post_format'] );
}
/* translators: %s - dynamic source type name. */
$tooltip = sprintf( esc_html__( 'Select %s to use for auto-populating field choices.', 'wpforms-lite' ), $type_name );
/* translators: %s - dynamic source type name. */
$label = sprintf( esc_html__( 'Dynamic %s Source', 'wpforms-lite' ), $type_name );
$options = array();
$source = ! empty( $field[ 'dynamic_' . $type ] ) ? esc_attr( $field[ 'dynamic_' . $type ] ) : '';
foreach ( $items as $key => $item ) {
$options[ $key ] = $item->labels->name;
}
// Field option label.
$option_label = $this->field_element(
'label',
$field,
array(
'slug' => 'dynamic_' . $type,
'value' => $label,
'tooltip' => $tooltip,
),
false
);
// Field option select input.
$option_input = $this->field_element(
'select',
$field,
array(
'slug' => 'dynamic_' . $type,
'options' => $options,
'value' => $source,
),
false
);
// Field option row (markup) including label and input.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'dynamic_' . $type,
'content' => $option_label . $option_input,
),
false
);
} // End if().
break;
}
if ( ! $echo ) {
return $output;
}
if ( in_array( $option, array( 'basic-options', 'advanced-options' ), true ) ) {
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_before_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_bottom_{$option}", $field, $this );
}
echo $output; // WPCS: XSS ok.
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_top_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_after_{$option}", $field, $this );
}
} else {
echo $output; // WPCS: XSS ok.
}
}
/**
* Helper function to create common field options that are used frequently
* in the field preview.
*
* @since 1.0.0
* @since 1.5.0 Added support for <select> HTML tag for choices.
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed Print or return a string.
*/
public function field_preview_option( $option, $field, $args = array(), $echo = true ) {
$output = '';
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
switch ( $option ) {
case 'label':
$label = isset( $field['label'] ) && ! empty( $field['label'] ) ? esc_html( $field['label'] ) : '';
$output = sprintf( '<label class="label-title %s"><span class="text">%s</span><span class="required">*</span></label>', $class, $label );
break;
case 'description':
$description = isset( $field['description'] ) && ! empty( $field['description'] ) ? $field['description'] : '';
$description = strpos( $class, 'nl2br' ) !== false ? nl2br( $description ) : $description;
$output = sprintf( '<div class="description %s">%s</div>', $class, $description );
break;
case 'choices':
$fields_w_choices = array( 'checkbox', 'gdpr-checkbox', 'select', 'payment-select', 'radio', 'payment-multiple' );
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$dynamic = ! empty( $field['dynamic_choices'] ) ? $field['dynamic_choices'] : false;
$total = 0;
/*
* Check to see if this field is configured for Dynamic Choices,
* either auto populating from a post type or a taxonomy.
*/
if ( ! empty( $field['dynamic_post_type'] ) ) {
switch ( $dynamic ) {
case 'post_type':
// Post type dynamic populating.
$total_obj = wp_count_posts( $field['dynamic_post_type'] );
$total = isset( $total_obj->publish ) ? (int) $total_obj->publish : 0;
$values = array();
$posts = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_post_type_args',
array(
'post_type' => $field['dynamic_post_type'],
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
),
$field,
$this->form_id
),
true
);
foreach ( $posts as $post ) {
$values[] = array(
'label' => $post->post_title,
);
}
break;
case 'taxonomy':
// Taxonomy dynamic populating.
$total = (int) wp_count_terms( $field['dynamic_taxonomy'] );
$values = array();
$terms = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_taxonomy_args',
array(
'taxonomy' => $field['dynamic_taxonomy'],
'hide_empty' => false,
),
$field,
$this->form_id
),
true
);
foreach ( $terms as $term ) {
$values[] = array(
'label' => $term->name,
);
}
break;
}
}
// Notify if dynamic choices source is currently empty.
if ( empty( $values ) ) {
$values = array(
'label' => esc_html__( '(empty)', 'wpforms-lite' ),
);
}
// Build output.
if ( ! in_array( $field['type'], $fields_w_choices, true ) ) {
break;
}
switch ( $field['type'] ) {
case 'checkbox':
case 'gdpr-checkbox':
$type = 'checkbox';
break;
case 'select':
case 'payment-select':
$type = 'select';
break;
default:
$type = 'radio';
break;
}
$list_class = array( 'primary-input' );
$with_images = empty( $field['dynamic_choices'] ) && ! empty( $field['choices_images'] );
if ( $with_images ) {
$list_class[] = 'wpforms-image-choices';
$list_class[] = 'wpforms-image-choices-' . sanitize_html_class( $field['choices_images_style'] );
}
// Special rules for <select>-based fields.
if ( 'select' === $type ) {
$placeholder = ! empty( $field['placeholder'] ) ? $field['placeholder'] : '';
$output = sprintf(
'<select class="%s" disabled>',
wpforms_sanitize_classes( $list_class, true )
);
// Optional placeholder.
if ( ! empty( $placeholder ) ) {
$output .= sprintf(
'<option value="" class="placeholder">%s</option>',
esc_html( $placeholder )
);
}
// Build the select options (even though user can only see 1st option).
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? (bool) $value['default'] : false;
$selected = ! empty( $placeholder ) ? '' : selected( true, $default, false );
$output .= sprintf(
'<option %s>%s</option>',
$selected,
esc_html( $value['label'] )
);
}
$output .= '</select>';
} else {
// Normal checkbox/radio-based fields.
$output = sprintf(
'<ul class="%s">',
wpforms_sanitize_classes( $list_class, true )
);
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? $value['default'] : '';
$selected = checked( '1', $default, false );
$input_class = array();
$item_class = array();
if ( ! empty( $value['default'] ) ) {
$item_class[] = 'wpforms-selected';
}
if ( $with_images ) {
$item_class[] = 'wpforms-image-choices-item';
}
$output .= sprintf(
'<li class="%s">',
wpforms_sanitize_classes( $item_class, true )
);
if ( $with_images ) {
if ( in_array( $field['choices_images_style'], array( 'modern', 'classic' ), true ) ) {
$input_class[] = 'wpforms-screen-reader-element';
}
$output .= '<label>';
$output .= sprintf(
'<span class="wpforms-image-choices-image"><img src="%s" alt="%s"%s></span>',
! empty( $value['image'] ) ? esc_url( $value['image'] ) : WPFORMS_PLUGIN_URL . 'assets/images/placeholder-200x125.png',
esc_attr( $value['label'] ),
! empty( $value['label'] ) ? ' title="' . esc_attr( $value['label'] ) . '"' : ''
);
if ( 'none' === $field['choices_images_style'] ) {
$output .= '<br>';
}
$output .= sprintf(
'<input type="%s" class="%s" %s disabled>',
$type,
wpforms_sanitize_classes( $input_class, true ),
$selected
);
$output .= '<span class="wpforms-image-choices-label">' . wp_kses_post( $value['label'] ) . '</span>';
$output .= '</label>';
} else {
$output .= sprintf(
'<input type="%s" %s disabled>%s',
$type,
$selected,
$value['label']
);
}
$output .= '</li>';
}
$output .= '</ul>';
}
/*
* Dynamic population is enabled and contains more than 20 items,
* include a note about results displayed.
*/
if ( $total > 20 ) {
$output .= '<div class="wpforms-alert-dynamic wpforms-alert wpforms-alert-warning">';
$output .= sprintf(
wp_kses(
/* translators: %d - total amount of choices. */
__( 'Showing the first 20 choices.<br> All %d choices will be displayed when viewing the form.', 'wpforms-lite' ),
array(
'br' => array(),
)
),
$total
);
$output .= '</div>';
}
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Create a new field in the admin AJAX editor.
*
* @since 1.0.0
*/
public function field_new() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
die( esc_html__( 'You do not have permission.', 'wpforms-lite' ) );
}
// Check for form ID.
if ( ! isset( $_POST['id'] ) || empty( $_POST['id'] ) ) {
die( esc_html__( 'No form ID found', 'wpforms-lite' ) );
}
// Check for field type to add.
if ( ! isset( $_POST['type'] ) || empty( $_POST['type'] ) ) {
die( esc_html__( 'No field type found', 'wpforms-lite' ) );
}
// Grab field data.
$field_args = ! empty( $_POST['defaults'] ) ? (array) $_POST['defaults'] : array();
$field_type = esc_attr( $_POST['type'] );
$field_id = wpforms()->form->next_field_id( $_POST['id'] );
$field = array(
'id' => $field_id,
'type' => $field_type,
'label' => $this->name,
'description' => '',
);
$field = wp_parse_args( $field_args, $field );
$field = apply_filters( 'wpforms_field_new_default', $field );
$field_required = apply_filters( 'wpforms_field_new_required', '', $field );
$field_class = apply_filters( 'wpforms_field_new_class', '', $field );
// Field types that default to required.
if ( ! empty( $field_required ) ) {
$field_required = 'required';
$field['required'] = '1';
}
// Build Preview.
ob_start();
$this->field_preview( $field );
$prev = ob_get_clean();
$preview = sprintf( '<div class="wpforms-field wpforms-field-%s %s %s" id="wpforms-field-%d" data-field-id="%d" data-field-type="%s">', $field_type, $field_required, $field_class, $field['id'], $field['id'], $field_type );
$preview .= sprintf( '<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' ) );
$preview .= sprintf( '<a href="#" class="wpforms-field-delete" title="%s"><i class="fa fa-times-circle"></i></a>', esc_attr__( 'Delete Field', 'wpforms-lite' ) );
$preview .= sprintf( '<span class="wpforms-field-helper">%s</span>', esc_html__( 'Click to edit. Drag to reorder.', 'wpforms-lite' ) );
$preview .= $prev;
$preview .= '</div>';
// Build Options.
$options = sprintf( '<div class="wpforms-field-option wpforms-field-option-%s" id="wpforms-field-option-%d" data-field-id="%d">', esc_attr( $field['type'] ), $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][id]" value="%d" class="wpforms-field-option-hidden-id">', $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][type]" value="%s" class="wpforms-field-option-hidden-type">', $field['id'], esc_attr( $field['type'] ) );
ob_start();
$this->field_options( $field );
$options .= ob_get_clean();
$options .= '</div>';
// Prepare to return compiled results.
wp_send_json_success(
array(
'form_id' => (int) $_POST['id'],
'field' => $field,
'preview' => $preview,
'options' => $options,
)
);
}
/**
* Display the field input elements on the frontend.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
* @param array $field_atts Field attributes.
* @param array $form_data Form data and settings.
*/
abstract public function field_display( $field, $field_atts, $form_data );
/**
* Display field input errors if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param array $field Field data and settings.
*/
public function field_display_error( $key, $field ) {
// Need an error.
if ( empty( $field['properties']['error']['value'][ $key ] ) ) {
return;
}
printf(
'<label class="wpforms-error" for="%s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
esc_html( $field['properties']['error']['value'][ $key ] )
);
}
/**
* Display field input sublabel if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param string $position Sublabel position.
* @param array $field Field data and settings.
*/
public function field_display_sublabel( $key, $position, $field ) {
// Need a sublabel value.
if ( empty( $field['properties']['inputs'][ $key ]['sublabel']['value'] ) ) {
return;
}
$pos = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['position'] ) ? $field['properties']['inputs'][ $key ]['sublabel']['position'] : 'after';
$hidden = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['hidden'] ) ? 'wpforms-sublabel-hide' : '';
if ( $pos !== $position ) {
return;
}
printf(
'<label for="%s" class="wpforms-field-sublabel %s %s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
sanitize_html_class( $pos ),
$hidden,
$field['properties']['inputs'][ $key ]['sublabel']['value']
);
}
/**
* Validates field on form submit.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param array $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function validate( $field_id, $field_submit, $form_data ) {
// Basic required check - If field is marked as required, check for entry data.
if ( ! empty( $form_data['fields'][ $field_id ]['required'] ) && empty( $field_submit ) && '0' != $field_submit ) {
wpforms()->process->errors[ $form_data['id'] ][ $field_id ] = wpforms_get_required_label();
}
}
/**
* Formats and sanitizes field.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param array $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function format( $field_id, $field_submit, $form_data ) {
if ( is_array( $field_submit ) ) {
$field_submit = array_filter( $field_submit );
$field_submit = implode( "\r\n", $field_submit );
}
$name = ! empty( $form_data['fields'][ $field_id ]['label'] ) ? sanitize_text_field( $form_data['fields'][ $field_id ]['label'] ) : '';
// Sanitize but keep line breaks.
$value = wpforms_sanitize_textarea_field( $field_submit );
wpforms()->process->fields[ $field_id ] = array(
'name' => $name,
'value' => $value,
'id' => absint( $field_id ),
'type' => $this->type,
);
}
}
home/xbodynamge/crosstraining/wp-content/plugins/wpforms-lite/includes/analytics/class-base.php 0000604 00000006557 15113747146 0027272 0 ustar 00 <?php
/**
* Analytics integration class.
*
* @package WPForms
* @author WPForms
* @since 1.4.5
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Analytics_Integration {
/**
* Payment name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Payment name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Payment icon.
*
* @since 1.0.0
* @var string
*/
public $icon;
/**
* Form data and settings.
*
* @since 1.1.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->init();
// Add to list of available analytics.
add_filter( 'wpforms_analytics_available', array( $this, 'register_analytics' ), $this->priority, 1 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_analytics_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_analytics_panel_content', array( $this, 'builder_output' ), $this->priority );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered analytics.
*
* @since 1.0.0
*
* @param array $analytics
*
* @return array
*/
public function register_analytics( $analytics = array() ) {
$analytics[ $this->slug ] = $this->name;
return $analytics;
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.1.0
*/
public function builder_form_data() {
$this->form_data = WPForms_Builder::instance()->form_data;
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$configured = ! empty( $this->form_data['analytics'][ $this->slug ]['enable'] ) ? 'configured' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . $configured . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<div class="wpforms-panel-content-section-title">
<?php echo esc_html( $this->name ); ?>
</div>
<div class="wpforms-payment-settings wpforms-clear">
<?php $this->builder_content(); ?>
</div>
</div>
<?php
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
}
}
home/xbodynamge/namtation/wp-content/plugins/wpforms-lite/includes/providers/class-base.php 0000644 00000102364 15113761015 0026411 0 ustar 00 <?php
/**
* Provider class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Provider {
/**
* Provider addon version.
*
* @since 1.0.0
*
* @var string
*/
protected $version;
/**
* Provider name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Provider name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Holds the API connections.
*
* @since 1.0.0
*
* @var mixed
*/
public $api = false;
/**
* Service icon.
*
* @since 1.0.0
*
* @var string
*/
public $icon;
/**
* Service icon.
*
* @since 1.2.3
*
* @var string
*/
public $type;
/**
* Form data and settings.
*
* @since 1.2.3
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->type = esc_html__( 'Connection', 'wpforms-lite' );
$this->init();
// Add to list of available providers.
add_filter( 'wpforms_providers_available', array( $this, 'register_provider' ), $this->priority, 1 );
// Process builder AJAX requests.
add_action( "wp_ajax_wpforms_provider_ajax_{$this->slug}", array( $this, 'process_ajax' ) );
// Process entry.
add_action( 'wpforms_process_complete', array( $this, 'process_entry' ), 5, 4 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_providers_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_providers_panel_content', array( $this, 'builder_output' ), $this->priority );
// Remove provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_disconnect', array( $this, 'integrations_tab_disconnect' ) );
// Add new provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_add', array( $this, 'integrations_tab_add' ) );
// Add providers sections to the Settings Integrations tab.
add_action( 'wpforms_settings_providers', array( $this, 'integrations_tab_options' ), $this->priority, 2 );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered providers.
*
* @since 1.0.0
*
* @param array $providers Array of all active providers.
*
* @return array
*/
public function register_provider( $providers = array() ) {
$providers[ $this->slug ] = $this->name;
return $providers;
}
/**
* Process the Builder AJAX requests.
*
* @since 1.0.0
*/
public function process_ajax() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
$name = ! empty( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
$task = ! empty( $_POST['task'] ) ? sanitize_text_field( wp_unslash( $_POST['task'] ) ) : '';
$id = ! empty( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '';
$connection_id = ! empty( $_POST['connection_id'] ) ? sanitize_text_field( wp_unslash( $_POST['connection_id'] ) ) : '';
$account_id = ! empty( $_POST['account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) : '';
$list_id = ! empty( $_POST['list_id'] ) ? sanitize_text_field( wp_unslash( $_POST['list_id'] ) ) : '';
$data = ! empty( $_POST['data'] ) ? array_map( 'sanitize_text_field', wp_parse_args( wp_unslash( $_POST['data'] ) ) ) : array(); //phpcs:ignore
/*
* Create new connection.
*/
if ( 'new_connection' === $task ) {
$connection = $this->output_connection(
'',
array(
'connection_name' => $name,
),
$id
);
wp_send_json_success(
array(
'html' => $connection,
)
);
}
/*
* Create new Provider account.
*/
if ( 'new_account' === $task ) {
$auth = $this->api_auth( $data, $id );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => $auth->get_error_message(),
)
);
} else {
$accounts = $this->output_accounts(
$connection_id,
array(
'account_id' => $auth,
)
);
wp_send_json_success(
array(
'html' => $accounts,
)
);
}
}
/*
* Select/Toggle Provider accounts.
*/
if ( 'select_account' === $task ) {
$lists = $this->output_lists(
$connection_id,
array(
'account_id' => $account_id,
)
);
if ( is_wp_error( $lists ) ) {
wp_send_json_error(
array(
'error' => $lists->get_error_message(),
)
);
} else {
wp_send_json_success(
array(
'html' => $lists,
)
);
}
}
/*
* Select/Toggle Provider account lists.
*/
if ( 'select_list' === $task ) {
$fields = $this->output_fields(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
),
$id
);
if ( is_wp_error( $fields ) ) {
wp_send_json_error(
array(
'error' => $fields->get_error_message(),
)
);
} else {
$groups = $this->output_groups(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
)
);
$conditionals = $this->output_conditionals(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
),
array(
'id' => absint( $_POST['form_id'] ), //phpcs:ignore
)
);
$options = $this->output_options(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
)
);
wp_send_json_success(
array(
'html' => $groups . $fields . $conditionals . $options,
)
);
}
}
die();
}
/**
* Process and submit entry to provider.
*
* @since 1.0.0
*
* @param array $fields List of fields in a form.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param int $entry_id Saved entry ID.
*/
public function process_entry( $fields, $entry, $form_data, $entry_id ) {
}
/**
* Process conditional fields.
*
* @since 1.0.0
*
* @param array $fields List of fields with their data and settings.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param array $connection List of connection settings.
*
* @return bool
*/
public function process_conditionals( $fields, $entry, $form_data, $connection ) {
if ( empty( $connection['conditional_logic'] ) || empty( $connection['conditionals'] ) ) {
return true;
}
$process = wpforms_conditional_logic()->process( $fields, $form_data, $connection['conditionals'] );
if ( ! empty( $connection['conditional_type'] ) && 'stop' === $connection['conditional_type'] ) {
$process = ! $process;
}
return $process;
}
/**
* Retrieve all available forms in a field.
*
* Not all fields should be available for merge tags so we compare against a
* white-list. Also some fields, such as Name, should have additional
* variations.
*
* @since 1.0.0
*
* @param object|bool $form
* @param array $whitelist
*
* @return bool|array
*/
public function get_form_fields( $form = false, $whitelist = array() ) {
// Accept form (post) object or form ID.
if ( is_object( $form ) ) {
$form = wpforms_decode( $form->post_content );
} elseif ( is_numeric( $form ) ) {
$form = wpforms()->form->get(
$form,
array(
'content_only' => true,
)
);
}
if ( ! is_array( $form ) || empty( $form['fields'] ) ) {
return false;
}
// White list of field types to allow.
$allowed_form_fields = array(
'text',
'textarea',
'select',
'radio',
'checkbox',
'email',
'address',
'url',
'name',
'hidden',
'date-time',
'phone',
'number',
);
$allowed_form_fields = apply_filters( 'wpforms_providers_fields', $allowed_form_fields );
$whitelist = ! empty( $whitelist ) ? $whitelist : $allowed_form_fields;
$form_fields = $form['fields'];
foreach ( $form_fields as $id => $form_field ) {
if ( ! in_array( $form_field['type'], $whitelist, true ) ) {
unset( $form_fields[ $id ] );
}
}
return $form_fields;
}
/**
* Get form fields ready for select list options.
*
* In this function we also do the logic to limit certain fields to certain
* provider field types.
*
* @since 1.0.0
*
* @param array $form_fields
* @param string $form_field_type
*
* @return array
*/
public function get_form_field_select( $form_fields = array(), $form_field_type = '' ) {
if ( empty( $form_fields ) || empty( $form_field_type ) ) {
return array();
}
$formatted = array();
// Include only specific field types.
foreach ( $form_fields as $id => $form_field ) {
// Email.
if (
'email' === $form_field_type &&
! in_array( $form_field['type'], array( 'text', 'email' ), true )
) {
unset( $form_fields[ $id ] );
}
// Address.
if (
'address' === $form_field_type &&
! in_array( $form_field['type'], array( 'address' ), true )
) {
unset( $form_fields[ $id ] );
}
}
// Format.
foreach ( $form_fields as $id => $form_field ) {
// Complex Name field.
if ( 'name' === $form_field['type'] ) {
// Full Name.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Full)', 'wpforms-lite' ),
$form_field['label']
),
);
// First Name.
if ( strpos( $form_field['format'], 'first' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'first',
'type' => $form_field['type'],
'subtype' => 'first',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (First)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Middle Name.
if ( strpos( $form_field['format'], 'middle' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'middle',
'type' => $form_field['type'],
'subtype' => 'middle',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Middle)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Last Name.
if ( strpos( $form_field['format'], 'last' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'last',
'type' => $form_field['type'],
'subtype' => 'last',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Last)', 'wpforms-lite' ),
$form_field['label']
),
);
}
} else {
// All other fields.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => $form_field['label'],
);
}
}
return $formatted;
}
/************************************************************************
* API methods - these methods interact directly with the provider API. *
************************************************************************/
/**
* Authenticate with the provider API.
*
* @since 1.0.0
*
* @param array $data
* @param string $form_id
*
* @return mixed id or error object
*/
public function api_auth( $data = array(), $form_id = '' ) {
}
/**
* Establish connection object to provider API.
*
* @since 1.0.0
*
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_connect( $account_id ) {
}
/**
* Retrieve provider account lists.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_lists( $connection_id = '', $account_id = '' ) {
}
/**
* Retrieve provider account list groups.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_groups( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/**
* Retrieve provider account list fields.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_fields( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/*************************************************************************
* Output methods - these methods generally return HTML for the builder. *
*************************************************************************/
/**
* Connection HTML.
*
* This method compiles all the HTML necessary for a connection to a provider.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form Form id or form data.
*
* @return string
*/
public function output_connection( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) ) {
$connection_id = 'connection_' . uniqid();
}
if ( empty( $connection ) || empty( $form ) ) {
return '';
}
$output = sprintf( '<div class="wpforms-provider-connection" data-provider="%s" data-connection_id="%s">', $this->slug, $connection_id );
$output .= $this->output_connection_header( $connection_id, $connection );
$output .= $this->output_auth();
$output .= $this->output_accounts( $connection_id, $connection );
$lists = $this->output_lists( $connection_id, $connection );
$output .= ! is_wp_error( $lists ) ? $lists : '';
$output .= $this->output_groups( $connection_id, $connection );
$fields = $this->output_fields( $connection_id, $connection, $form );
$output .= ! is_wp_error( $fields ) ? $fields : '';
$output .= $this->output_conditionals( $connection_id, $connection, $form );
$output .= $this->output_options( $connection_id, $connection );
$output .= '</div>';
return $output;
}
/**
* Connection header HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_connection_header( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$output = '<div class="wpforms-provider-connection-header">';
$output .= sprintf( '<span>%s</span>', sanitize_text_field( $connection['connection_name'] ) );
$output .= '<button class="wpforms-provider-connection-delete"><i class="fa fa-times-circle"></i></button>';
$output .= sprintf( '<input type="hidden" name="providers[%s][%s][connection_name]" value="%s">', $this->slug, $connection_id, esc_attr( $connection['connection_name'] ) );
$output .= '</div>';
return $output;
}
/**
* Provider account authorize fields HTML.
*
* @since 1.0.0
*
* @return mixed
*/
public function output_auth() {
}
/**
* Provider account select HTML.
*
* @since 1.0.0
*
* @param string $connection_id Unique connection ID.
* @param array $connection Array of connection data.
*
* @return string
*/
public function output_accounts( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$providers = wpforms_get_providers_options();
if ( empty( $providers[ $this->slug ] ) ) {
return '';
}
$output = '<div class="wpforms-provider-accounts wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Account', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][account_id]">', $this->slug, $connection_id );
foreach ( $providers[ $this->slug ] as $key => $provider_details ) {
$selected = ! empty( $connection['account_id'] ) ? $connection['account_id'] : '';
$output .= sprintf(
'<option value="%s" %s>%s</option>',
$key,
selected( $selected, $key, false ),
esc_html( $provider_details['label'] )
);
}
$output .= sprintf( '<option value="">%s</a>', esc_html__( 'Add New Account', 'wpforms-lite' ) );
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account lists HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return WP_Error|string
*/
public function output_lists( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) ) {
return '';
}
$lists = $this->api_lists( $connection_id, $connection['account_id'] );
$selected = ! empty( $connection['list_id'] ) ? $connection['list_id'] : '';
if ( is_wp_error( $lists ) ) {
return $lists;
}
$output = '<div class="wpforms-provider-lists wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select List', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][list_id]">', $this->slug, $connection_id );
if ( ! empty( $lists ) ) {
foreach ( $lists as $list ) {
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $list['id'] ),
selected( $selected, $list['id'], false ),
esc_attr( $list['name'] )
);
}
}
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account list groups HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_groups( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) ) {
return '';
}
$groupsets = $this->api_groups( $connection_id, $connection['account_id'], $connection['list_id'] );
if ( is_wp_error( $groupsets ) ) {
return '';
}
$output = '<div class="wpforms-provider-groups wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Groups', 'wpforms-lite' ) );
$output .= sprintf( '<p>%s</p>', esc_html__( 'We also noticed that you have some segments in your list. You can select specific list segments below if needed. This is optional.', 'wpforms-lite' ) );
$output .= '<div class="wpforms-provider-groups-list">';
foreach ( $groupsets as $groupset ) {
$output .= sprintf( '<p>%s</p>', esc_html( $groupset['name'] ) );
foreach ( $groupset['groups'] as $group ) {
$selected = ! empty( $connection['groups'] ) && ! empty( $connection['groups'][ $groupset['id'] ] ) ? in_array( $group['name'], $connection['groups'][ $groupset['id'] ], true ) : false;
$output .= sprintf(
'<span><input id="group_%s" type="checkbox" value="%s" name="providers[%s][%s][groups][%s][%s]" %s><label for="group_%s">%s</label></span>',
esc_attr( $group['id'] ),
esc_attr( $group['name'] ),
$this->slug,
$connection_id,
$groupset['id'],
$group['id'],
checked( $selected, true, false ),
esc_attr( $group['id'] ),
esc_attr( $group['name'] )
);
}
}
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* Provider account list fields HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form
*
* @return WP_Error|string
*/
public function output_fields( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) || empty( $form ) ) {
return '';
}
$provider_fields = $this->api_fields( $connection_id, $connection['account_id'], $connection['list_id'] );
$form_fields = $this->get_form_fields( $form );
if ( is_wp_error( $provider_fields ) ) {
return $provider_fields;
}
$output = '<div class="wpforms-provider-fields wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'List Fields', 'wpforms-lite' ) );
// Table with all the fields.
$output .= '<table>';
$output .= sprintf( '<thead><tr><th>%s</th><th>%s</th></thead>', esc_html__( 'List Fields', 'wpforms-lite' ), esc_html__( 'Available Form Fields', 'wpforms-lite' ) );
$output .= '<tbody>';
foreach ( $provider_fields as $provider_field ) :
$output .= '<tr>';
$output .= '<td>';
$output .= esc_html( $provider_field['name'] );
if (
! empty( $provider_field['req'] ) &&
$provider_field['req'] == '1'
) {
$output .= '<span class="required">*</span>';
}
$output .= '<td>';
$output .= sprintf( '<select name="providers[%s][%s][fields][%s]">', $this->slug, $connection_id, esc_attr( $provider_field['tag'] ) );
$output .= '<option value=""></option>';
$options = $this->get_form_field_select( $form_fields, $provider_field['field_type'] );
foreach ( $options as $option ) {
$value = sprintf( '%d.%s.%s', $option['id'], $option['key'], $option['provider_type'] );
$selected = ! empty( $connection['fields'][ $provider_field['tag'] ] ) ? selected( $connection['fields'][ $provider_field['tag'] ], $value, false ) : '';
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $value ), $selected, esc_html( $option['label'] ) );
}
$output .= '</select>';
$output .= '</td>';
$output .= '</tr>';
endforeach;
$output .= '</tbody>';
$output .= '</table>';
$output .= '</div>';
return $output;
}
/**
* Provider connection conditional options HTML
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param string|array $form
*
* @return string
*/
public function output_conditionals( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection['account_id'] ) ) {
return '';
}
return wpforms_conditional_logic()->builder_block(
array(
'form' => $this->form_data,
'type' => 'panel',
'panel' => $this->slug,
'parent' => 'providers',
'subsection' => $connection_id,
'reference' => esc_html__( 'Marketing provider connection', 'wpforms-lite' ),
),
false
);
}
/**
* Provider account list options HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_options( $connection_id = '', $connection = array() ) {
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.2.3
*/
public function builder_form_data() {
if ( ! empty( $_GET['form_id'] ) && empty( $this->form_data ) ) {
$this->form_data = wpforms()->form->get(
absint( $_GET['form_id'] ),
array(
'content_only' => true,
)
);
}
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
$form_data = $this->form_data;
$providers = wpforms_get_providers_options();
if ( ! empty( $form_data['providers'][ $this->slug ] ) && ! empty( $providers[ $this->slug ] ) ) {
foreach ( $form_data['providers'][ $this->slug ] as $connection_id => $connection ) {
foreach ( $providers[ $this->slug ] as $account_id => $connections ) {
if (
! empty( $connection['account_id'] ) &&
$connection['account_id'] === $account_id
) {
echo $this->output_connection( $connection_id, $connection, $form_data );
}
}
}
}
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$form_data = $this->form_data;
$configured = ! empty( $form_data['providers'][ $this->slug ] ) ? 'configured' : '';
$configured = apply_filters( 'wpforms_providers_' . $this->slug . '_configured', $configured );
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . esc_attr( $configured ) . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<?php $this->builder_output_before(); ?>
<div class="wpforms-panel-content-section-title">
<?php echo $this->name; ?>
<button class="wpforms-provider-connections-add" data-form_id="<?php echo absint( $_GET['form_id'] ); ?>"
data-provider="<?php echo esc_attr( $this->slug ); ?>"
data-type="<?php echo esc_attr( strtolower( $this->type ) ); ?>">
<?php
printf(
/* translators: %s - Provider type. */
esc_html__( 'Add New %s', 'wpforms-lite' ),
esc_html( $this->type )
);
?>
</button>
</div>
<div class="wpforms-provider-connections-wrap wpforms-clear">
<div class="wpforms-provider-connections">
<?php $this->builder_content(); ?>
</div>
</div>
<?php $this->builder_output_after(); ?>
</div>
<?php
}
/**
* Optionally output content before the main builder output.
*
* @since 1.3.6
*/
public function builder_output_before() {
}
/**
* Optionally output content after the main builder output.
*
* @since 1.3.6
*/
public function builder_output_after() {
}
/*************************************************************************
* Integrations tab methods - these methods relate to the settings page. *
*************************************************************************/
/**
* Form fields to add a new provider account.
*
* @since 1.0.0
*/
public function integrations_tab_new_form() {
}
/**
* AJAX to disconnect a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_disconnect() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['provider'] ) || empty( $_POST['key'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$providers = wpforms_get_providers_options();
if ( ! empty( $providers[ $_POST['provider'] ][ $_POST['key'] ] ) ) {
unset( $providers[ $_POST['provider'] ][ $_POST['key'] ] );
update_option( 'wpforms_providers', $providers );
wp_send_json_success();
} else {
wp_send_json_error(
array(
'error' => esc_html__( 'Connection missing', 'wpforms-lite' ),
)
);
}
}
/**
* AJAX to add a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_add() {
if ( $_POST['provider'] !== $this->slug ) { //phpcs:ignore
return;
}
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['data'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$data = wp_parse_args( $_POST['data'], array() );
$auth = $this->api_auth( $data, '' );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Could not connect to the provider.', 'wpforms-lite' ),
'error_msg' => $auth->get_error_message(),
)
);
} else {
$account = '<li class="wpforms-clear">';
$account .= '<span class="label">' . sanitize_text_field( $data['label'] ) . '</span>';
/* translators: %s - Connection date. */
$account .= '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format', time() ) ) ) . '</span>';
$account .= '<span class="remove"><a href="#" data-provider="' . $this->slug . '" data-key="' . esc_attr( $auth ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a></span>';
$account .= '</li>';
wp_send_json_success(
array(
'html' => $account,
)
);
}
}
/**
* Add provider to the Settings Integrations tab.
*
* @since 1.0.0
*
* @param array $active Array of active connections.
* @param array $settings Array of all connections settings.
*/
public function integrations_tab_options( $active, $settings ) {
$connected = ! empty( $active[ $this->slug ] );
$accounts = ! empty( $settings[ $this->slug ] ) ? $settings[ $this->slug ] : array();
$class = $connected && $accounts ? 'connected' : '';
$arrow = 'right';
/* translators: %s - provider name. */
$title_connect_to = sprintf( esc_html__( 'Connect to %s', 'wpforms-lite' ), esc_html( $this->name ) );
// This lets us highlight a specific service by a special link.
if ( ! empty( $_GET['wpforms-integration'] ) ) { //phpcs:ignore
if ( $this->slug === $_GET['wpforms-integration'] ) { //phpcs:ignore
$class .= ' focus-in';
$arrow = 'down';
} else {
$class .= ' focus-out';
}
}
?>
<div id="wpforms-integration-<?php echo esc_attr( $this->slug ); ?>" class="wpforms-settings-provider wpforms-clear <?php echo esc_attr( $this->slug ); ?> <?php echo esc_attr( $class ); ?>">
<div class="wpforms-settings-provider-header wpforms-clear" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-logo">
<i title="<?php esc_attr_e( 'Show Accounts', 'wpforms-lite' ); ?>" class="fa fa-chevron-<?php echo esc_attr( $arrow ); ?>"></i>
<img src="<?php echo esc_url( $this->icon ); ?>">
</div>
<div class="wpforms-settings-provider-info">
<h3><?php echo esc_html( $this->name ); ?></h3>
<p>
<?php
/* translators: %s - provider name. */
printf( esc_html__( 'Integrate %s with WPForms', 'wpforms-lite' ), esc_html( $this->name ) );
?>
</p>
<span class="connected-indicator green"><i class="fa fa-check-circle-o"></i> <?php esc_html_e( 'Connected', 'wpforms-lite' ); ?></span>
</div>
</div>
<div class="wpforms-settings-provider-accounts" id="provider-<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-accounts-list">
<ul>
<?php
if ( ! empty( $accounts ) ) {
foreach ( $accounts as $key => $account ) {
echo '<li class="wpforms-clear">';
echo '<span class="label">' . esc_html( $account['label'] ) . '</span>';
/* translators: %s - Connection date. */
echo '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format' ), intval( $account['date'] ) ) ) . '</span>';
echo '<span class="remove"><a href="#" data-provider="' . esc_attr( $this->slug ) . '" data-key="' . esc_attr( $key ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a></span>';
echo '</li>';
}
}
?>
</ul>
</div>
<p class="wpforms-settings-provider-accounts-toggle">
<a class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey" href="#" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<i class="fa fa-plus"></i> <?php esc_html_e( 'Add New Account', 'wpforms-lite' ); ?>
</a>
</p>
<div class="wpforms-settings-provider-accounts-connect">
<form>
<p><?php esc_html_e( 'Please fill out all of the fields below to add your new provider account.', 'wpforms-lite' ); ?></span></p>
<p class="wpforms-settings-provider-accounts-connect-fields">
<?php $this->integrations_tab_new_form(); ?>
</p>
<button type="submit" class="wpforms-btn wpforms-btn-md wpforms-btn-orange wpforms-settings-provider-connect"
data-provider="<?php echo esc_attr( $this->slug ); ?>" title="<?php echo esc_attr( $title_connect_to ); ?>">
<?php echo esc_html( $title_connect_to ); ?>
</button>
</form>
</div>
</div>
</div>
<?php
}
/**
* Error wrapper for WP_Error.
*
* @since 1.0.0
*
* @param string $message
* @param string $parent
*
* @return WP_Error
*/
public function error( $message = '', $parent = '0' ) {
return new WP_Error( $this->slug . '-error', $message );
}
}
home/xbodynamge/namtation/wp-content/plugins/wpforms-lite/includes/templates/class-base.php 0000644 00000010547 15114025712 0026371 0 ustar 00 <?php
/**
* Base form template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Template {
/**
* Full name of the template, eg "Contact Form".
*
* @since 1.0.0
* @var string
*/
public $name;
/**
* Slug of the template, eg "contact-form" - no spaces.
*
* @since 1.0.0
* @var string
*/
public $slug;
/**
* Short description the template.
*
* @since 1.0.0
* @var string
*/
public $description = '';
/**
* Short description of the fields included with the template.
*
* @since 1.0.0
* @var string
*/
public $includes = '';
/**
* URL of the icon to display in the admin area.
*
* @since 1.0.0
* @var string
*/
public $icon = '';
/**
* Array of data that is assigned to the post_content on form creation.
*
* @since 1.0.0
* @var array
*/
public $data;
/**
* Priority to show in the list of available templates.
*
* @since 1.0.0
* @var int
*/
public $priority = 20;
/**
* Core or additional template.
*
* @since 1.4.0
* @var bool
*/
public $core = false;
/**
* Modal message to display when the template is applied.
*
* @since 1.0.0
* @var array
*/
public $modal = '';
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Bootstrap.
$this->init();
$type = $this->core ? '_core' : '';
add_filter( "wpforms_form_templates{$type}", array( $this, 'template_details' ), $this->priority );
add_filter( 'wpforms_create_form_args', array( $this, 'template_data' ), 10, 2 );
add_filter( 'wpforms_save_form_args', array( $this, 'template_replace' ), 10, 3 );
add_filter( 'wpforms_builder_template_active', array( $this, 'template_active' ), 10, 2 );
}
/**
* Let's get started.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add basic template details to the Add New Form admin screen.
*
* @since 1.0.0
*
* @param array $templates
*
* @return array
*/
public function template_details( $templates ) {
$templates[] = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
);
return $templates;
}
/**
* Add template data when form is created.
*
* @since 1.0.0
*
* @param array $args
* @param array $data
*
* @return array
*/
public function template_data( $args, $data ) {
if ( ! empty( $data ) && ! empty( $data['template'] ) ) {
if ( $data['template'] === $this->slug ) {
$args['post_content'] = wpforms_encode( $this->data );
}
}
return $args;
}
/**
* Replace template on post update if triggered.
*
* @since 1.0.0
*
* @param array $form
* @param array $data
* @param array $args
*
* @return array
*/
public function template_replace( $form, $data, $args ) {
if ( ! empty( $args['template'] ) ) {
if ( $args['template'] === $this->slug ) {
$new = $this->data;
$new['settings'] = ! empty( $form['post_content']['settings'] ) ? $form['post_content']['settings'] : array();
$form['post_content'] = wpforms_encode( $new );
}
}
return $form;
}
/**
* Pass information about the active template back to the builder.
*
* @since 1.0.0
*
* @param array $details
* @param object $form
*
* @return array
*/
public function template_active( $details, $form ) {
if ( empty( $form ) ) {
return;
}
$form_data = wpforms_decode( $form->post_content );
if ( empty( $this->modal ) || empty( $form_data['meta']['template'] ) || $this->slug !== $form_data['meta']['template'] ) {
return $details;
} else {
$display = $this->template_modal_conditional( $form_data );
}
$template = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
'modal' => $this->modal,
'modal_display' => $display,
);
return $template;
}
/**
* Conditional to determine if the template informational modal screens
* should display.
*
* @since 1.0.0
*
* @param array $form_data Form data and settings.
*
* @return boolean
*/
public function template_modal_conditional( $form_data ) {
return false;
}
}
crosstraining/wp-content/plugins/wpforms-lite/includes/admin/builder/panels/class-base.php 0000604 00000010770 15114037003 0031175 0 ustar 00 home/xbodynamge <?php
/**
* Base panel class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
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 integer
*/
public $order = 50;
/**
* If panel contains a sidebar element or is full width.
*
* @since 1.0.0
* @var boolean
*/
public $sidebar = false;
/**
* Contains form object if we have one.
*
* @since 1.0.0
* @var object
*/
public $form;
/**
* Contains array of the form data (post_content).
*
* @since 1.0.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Load form if found.
$form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
$this->form = wpforms()->form->get( $form_id );
$this->form_data = $this->form ? wpforms_decode( $this->form->post_content ) : false;
// Bootstrap.
$this->init();
// Load panel specific enqueues.
add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ), 15 );
// Primary panel button.
add_action( 'wpforms_builder_panel_buttons', array( $this, 'button' ), $this->order, 2 );
// Output.
add_action( 'wpforms_builder_panels', array( $this, 'panel_output' ), $this->order, 2 );
}
/**
* 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
}
/**
* Outputs the contents of the panel.
*
* @since 1.0.0
*
* @param object $form
* @param string $view
*/
public function panel_output( $form, $view ) {
$active = $view === $this->slug ? 'active' : '';
$wrap = $this->sidebar ? 'wpforms-panel-sidebar-content' : 'wpforms-panel-full-content';
printf( '<div class="wpforms-panel %s" id="wpforms-panel-%s">', $active, esc_attr( $this->slug ) );
printf( '<div class="wpforms-panel-name">%s</div>', $this->name );
printf( '<div class="%s">', $wrap );
if ( true === $this->sidebar ) {
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>';
}
/**
* Outputs the panel's sidebar if we have one.
*
* @since 1.0.0
*/
public function panel_sidebar() {
}
/**
* Outputs panel sidebar sections.
*
* @since 1.0.0
*
* @param string $name
* @param string $slug
* @param string $icon
*/
public function panel_sidebar_section( $name, $slug, $icon = '' ) {
$class = '';
$class .= $slug === 'default' ? ' default' : '';
$class .= ! empty( $icon ) ? ' icon' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section wpforms-panel-sidebar-section-' . esc_attr( $slug ) . $class . '" 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>';
}
/**
* Outputs the panel's primary content.
*
* @since 1.0.0
*/
public function panel_content() {
}
}
home/xbodynamge/lebauwcentre/wp-content/plugins/wpforms-lite/includes/fields/class-base.php 0000644 00000161735 15114074671 0026345 0 ustar 00 <?php
/**
* Base field template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Field {
/**
* Full name of the field type, eg "Paragraph Text".
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Type of the field, eg "textarea".
*
* @since 1.0.0
*
* @var string
*/
public $type;
/**
* 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 integer
*/
public $order = 1;
/**
* Field group the field belongs to.
*
* @since 1.0.0
*
* @var string
*/
public $group = 'standard';
/**
* Placeholder to hold default value(s) for some field types.
*
* @since 1.0.0
*
* @var mixed
*/
public $defaults;
/**
* Current form ID in the admin builder.
*
* @since 1.1.1
*
* @var int|bool
*/
public $form_id;
/**
* Current form data in.
*
* @since 1.1.1
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*
* @param bool $init Pass false to allow to shortcut the whole initialization, if needed.
*/
public function __construct( $init = true ) {
if ( ! $init ) {
return;
}
// The form ID is to be accessed in the builder.
$this->form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
// Bootstrap.
$this->init();
// Add fields tab.
add_filter( 'wpforms_builder_fields_buttons', array( $this, 'field_button' ), 15 );
// Field options tab.
add_action( "wpforms_builder_fields_options_{$this->type}", array( $this, 'field_options' ), 10 );
// Preview fields.
add_action( "wpforms_builder_fields_previews_{$this->type}", array( $this, 'field_preview' ), 10 );
// AJAX Add new field.
add_action( "wp_ajax_wpforms_new_field_{$this->type}", array( $this, 'field_new' ) );
// Display field input elements on front-end.
add_action( "wpforms_display_field_{$this->type}", array( $this, 'field_display' ), 10, 3 );
// Validation on submit.
add_action( "wpforms_process_validate_{$this->type}", array( $this, 'validate' ), 10, 3 );
// Format.
add_action( "wpforms_process_format_{$this->type}", array( $this, 'format' ), 10, 3 );
// Prefill.
add_filter( 'wpforms_field_properties', array( $this, 'field_prefill_value_property' ), 10, 3 );
}
/**
* All systems go. Used by subclasses. Required.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*/
abstract public function init();
/**
* Prefill field value with either fallback or dynamic data.
* Needs to be public (although internal) to be used in WordPress hooks.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
* @param array $form_data Prepared form data/settings.
*
* @return array Modified field properties.
*/
public function field_prefill_value_property( $properties, $field, $form_data ) {
// Process only for current field.
if ( $this->type !== $field['type'] ) {
return $properties;
}
// Set the form data, so we can reuse it later, even on front-end.
$this->form_data = $form_data;
// Dynamic data.
if ( ! empty( $this->form_data['settings']['dynamic_population'] ) ) {
$properties = $this->field_prefill_value_property_dynamic( $properties, $field );
}
// Fallback data, rewrites dynamic because user-submitted data is more important.
$properties = $this->field_prefill_value_property_fallback( $properties, $field );
return $properties;
}
/**
* As we are processing user submitted data - ignore all admin-defined defaults.
* Preprocess choices-related fields only.
*
* @since 1.5.0
*
* @param array $field Field data and settings.
* @param array $properties Properties we are modifying.
*/
protected function field_prefill_remove_choices_defaults( $field, &$properties ) {
if (
! empty( $field['dynamic_choices'] ) ||
! empty( $field['choices'] )
) {
array_walk_recursive(
$properties['inputs'],
function ( &$value, $key ) {
if ( 'default' === $key ) {
$value = false;
}
if ( 'wpforms-selected' === $value ) {
$value = '';
}
}
);
}
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_dynamic_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
// For dynamic population we require $_GET.
if ( empty( $_GET ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_dynamic_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a dynamic value, that we get from $_GET.
* The pattern is: wpf4_12_primary, where:
* 4 - form_id,
* 12 - field_id,
* first - input key.
* As 'primary' is our default input key, "wpf4_12_primary" and "wpf4_12" are the same.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_dynamic( $properties, $field ) {
if ( ! $this->is_dynamic_population_allowed( $properties, $field ) ) {
return $properties;
}
// Iterate over each GET key, parse, and scrap data from there.
foreach ( $_GET as $key => $raw_value ) { // phpcs:ignore
preg_match( '/wpf(\d+)_(\d+)(.*)/i', $key, $matches );
if ( empty( $matches ) || ! is_array( $matches ) ) {
continue;
}
// Required.
$form_id = absint( $matches[1] );
$field_id = absint( $matches[2] );
$input = 'primary';
// Optional.
if ( ! empty( $matches[3] ) ) {
$input = sanitize_key( trim( $matches[3], '_' ) );
}
// Both form and field IDs should be the same as current form/field.
if (
(int) $this->form_data['id'] !== $form_id ||
(int) $field['id'] !== $field_id
) {
// Go to the next GET param.
continue;
}
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* Some fields (like checkboxes) support multiple selection.
* We do not support nested values, so omit them.
* Example: ?wpf771_19_wpforms[fields][19][address1]=test
* In this case:
* $input = wpforms
* $raw_value = [fields=>[]]
* $single_value = [19=>[]]
* There is no reliable way to clean those things out.
* So we will ignore the value altogether if it's an array.
* We support only single value numeric arrays, like these:
* ?wpf771_19[]=test1&wpf771_19[]=test2
* ?wpf771_19_value[]=test1&wpf771_19_value[]=test2
* ?wpf771_41_r3_c2[]=1&wpf771_41_r1_c4[]=1
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, $input, $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, $input, $properties, $field );
}
}
return $properties;
}
/**
* Get the value, that is used to prefill via dynamic or fallback population.
* Based on field data and current properties.
*
* @since 1.5.0
*
* @param string $raw_value Value from a GET param, always a string.
* @param string $input Represent a subfield inside the field. May be empty.
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function get_field_populated_single_property_value( $raw_value, $input, $properties, $field ) {
if ( ! is_string( $raw_value ) ) {
return $properties;
}
$get_value = stripslashes( sanitize_text_field( $raw_value ) );
// For fields that have dynamic choices we need to add extra logic.
if ( ! empty( $field['dynamic_choices'] ) ) {
$default_key = null;
foreach ( $properties['inputs'] as $input_key => $input_arr ) {
// Dynamic choices support only integers in its values.
if ( absint( $get_value ) === $input_arr['attr']['value'] ) {
$default_key = $input_key;
// Stop iterating over choices.
break;
}
}
// Redefine default choice only if dynamic value has changed anything.
if ( null !== $default_key ) {
foreach ( $properties['inputs'] as $input_key => $choice_arr ) {
if ( $input_key === $default_key ) {
$properties['inputs'][ $input_key ]['default'] = true;
$properties['inputs'][ $input_key ]['container']['class'][] = 'wpforms-selected';
// Stop iterating over choices.
break;
}
}
}
} elseif ( ! empty( $field['choices'] ) && is_array( $field['choices'] ) ) {
$default_key = null;
// For fields that have normal choices we need to add extra logic.
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( isset( $field['show_values'] ) ) {
if (
isset( $choice_arr['value'] ) &&
strtoupper( $choice_arr['value'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
} else {
if (
isset( $choice_arr['label'] ) &&
strtoupper( $choice_arr['label'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
}
}
// Redefine default choice only if population value has changed anything.
if ( null !== $default_key ) {
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( $choice_key === $default_key ) {
$properties['inputs'][ $choice_key ]['default'] = true;
$properties['inputs'][ $choice_key ]['container']['class'][] = 'wpforms-selected';
break;
}
}
}
} else {
/*
* For other types of fields we need to check that
* the key is registered for the defined field in inputs array.
*/
if (
! empty( $input ) &&
isset( $properties['inputs'][ $input ] )
) {
$properties['inputs'][ $input ]['attr']['value'] = $get_value;
}
}
return $properties;
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_fallback_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
/*
* Commented out to allow partial fail for complex multi-inputs fields.
* Example: name field with first/last format and being required, filled out only first.
* On submit we will preserve those sub-inputs that are not empty and display an error for an empty.
*/
// Do not populate if there are errors for that field.
/*
$errors = wpforms()->process->errors;
if ( ! empty( $errors[ $this->form_data['id'] ][ $field['id'] ] ) ) {
$allowed = false;
}
*/
// Require form id being the same for submitted and currently rendered form.
if (
! empty( $_POST['wpforms']['id'] ) && // phpcs:ignore
(int) $_POST['wpforms']['id'] !== (int) $this->form_data['id'] // phpcs:ignore
) {
$allowed = false;
}
// Require $_POST of submitted field.
if ( empty( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
$allowed = false;
}
// Require field (processed and rendered) being the same.
if ( ! isset( $_POST['wpforms']['fields'][ $field['id'] ] ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_fallback_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a fallback value from form submission (in case of JS validation failed), that we get from $_POST.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_fallback( $properties, $field ) {
if ( ! $this->is_fallback_population_allowed( $properties, $field ) ) {
return $properties;
}
if ( empty( $_POST['wpforms']['fields'] ) || ! is_array( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
return $properties;
}
// We got user submitted raw data (not processed, will be done later).
$raw_value = $_POST['wpforms']['fields'][ $field['id'] ]; // phpcs:ignore
$input = 'primary';
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* For this particular field this value may be either array or a string.
* In array - this is a complex field, like address.
* The key in array will be a sub-input (address1, state), and its appropriate value.
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $input => $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, sanitize_key( $input ), $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, sanitize_key( $input ), $properties, $field );
}
return $properties;
}
/**
* Create the button for the 'Add Fields' tab, inside the form editor.
*
* @since 1.0.0
*
* @param array $fields List of form fields with their data.
*
* @return array
*/
public function field_button( $fields ) {
// Add field information to fields array.
$fields[ $this->group ]['fields'][] = array(
'order' => $this->order,
'name' => $this->name,
'type' => $this->type,
'icon' => $this->icon,
);
// Wipe hands clean.
return $fields;
}
/**
* Creates the field options panel. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_options( $field );
/**
* Creates the field preview. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_preview( $field );
/**
* Helper function to create field option elements.
*
* Field option elements are pieces that help create a field option.
* They are used to quickly build field options.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_element( $option, $field, $args = array(), $echo = true ) {
$id = (int) $field['id'];
$class = ! empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
$slug = ! empty( $args['slug'] ) ? sanitize_title( $args['slug'] ) : '';
$data = '';
$output = '';
if ( ! empty( $args['data'] ) ) {
foreach ( $args['data'] as $arg_key => $val ) {
if ( is_array( $val ) ) {
$val = wp_json_encode( $val );
}
$data .= ' data-' . $arg_key . '=\'' . $val . '\'';
}
}
switch ( $option ) {
// Row.
case 'row':
$output = sprintf(
'<div class="wpforms-field-option-row wpforms-field-option-row-%s %s" id="wpforms-field-option-row-%d-%s" data-field-id="%d">%s</div>',
$slug,
$class,
$id,
$slug,
$id,
$args['content']
);
break;
// Label.
case 'label':
$output = sprintf( '<label for="wpforms-field-option-%d-%s">%s', $id, $slug, esc_html( $args['value'] ) );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
if ( isset( $args['after_tooltip'] ) && ! empty( $args['after_tooltip'] ) ) {
$output .= $args['after_tooltip'];
}
$output .= '</label>';
break;
// Text input.
case 'text':
$type = ! empty( $args['type'] ) ? esc_attr( $args['type'] ) : 'text';
$placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : '';
$before = ! empty( $args['before'] ) ? '<span class="before-input">' . esc_html( $args['before'] ) . '</span>' : '';
if ( ! empty( $before ) ) {
$class .= ' has-before';
}
$output = sprintf( '%s<input type="%s" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="%s" placeholder="%s" %s>', $before, $type, $class, $id, $slug, $id, $slug, esc_attr( $args['value'] ), $placeholder, $data );
break;
// Textarea.
case 'textarea':
$rows = ! empty( $args['rows'] ) ? (int) $args['rows'] : '3';
$output = sprintf( '<textarea class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" rows="%d" %s>%s</textarea>', $class, $id, $slug, $id, $slug, $rows, $data, $args['value'] );
break;
// Checkbox.
case 'checkbox':
$checked = checked( '1', $args['value'], false );
$output = sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s>', $class, $id, $slug, $id, $slug, $checked, $data );
$output .= sprintf( '<label for="wpforms-field-option-%d-%s" class="inline">%s', $id, $slug, $args['desc'] );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
$output .= '</label>';
break;
// Toggle.
case 'toggle':
$checked = checked( '1', $args['value'], false );
$icon = $args['value'] ? 'fa-toggle-on' : 'fa-toggle-off';
$cls = $args['value'] ? 'wpforms-on' : 'wpforms-off';
$status = $args['value'] ? esc_html__( 'On', 'wpforms-lite' ) : esc_html__( 'Off', 'wpforms-lite' );
$output = sprintf( '<span class="wpforms-toggle-icon %s"><i class="fa %s" aria-hidden="true"></i> <span class="wpforms-toggle-icon-label">%s</span>', $cls, $icon, $status );
$output .= sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s></span>', $class, $id, $slug, $id, $slug, $checked, $data );
break;
// Select.
case 'select':
$options = $args['options'];
$value = isset( $args['value'] ) ? $args['value'] : '';
$output = sprintf( '<select class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" %s>', $class, $id, $slug, $id, $slug, $data );
foreach ( $options as $arg_key => $arg_option ) {
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $arg_key ), selected( $arg_key, $value, false ), $arg_option );
}
$output .= '</select>';
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Helper function to create common field options that are used frequently.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_option( $option, $field, $args = array(), $echo = true ) {
switch ( $option ) {
/**
* Basic Fields.
*/
/*
* Basic Options markup.
*/
case 'basic-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
if ( 'open' === $markup ) {
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-basic" id="wpforms-field-option-basic-%d">', $field['id'] );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <span>(ID #%d)</span> <i class="fa fa-angle-down"></i></a>', $this->name, $field['id'] );
$output .= sprintf( '<div class="wpforms-field-option-group-inner %s">', $class );
} else {
$output = '</div></div>';
}
break;
/*
* Field Label.
*/
case 'label':
$value = ! empty( $field['label'] ) ? esc_attr( $field['label'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field label. Field labels are recommended and can be hidden in the Advanced Settings.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'label', 'value' => esc_html__( 'Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'label', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label', 'content' => $output ), false );
break;
/*
* Field Description.
*/
case 'description':
$value = ! empty( $field['description'] ) ? esc_attr( $field['description'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field description.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'description', 'value' => esc_html__( 'Description', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'description', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'description', 'content' => $output ), false );
break;
/*
* Field Required toggle.
*/
case 'required':
$default = ! empty( $args['default'] ) ? $args['default'] : '0';
$value = isset( $field['required'] ) ? $field['required'] : $default;
$tooltip = esc_html__( 'Check this option to mark the field required. A form will not submit unless all required fields are provided.', 'wpforms-lite' );
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'required', 'value' => $value, 'desc' => esc_html__( 'Required', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'required', 'content' => $output ), false );
break;
/*
* Field Meta (field type and ID).
*/
case 'meta':
$output = sprintf( '<label>%s</label>', 'Type' );
$output .= sprintf( '<p class="meta">%s <span class="id">(ID #%d)</span></p>', $this->name, $field['id'] );
$output = $this->field_element( 'row', $field, array( 'slug' => 'meta', 'content' => $output ), false );
break;
/*
* Code Block.
*/
case 'code':
$value = ! empty( $field['code'] ) ? esc_textarea( $field['code'] ) : '';
$tooltip = esc_html__( 'Enter code for the form field.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'code', 'value' => esc_html__( 'Code', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'code', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'code', 'content' => $output ), false );
break;
/*
* Choices.
*/
case 'choices':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$label = ! empty( $args['label'] ) ? esc_html( $args['label'] ) : esc_html__( 'Choices', 'wpforms-lite' );
$class = array();
if ( ! empty( $field['show_values'] ) ) {
$class[] = 'show-values';
}
if ( ! empty( $field['dynamic_choices'] ) ) {
$class[] = 'wpforms-hidden';
}
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => $label,
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
'after_tooltip' => '<a href="#" class="toggle-bulk-add-display"><i class="fa fa-download"></i> <span>' . esc_html__( 'Bulk Add', 'wpforms-lite' ) . '</span></a>',
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="%s" name="%s[default]" class="default" value="1" %s>',
'checkbox' === $this->type ? 'checkbox' : 'radio',
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value">',
$base,
esc_attr( $value['value'] )
);
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Field note: dynamic status.
$source = '';
$type = '';
$dynamic = ! empty( $field['dynamic_choices'] ) ? esc_html( $field['dynamic_choices'] ) : '';
if ( 'post_type' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'post type', 'wpforms-lite' );
$pt = get_post_type_object( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( null !== $pt ) {
$source = $pt->labels->name;
}
} elseif ( 'taxonomy' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'taxonomy', 'wpforms-lite' );
$tax = get_taxonomy( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( false !== $tax ) {
$source = $tax->labels->name;
}
}
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
empty( $dynamic ) && ! empty( $field[ 'dynamic_' . $dynamic ] ) ? '' : 'wpforms-hidden'
);
$note .= sprintf(
/* translators: %1$s - source name; %2$s - type name. */
esc_html__( 'Choices are dynamically populated from the %1$s %2$s.', 'wpforms' ),
'<span class="dynamic-name">' . $source . '</span>',
'<span class="dynamic-type">' . $type . '</span>'
);
$note .= '</div>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld . $note,
),
false
);
break;
/*
* Choices for payments.
*/
case 'choices_payments':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$class = array();
$input_type = in_array( $field['type'], array( 'payment-multiple', 'payment-select' ), true ) ? 'radio' : 'checkbox';
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => esc_html__( 'Items', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="%s" name="%s[default]" class="default" value="1" %s>',
$input_type,
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value wpforms-money-input" placeholder="%s">',
$base,
esc_attr( $value['value'] ),
wpforms_format_amount( 0 )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld,
),
false
);
break;
/*
* Choices Images.
*/
case 'choices_images':
// Field note: Image tips.
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden'
);
$note .= esc_html__( 'Images are not cropped or resized. For best results, they should be the same size and 250x250 pixels or smaller.', 'wpforms-lite' );
$note .= '</div>';
// Field contents.
$fld = $this->field_element(
'checkbox',
$field,
array(
'slug' => 'choices_images',
'value' => isset( $field['choices_images'] ) ? '1' : '0',
'desc' => esc_html__( 'Use image choices', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Check this option to enable using images with the choices.', 'wpforms-lite' ),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images',
'class' => ! empty( $field['dynamic_choices'] ) ? 'wpforms-hidden' : '',
'content' => $note . $fld,
),
false
);
break;
/*
* Choices Images Style.
*/
case 'choices_images_style':
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices_images_style',
'value' => esc_html__( 'Image Choice Style', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Select the style for the image choices.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = $this->field_element(
'select',
$field,
array(
'slug' => 'choices_images_style',
'value' => ! empty( $field['choices_images_style'] ) ? esc_attr( $field['choices_images_style'] ) : 'modern',
'options' => array(
'modern' => esc_html__( 'Modern', 'wpforms-lite' ),
'classic' => esc_html__( 'Classic', 'wpforms-lite' ),
'none' => esc_html__( 'None', 'wpforms-lite' ),
),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images_style',
'content' => $lbl . $fld,
'class' => ! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden',
),
false
);
break;
/**
* Advanced Fields.
*/
/*
* Default value.
*/
case 'default_value':
$value = ! empty( $field['default_value'] ) ? esc_attr( $field['default_value'] ) : '';
$tooltip = esc_html__( 'Enter text for the default form field value.', 'wpforms-lite' );
$toggle = '<a href="#" class="toggle-smart-tag-display" data-type="other"><i class="fa fa-tags"></i> <span>' . esc_html__( 'Show Smart Tags', 'wpforms-lite' ) . '</span></a>';
$output = $this->field_element( 'label', $field, array( 'slug' => 'default_value', 'value' => esc_html__( 'Default Value', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'default_value', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'default_value', 'content' => $output ), false );
break;
/*
* Size.
*/
case 'size':
$value = ! empty( $field['size'] ) ? esc_attr( $field['size'] ) : 'medium';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
$tooltip = esc_html__( 'Select the default form field size.', 'wpforms-lite' );
$options = array(
'small' => esc_html__( 'Small', 'wpforms-lite' ),
'medium' => esc_html__( 'Medium', 'wpforms-lite' ),
'large' => esc_html__( 'Large', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'size', 'value' => esc_html__( 'Field Size', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'size', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'size', 'content' => $output, 'class' => $class ), false );
break;
/*
* Advanced Options markup.
*/
case 'advanced-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
if ( 'open' === $markup ) {
$override = apply_filters( 'wpforms_advanced_options_override', false );
$override = ! empty( $override ) ? 'style="display:' . $override . ';"' : '';
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-advanced wpforms-hide" id="wpforms-field-option-advanced-%d" %s>', $field['id'], $override );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <i class="fa fa-angle-right"></i></a>', esc_html__( 'Advanced Options', 'wpforms-lite' ) );
$output .= '<div class="wpforms-field-option-group-inner">';
} else {
$output = '</div></div>';
}
break;
/*
* Placeholder.
*/
case 'placeholder':
$value = ! empty( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field placeholder.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'placeholder', 'value' => esc_html__( 'Placeholder Text', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'placeholder', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'placeholder', 'content' => $output ), false );
break;
/*
* CSS classes.
*/
case 'css':
$toggle = '';
$value = ! empty( $field['css'] ) ? esc_attr( $field['css'] ) : '';
$tooltip = esc_html__( 'Enter CSS class names for the form field container. Class names should be separated with spaces.', 'wpforms-lite' );
if ( 'pagebreak' !== $field['type'] ) {
$toggle = '<a href="#" class="toggle-layout-selector-display"><i class="fa fa-th-large"></i> <span>' . esc_html__( 'Show Layouts', 'wpforms-lite' ) . '</span></a>';
}
// Build output.
$output = $this->field_element( 'label', $field, array( 'slug' => 'css', 'value' => esc_html__( 'CSS Classes', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'css', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'css', 'content' => $output ), false );
break;
/*
* Hide Label.
*/
case 'label_hide':
$value = isset( $field['label_hide'] ) ? $field['label_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'label_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label_hide', 'content' => $output ), false );
break;
/*
* Hide Sub-Labels.
*/
case 'sublabel_hide':
$value = isset( $field['sublabel_hide'] ) ? $field['sublabel_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field sub-label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'sublabel_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Sub-Labels', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'sublabel_hide', 'content' => $output ), false );
break;
/*
* Input Columns.
*/
case 'input_columns':
$value = ! empty( $field['input_columns'] ) ? esc_attr( $field['input_columns'] ) : '';
$tooltip = esc_html__( 'Select the layout for displaying field choices.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'One Column', 'wpforms-lite' ),
'2' => esc_html__( 'Two Columns', 'wpforms-lite' ),
'3' => esc_html__( 'Three Columns', 'wpforms-lite' ),
'inline' => esc_html__( 'Inline', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'input_columns', 'value' => esc_html__( 'Choice Layout', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'input_columns', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'input_columns', 'content' => $output ), false );
break;
/*
* Dynamic Choices.
*/
case 'dynamic_choices':
$value = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
$tooltip = esc_html__( 'Select auto-populate method to use.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'Off', 'wpforms-lite' ),
'post_type' => esc_html__( 'Post Type', 'wpforms-lite' ),
'taxonomy' => esc_html__( 'Taxonomy', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'dynamic_choices', 'value' => esc_html__( 'Dynamic Choices', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'dynamic_choices', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'dynamic_choices', 'content' => $output ), false );
break;
/*
* Dynamic Choices Source.
*/
case 'dynamic_choices_source':
$output = '';
$type = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
if ( ! empty( $type ) ) {
$type_name = '';
$items = array();
if ( 'post_type' === $type ) {
$type_name = esc_html__( 'Post Type', 'wpforms-lite' );
$items = get_post_types(
array(
'public' => true,
),
'objects'
);
unset( $items['attachment'] );
} elseif ( 'taxonomy' === $type ) {
$type_name = esc_html__( 'Taxonomy', 'wpforms-lite' );
$items = get_taxonomies(
array(
'public' => true,
),
'objects'
);
unset( $items['post_format'] );
}
/* translators: %s - dynamic source type name. */
$tooltip = sprintf( esc_html__( 'Select %s to use for auto-populating field choices.', 'wpforms-lite' ), $type_name );
/* translators: %s - dynamic source type name. */
$label = sprintf( esc_html__( 'Dynamic %s Source', 'wpforms-lite' ), $type_name );
$options = array();
$source = ! empty( $field[ 'dynamic_' . $type ] ) ? esc_attr( $field[ 'dynamic_' . $type ] ) : '';
foreach ( $items as $key => $item ) {
$options[ $key ] = $item->labels->name;
}
// Field option label.
$option_label = $this->field_element(
'label',
$field,
array(
'slug' => 'dynamic_' . $type,
'value' => $label,
'tooltip' => $tooltip,
),
false
);
// Field option select input.
$option_input = $this->field_element(
'select',
$field,
array(
'slug' => 'dynamic_' . $type,
'options' => $options,
'value' => $source,
),
false
);
// Field option row (markup) including label and input.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'dynamic_' . $type,
'content' => $option_label . $option_input,
),
false
);
} // End if().
break;
}
if ( ! $echo ) {
return $output;
}
if ( in_array( $option, array( 'basic-options', 'advanced-options' ), true ) ) {
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_before_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_bottom_{$option}", $field, $this );
}
echo $output; // WPCS: XSS ok.
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_top_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_after_{$option}", $field, $this );
}
} else {
echo $output; // WPCS: XSS ok.
}
}
/**
* Helper function to create common field options that are used frequently
* in the field preview.
*
* @since 1.0.0
* @since 1.5.0 Added support for <select> HTML tag for choices.
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed Print or return a string.
*/
public function field_preview_option( $option, $field, $args = array(), $echo = true ) {
$output = '';
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
switch ( $option ) {
case 'label':
$label = isset( $field['label'] ) && ! empty( $field['label'] ) ? esc_html( $field['label'] ) : '';
$output = sprintf( '<label class="label-title %s"><span class="text">%s</span><span class="required">*</span></label>', $class, $label );
break;
case 'description':
$description = isset( $field['description'] ) && ! empty( $field['description'] ) ? $field['description'] : '';
$description = strpos( $class, 'nl2br' ) !== false ? nl2br( $description ) : $description;
$output = sprintf( '<div class="description %s">%s</div>', $class, $description );
break;
case 'choices':
$fields_w_choices = array( 'checkbox', 'gdpr-checkbox', 'select', 'payment-select', 'radio', 'payment-multiple', 'payment-checkbox' );
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$dynamic = ! empty( $field['dynamic_choices'] ) ? $field['dynamic_choices'] : false;
$total = 0;
/*
* Check to see if this field is configured for Dynamic Choices,
* either auto populating from a post type or a taxonomy.
*/
if ( ! empty( $field['dynamic_post_type'] ) ) {
switch ( $dynamic ) {
case 'post_type':
// Post type dynamic populating.
$total_obj = wp_count_posts( $field['dynamic_post_type'] );
$total = isset( $total_obj->publish ) ? (int) $total_obj->publish : 0;
$values = array();
$posts = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_post_type_args',
array(
'post_type' => $field['dynamic_post_type'],
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
),
$field,
$this->form_id
),
true
);
foreach ( $posts as $post ) {
$values[] = array(
'label' => $post->post_title,
);
}
break;
case 'taxonomy':
// Taxonomy dynamic populating.
$total = (int) wp_count_terms( $field['dynamic_taxonomy'] );
$values = array();
$terms = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_taxonomy_args',
array(
'taxonomy' => $field['dynamic_taxonomy'],
'hide_empty' => false,
),
$field,
$this->form_id
),
true
);
foreach ( $terms as $term ) {
$values[] = array(
'label' => $term->name,
);
}
break;
}
}
// Notify if dynamic choices source is currently empty.
if ( empty( $values ) ) {
$values = array(
'label' => esc_html__( '(empty)', 'wpforms-lite' ),
);
}
// Build output.
if ( ! in_array( $field['type'], $fields_w_choices, true ) ) {
break;
}
switch ( $field['type'] ) {
case 'checkbox':
case 'gdpr-checkbox':
case 'payment-checkbox':
$type = 'checkbox';
break;
case 'select':
case 'payment-select':
$type = 'select';
break;
default:
$type = 'radio';
break;
}
$list_class = array( 'primary-input' );
$with_images = empty( $field['dynamic_choices'] ) && ! empty( $field['choices_images'] );
if ( $with_images ) {
$list_class[] = 'wpforms-image-choices';
$list_class[] = 'wpforms-image-choices-' . sanitize_html_class( $field['choices_images_style'] );
}
// Special rules for <select>-based fields.
if ( 'select' === $type ) {
$placeholder = ! empty( $field['placeholder'] ) ? $field['placeholder'] : '';
$output = sprintf(
'<select class="%s" disabled>',
wpforms_sanitize_classes( $list_class, true )
);
// Optional placeholder.
if ( ! empty( $placeholder ) ) {
$output .= sprintf(
'<option value="" class="placeholder">%s</option>',
esc_html( $placeholder )
);
}
// Build the select options (even though user can only see 1st option).
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? (bool) $value['default'] : false;
$selected = ! empty( $placeholder ) ? '' : selected( true, $default, false );
$output .= sprintf(
'<option %s>%s</option>',
$selected,
esc_html( $value['label'] )
);
}
$output .= '</select>';
} else {
// Normal checkbox/radio-based fields.
$output = sprintf(
'<ul class="%s">',
wpforms_sanitize_classes( $list_class, true )
);
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? $value['default'] : '';
$selected = checked( '1', $default, false );
$input_class = array();
$item_class = array();
if ( ! empty( $value['default'] ) ) {
$item_class[] = 'wpforms-selected';
}
if ( $with_images ) {
$item_class[] = 'wpforms-image-choices-item';
}
$output .= sprintf(
'<li class="%s">',
wpforms_sanitize_classes( $item_class, true )
);
if ( $with_images ) {
if ( in_array( $field['choices_images_style'], array( 'modern', 'classic' ), true ) ) {
$input_class[] = 'wpforms-screen-reader-element';
}
$output .= '<label>';
$output .= sprintf(
'<span class="wpforms-image-choices-image"><img src="%s" alt="%s"%s></span>',
! empty( $value['image'] ) ? esc_url( $value['image'] ) : WPFORMS_PLUGIN_URL . 'assets/images/placeholder-200x125.png',
esc_attr( $value['label'] ),
! empty( $value['label'] ) ? ' title="' . esc_attr( $value['label'] ) . '"' : ''
);
if ( 'none' === $field['choices_images_style'] ) {
$output .= '<br>';
}
$output .= sprintf(
'<input type="%s" class="%s" %s disabled>',
$type,
wpforms_sanitize_classes( $input_class, true ),
$selected
);
$output .= '<span class="wpforms-image-choices-label">' . wp_kses_post( $value['label'] ) . '</span>';
$output .= '</label>';
} else {
$output .= sprintf(
'<input type="%s" %s disabled>%s',
$type,
$selected,
$value['label']
);
}
$output .= '</li>';
}
$output .= '</ul>';
}
/*
* Dynamic population is enabled and contains more than 20 items,
* include a note about results displayed.
*/
if ( $total > 20 ) {
$output .= '<div class="wpforms-alert-dynamic wpforms-alert wpforms-alert-warning">';
$output .= sprintf(
wp_kses(
/* translators: %d - total amount of choices. */
__( 'Showing the first 20 choices.<br> All %d choices will be displayed when viewing the form.', 'wpforms-lite' ),
array(
'br' => array(),
)
),
$total
);
$output .= '</div>';
}
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Create a new field in the admin AJAX editor.
*
* @since 1.0.0
*/
public function field_new() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
die( esc_html__( 'You do not have permission.', 'wpforms-lite' ) );
}
// Check for form ID.
if ( ! isset( $_POST['id'] ) || empty( $_POST['id'] ) ) {
die( esc_html__( 'No form ID found', 'wpforms-lite' ) );
}
// Check for field type to add.
if ( ! isset( $_POST['type'] ) || empty( $_POST['type'] ) ) {
die( esc_html__( 'No field type found', 'wpforms-lite' ) );
}
// Grab field data.
$field_args = ! empty( $_POST['defaults'] ) ? (array) $_POST['defaults'] : array();
$field_type = esc_attr( $_POST['type'] );
$field_id = wpforms()->form->next_field_id( $_POST['id'] );
$field = array(
'id' => $field_id,
'type' => $field_type,
'label' => $this->name,
'description' => '',
);
$field = wp_parse_args( $field_args, $field );
$field = apply_filters( 'wpforms_field_new_default', $field );
$field_required = apply_filters( 'wpforms_field_new_required', '', $field );
$field_class = apply_filters( 'wpforms_field_new_class', '', $field );
// Field types that default to required.
if ( ! empty( $field_required ) ) {
$field_required = 'required';
$field['required'] = '1';
}
// Build Preview.
ob_start();
$this->field_preview( $field );
$prev = ob_get_clean();
$preview = sprintf( '<div class="wpforms-field wpforms-field-%s %s %s" id="wpforms-field-%d" data-field-id="%d" data-field-type="%s">', $field_type, $field_required, $field_class, $field['id'], $field['id'], $field_type );
$preview .= sprintf( '<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' ) );
$preview .= sprintf( '<a href="#" class="wpforms-field-delete" title="%s"><i class="fa fa-trash"></i></a>', esc_attr__( 'Delete Field', 'wpforms-lite' ) );
$preview .= sprintf( '<span class="wpforms-field-helper">%s</span>', esc_html__( 'Click to edit. Drag to reorder.', 'wpforms-lite' ) );
$preview .= $prev;
$preview .= '</div>';
// Build Options.
$options = sprintf( '<div class="wpforms-field-option wpforms-field-option-%s" id="wpforms-field-option-%d" data-field-id="%d">', esc_attr( $field['type'] ), $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][id]" value="%d" class="wpforms-field-option-hidden-id">', $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][type]" value="%s" class="wpforms-field-option-hidden-type">', $field['id'], esc_attr( $field['type'] ) );
ob_start();
$this->field_options( $field );
$options .= ob_get_clean();
$options .= '</div>';
// Prepare to return compiled results.
wp_send_json_success(
array(
'form_id' => (int) $_POST['id'],
'field' => $field,
'preview' => $preview,
'options' => $options,
)
);
}
/**
* Display the field input elements on the frontend.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
* @param array $field_atts Field attributes.
* @param array $form_data Form data and settings.
*/
abstract public function field_display( $field, $field_atts, $form_data );
/**
* Display field input errors if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param array $field Field data and settings.
*/
public function field_display_error( $key, $field ) {
// Need an error.
if ( empty( $field['properties']['error']['value'][ $key ] ) ) {
return;
}
printf(
'<label class="wpforms-error" for="%s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
esc_html( $field['properties']['error']['value'][ $key ] )
);
}
/**
* Display field input sublabel if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param string $position Sublabel position.
* @param array $field Field data and settings.
*/
public function field_display_sublabel( $key, $position, $field ) {
// Need a sublabel value.
if ( empty( $field['properties']['inputs'][ $key ]['sublabel']['value'] ) ) {
return;
}
$pos = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['position'] ) ? $field['properties']['inputs'][ $key ]['sublabel']['position'] : 'after';
$hidden = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['hidden'] ) ? 'wpforms-sublabel-hide' : '';
if ( $pos !== $position ) {
return;
}
printf(
'<label for="%s" class="wpforms-field-sublabel %s %s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
sanitize_html_class( $pos ),
$hidden,
$field['properties']['inputs'][ $key ]['sublabel']['value']
);
}
/**
* Validates field on form submit.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param array $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function validate( $field_id, $field_submit, $form_data ) {
// Basic required check - If field is marked as required, check for entry data.
if ( ! empty( $form_data['fields'][ $field_id ]['required'] ) && empty( $field_submit ) && '0' != $field_submit ) {
wpforms()->process->errors[ $form_data['id'] ][ $field_id ] = wpforms_get_required_label();
}
}
/**
* Formats and sanitizes field.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param mixed $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function format( $field_id, $field_submit, $form_data ) {
if ( is_array( $field_submit ) ) {
$field_submit = array_filter( $field_submit );
$field_submit = implode( "\r\n", $field_submit );
}
$name = ! empty( $form_data['fields'][ $field_id ]['label'] ) ? sanitize_text_field( $form_data['fields'][ $field_id ]['label'] ) : '';
// Sanitize but keep line breaks.
$value = wpforms_sanitize_textarea_field( $field_submit );
wpforms()->process->fields[ $field_id ] = array(
'name' => $name,
'value' => $value,
'id' => absint( $field_id ),
'type' => $this->type,
);
}
}
home/xbodynamge/dev/wp-content/plugins/wpforms-lite/includes/admin/builder/panels/class-base.php 0000644 00000010770 15114277102 0027157 0 ustar 00 <?php
/**
* Base panel class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
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 integer
*/
public $order = 50;
/**
* If panel contains a sidebar element or is full width.
*
* @since 1.0.0
* @var boolean
*/
public $sidebar = false;
/**
* Contains form object if we have one.
*
* @since 1.0.0
* @var object
*/
public $form;
/**
* Contains array of the form data (post_content).
*
* @since 1.0.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Load form if found.
$form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
$this->form = wpforms()->form->get( $form_id );
$this->form_data = $this->form ? wpforms_decode( $this->form->post_content ) : false;
// Bootstrap.
$this->init();
// Load panel specific enqueues.
add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ), 15 );
// Primary panel button.
add_action( 'wpforms_builder_panel_buttons', array( $this, 'button' ), $this->order, 2 );
// Output.
add_action( 'wpforms_builder_panels', array( $this, 'panel_output' ), $this->order, 2 );
}
/**
* 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
}
/**
* Outputs the contents of the panel.
*
* @since 1.0.0
*
* @param object $form
* @param string $view
*/
public function panel_output( $form, $view ) {
$active = $view === $this->slug ? 'active' : '';
$wrap = $this->sidebar ? 'wpforms-panel-sidebar-content' : 'wpforms-panel-full-content';
printf( '<div class="wpforms-panel %s" id="wpforms-panel-%s">', $active, esc_attr( $this->slug ) );
printf( '<div class="wpforms-panel-name">%s</div>', $this->name );
printf( '<div class="%s">', $wrap );
if ( true === $this->sidebar ) {
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>';
}
/**
* Outputs the panel's sidebar if we have one.
*
* @since 1.0.0
*/
public function panel_sidebar() {
}
/**
* Outputs panel sidebar sections.
*
* @since 1.0.0
*
* @param string $name
* @param string $slug
* @param string $icon
*/
public function panel_sidebar_section( $name, $slug, $icon = '' ) {
$class = '';
$class .= $slug === 'default' ? ' default' : '';
$class .= ! empty( $icon ) ? ' icon' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section wpforms-panel-sidebar-section-' . esc_attr( $slug ) . $class . '" 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>';
}
/**
* Outputs the panel's primary content.
*
* @since 1.0.0
*/
public function panel_content() {
}
}
home/xbodynamge/dev/wp-content/plugins/wpforms-lite/includes/admin/importers/class-base.php 0000644 00000007465 15114277202 0026303 0 ustar 00 <?php
/**
* Base Importer class.
*
* @package WPForms
* @author WPForms
* @since 1.4.2
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Importer implements WPForms_Importer_Interface {
/**
* Importer name.
*
* @since 1.4.2
*
* @var string
*/
public $name;
/**
* Importer name in slug format.
*
* @since 1.4.2
*
* @var string
*/
public $slug;
/**
* Importer plugin path.
*
* @since 1.4.2
*
* @var string
*/
public $path;
/**
* Primary class constructor.
*
* @since 1.4.2
*/
public function __construct() {
$this->init();
// Add to list of available importers.
add_filter( 'wpforms_importers', array( $this, 'register' ), 10, 1 );
// Return array of all available forms.
add_filter( "wpforms_importer_forms_{$this->slug}", array( $this, 'get_forms' ), 10, 1 );
// Import a specific form with AJAX.
add_action( "wp_ajax_wpforms_import_form_{$this->slug}", array( $this, 'import_form' ) );
}
/**
* Add to list of registered importers.
*
* @since 1.4.2
*
* @param array $importers List of supported importers.
*
* @return array
*/
public function register( $importers = array() ) {
$importers[ $this->slug ] = array(
'name' => $this->name,
'slug' => $this->slug,
'path' => $this->path,
'installed' => file_exists( trailingslashit( WP_PLUGIN_DIR ) . $this->path ),
'active' => $this->is_active(),
);
return $importers;
}
/**
* If the importer source is available.
*
* @since 1.4.2
*
* @return bool
*/
protected function is_active() {
return is_plugin_active( $this->path );
}
/**
* Add the new form to the database and return AJAX data.
*
* @since 1.4.2
*
* @param array $form Form to import.
* @param array $unsupported List of unsupported fields.
* @param array $upgrade_plain List of fields, that are supported inside the paid WPForms, but not in Lite.
* @param array $upgrade_omit No field alternative in WPForms.
*/
public function add_form( $form, $unsupported = array(), $upgrade_plain = array(), $upgrade_omit = array() ) {
// Create empty form so we have an ID to work with.
$form_id = wp_insert_post( array(
'post_status' => 'publish',
'post_type' => 'wpforms',
) );
if ( empty( $form_id ) || is_wp_error( $form_id ) ) {
wp_send_json_success( array(
'error' => true,
'name' => sanitize_text_field( $form['settings']['form_title'] ),
'msg' => esc_html__( 'There was an error while creating a new form.', 'wpforms-lite' ),
) );
}
$form['id'] = $form_id;
$form['field_id'] = count( $form['fields'] ) + 1;
// Update the form with all our compiled data.
wpforms()->form->update( $form_id, $form );
// Make note that this form has been imported.
$this->track_import( $form['settings']['import_form_id'], $form_id );
// Build and send final AJAX response!
wp_send_json_success( array(
'name' => $form['settings']['form_title'],
'edit' => esc_url_raw( admin_url( 'admin.php?page=wpforms-builder&view=fields&form_id=' . $form_id ) ),
'preview' => wpforms()->preview->form_preview_url( $form_id ),
'unsupported' => $unsupported,
'upgrade_plain' => $upgrade_plain,
'upgrade_omit' => $upgrade_omit,
) );
}
/**
* After a form has been successfully imported we track it, so that in the
* future we can alert users if they try to import a form that has already
* been imported.
*
* @since 1.4.2
*
* @param int $source_id Imported plugin form ID.
* @param int $wpforms_id WPForms form ID.
*/
public function track_import( $source_id, $wpforms_id ) {
$imported = get_option( 'wpforms_imported', array() );
$imported[ $this->slug ][ $wpforms_id ] = $source_id;
update_option( 'wpforms_imported', $imported, false );
}
}
home/xbodynamge/lebauwcentre/wp-content/plugins/wpforms-lite/includes/analytics/class-base.php 0000644 00000006557 15114316517 0027064 0 ustar 00 <?php
/**
* Analytics integration class.
*
* @package WPForms
* @author WPForms
* @since 1.4.5
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Analytics_Integration {
/**
* Payment name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Payment name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Payment icon.
*
* @since 1.0.0
* @var string
*/
public $icon;
/**
* Form data and settings.
*
* @since 1.1.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->init();
// Add to list of available analytics.
add_filter( 'wpforms_analytics_available', array( $this, 'register_analytics' ), $this->priority, 1 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_analytics_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_analytics_panel_content', array( $this, 'builder_output' ), $this->priority );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered analytics.
*
* @since 1.0.0
*
* @param array $analytics
*
* @return array
*/
public function register_analytics( $analytics = array() ) {
$analytics[ $this->slug ] = $this->name;
return $analytics;
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.1.0
*/
public function builder_form_data() {
$this->form_data = WPForms_Builder::instance()->form_data;
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$configured = ! empty( $this->form_data['analytics'][ $this->slug ]['enable'] ) ? 'configured' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . $configured . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<div class="wpforms-panel-content-section-title">
<?php echo esc_html( $this->name ); ?>
</div>
<div class="wpforms-payment-settings wpforms-clear">
<?php $this->builder_content(); ?>
</div>
</div>
<?php
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
}
}
xbodynamge/crosstraining/wp-content/plugins/wpforms-lite/includes/admin/importers/class-base.php 0000604 00000007465 15114320522 0030321 0 ustar 00 home <?php
/**
* Base Importer class.
*
* @package WPForms
* @author WPForms
* @since 1.4.2
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Importer implements WPForms_Importer_Interface {
/**
* Importer name.
*
* @since 1.4.2
*
* @var string
*/
public $name;
/**
* Importer name in slug format.
*
* @since 1.4.2
*
* @var string
*/
public $slug;
/**
* Importer plugin path.
*
* @since 1.4.2
*
* @var string
*/
public $path;
/**
* Primary class constructor.
*
* @since 1.4.2
*/
public function __construct() {
$this->init();
// Add to list of available importers.
add_filter( 'wpforms_importers', array( $this, 'register' ), 10, 1 );
// Return array of all available forms.
add_filter( "wpforms_importer_forms_{$this->slug}", array( $this, 'get_forms' ), 10, 1 );
// Import a specific form with AJAX.
add_action( "wp_ajax_wpforms_import_form_{$this->slug}", array( $this, 'import_form' ) );
}
/**
* Add to list of registered importers.
*
* @since 1.4.2
*
* @param array $importers List of supported importers.
*
* @return array
*/
public function register( $importers = array() ) {
$importers[ $this->slug ] = array(
'name' => $this->name,
'slug' => $this->slug,
'path' => $this->path,
'installed' => file_exists( trailingslashit( WP_PLUGIN_DIR ) . $this->path ),
'active' => $this->is_active(),
);
return $importers;
}
/**
* If the importer source is available.
*
* @since 1.4.2
*
* @return bool
*/
protected function is_active() {
return is_plugin_active( $this->path );
}
/**
* Add the new form to the database and return AJAX data.
*
* @since 1.4.2
*
* @param array $form Form to import.
* @param array $unsupported List of unsupported fields.
* @param array $upgrade_plain List of fields, that are supported inside the paid WPForms, but not in Lite.
* @param array $upgrade_omit No field alternative in WPForms.
*/
public function add_form( $form, $unsupported = array(), $upgrade_plain = array(), $upgrade_omit = array() ) {
// Create empty form so we have an ID to work with.
$form_id = wp_insert_post( array(
'post_status' => 'publish',
'post_type' => 'wpforms',
) );
if ( empty( $form_id ) || is_wp_error( $form_id ) ) {
wp_send_json_success( array(
'error' => true,
'name' => sanitize_text_field( $form['settings']['form_title'] ),
'msg' => esc_html__( 'There was an error while creating a new form.', 'wpforms-lite' ),
) );
}
$form['id'] = $form_id;
$form['field_id'] = count( $form['fields'] ) + 1;
// Update the form with all our compiled data.
wpforms()->form->update( $form_id, $form );
// Make note that this form has been imported.
$this->track_import( $form['settings']['import_form_id'], $form_id );
// Build and send final AJAX response!
wp_send_json_success( array(
'name' => $form['settings']['form_title'],
'edit' => esc_url_raw( admin_url( 'admin.php?page=wpforms-builder&view=fields&form_id=' . $form_id ) ),
'preview' => wpforms()->preview->form_preview_url( $form_id ),
'unsupported' => $unsupported,
'upgrade_plain' => $upgrade_plain,
'upgrade_omit' => $upgrade_omit,
) );
}
/**
* After a form has been successfully imported we track it, so that in the
* future we can alert users if they try to import a form that has already
* been imported.
*
* @since 1.4.2
*
* @param int $source_id Imported plugin form ID.
* @param int $wpforms_id WPForms form ID.
*/
public function track_import( $source_id, $wpforms_id ) {
$imported = get_option( 'wpforms_imported', array() );
$imported[ $this->slug ][ $wpforms_id ] = $source_id;
update_option( 'wpforms_imported', $imported, false );
}
}
xbodynamge/lebauwcentre/wp-content/plugins/wpforms-lite/includes/admin/builder/panels/class-base.php0000644 00000010770 15114321025 0030774 0 ustar 00 home <?php
/**
* Base panel class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
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 integer
*/
public $order = 50;
/**
* If panel contains a sidebar element or is full width.
*
* @since 1.0.0
* @var boolean
*/
public $sidebar = false;
/**
* Contains form object if we have one.
*
* @since 1.0.0
* @var object
*/
public $form;
/**
* Contains array of the form data (post_content).
*
* @since 1.0.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Load form if found.
$form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
$this->form = wpforms()->form->get( $form_id );
$this->form_data = $this->form ? wpforms_decode( $this->form->post_content ) : false;
// Bootstrap.
$this->init();
// Load panel specific enqueues.
add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ), 15 );
// Primary panel button.
add_action( 'wpforms_builder_panel_buttons', array( $this, 'button' ), $this->order, 2 );
// Output.
add_action( 'wpforms_builder_panels', array( $this, 'panel_output' ), $this->order, 2 );
}
/**
* 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
}
/**
* Outputs the contents of the panel.
*
* @since 1.0.0
*
* @param object $form
* @param string $view
*/
public function panel_output( $form, $view ) {
$active = $view === $this->slug ? 'active' : '';
$wrap = $this->sidebar ? 'wpforms-panel-sidebar-content' : 'wpforms-panel-full-content';
printf( '<div class="wpforms-panel %s" id="wpforms-panel-%s">', $active, esc_attr( $this->slug ) );
printf( '<div class="wpforms-panel-name">%s</div>', $this->name );
printf( '<div class="%s">', $wrap );
if ( true === $this->sidebar ) {
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>';
}
/**
* Outputs the panel's sidebar if we have one.
*
* @since 1.0.0
*/
public function panel_sidebar() {
}
/**
* Outputs panel sidebar sections.
*
* @since 1.0.0
*
* @param string $name
* @param string $slug
* @param string $icon
*/
public function panel_sidebar_section( $name, $slug, $icon = '' ) {
$class = '';
$class .= $slug === 'default' ? ' default' : '';
$class .= ! empty( $icon ) ? ' icon' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section wpforms-panel-sidebar-section-' . esc_attr( $slug ) . $class . '" 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>';
}
/**
* Outputs the panel's primary content.
*
* @since 1.0.0
*/
public function panel_content() {
}
}
home/xbodynamge/lebauwcentre/wp-content/plugins/wpforms-lite/includes/templates/class-base.php 0000644 00000010547 15114323245 0027061 0 ustar 00 <?php
/**
* Base form template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Template {
/**
* Full name of the template, eg "Contact Form".
*
* @since 1.0.0
* @var string
*/
public $name;
/**
* Slug of the template, eg "contact-form" - no spaces.
*
* @since 1.0.0
* @var string
*/
public $slug;
/**
* Short description the template.
*
* @since 1.0.0
* @var string
*/
public $description = '';
/**
* Short description of the fields included with the template.
*
* @since 1.0.0
* @var string
*/
public $includes = '';
/**
* URL of the icon to display in the admin area.
*
* @since 1.0.0
* @var string
*/
public $icon = '';
/**
* Array of data that is assigned to the post_content on form creation.
*
* @since 1.0.0
* @var array
*/
public $data;
/**
* Priority to show in the list of available templates.
*
* @since 1.0.0
* @var int
*/
public $priority = 20;
/**
* Core or additional template.
*
* @since 1.4.0
* @var bool
*/
public $core = false;
/**
* Modal message to display when the template is applied.
*
* @since 1.0.0
* @var array
*/
public $modal = '';
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Bootstrap.
$this->init();
$type = $this->core ? '_core' : '';
add_filter( "wpforms_form_templates{$type}", array( $this, 'template_details' ), $this->priority );
add_filter( 'wpforms_create_form_args', array( $this, 'template_data' ), 10, 2 );
add_filter( 'wpforms_save_form_args', array( $this, 'template_replace' ), 10, 3 );
add_filter( 'wpforms_builder_template_active', array( $this, 'template_active' ), 10, 2 );
}
/**
* Let's get started.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add basic template details to the Add New Form admin screen.
*
* @since 1.0.0
*
* @param array $templates
*
* @return array
*/
public function template_details( $templates ) {
$templates[] = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
);
return $templates;
}
/**
* Add template data when form is created.
*
* @since 1.0.0
*
* @param array $args
* @param array $data
*
* @return array
*/
public function template_data( $args, $data ) {
if ( ! empty( $data ) && ! empty( $data['template'] ) ) {
if ( $data['template'] === $this->slug ) {
$args['post_content'] = wpforms_encode( $this->data );
}
}
return $args;
}
/**
* Replace template on post update if triggered.
*
* @since 1.0.0
*
* @param array $form
* @param array $data
* @param array $args
*
* @return array
*/
public function template_replace( $form, $data, $args ) {
if ( ! empty( $args['template'] ) ) {
if ( $args['template'] === $this->slug ) {
$new = $this->data;
$new['settings'] = ! empty( $form['post_content']['settings'] ) ? $form['post_content']['settings'] : array();
$form['post_content'] = wpforms_encode( $new );
}
}
return $form;
}
/**
* Pass information about the active template back to the builder.
*
* @since 1.0.0
*
* @param array $details
* @param object $form
*
* @return array
*/
public function template_active( $details, $form ) {
if ( empty( $form ) ) {
return;
}
$form_data = wpforms_decode( $form->post_content );
if ( empty( $this->modal ) || empty( $form_data['meta']['template'] ) || $this->slug !== $form_data['meta']['template'] ) {
return $details;
} else {
$display = $this->template_modal_conditional( $form_data );
}
$template = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
'modal' => $this->modal,
'modal_display' => $display,
);
return $template;
}
/**
* Conditional to determine if the template informational modal screens
* should display.
*
* @since 1.0.0
*
* @param array $form_data Form data and settings.
*
* @return boolean
*/
public function template_modal_conditional( $form_data ) {
return false;
}
}
home/xbodynamge/lebauwcentre/wp-content/plugins/wpforms-lite/includes/admin/importers/class-base.php0000644 00000007455 15114336273 0030210 0 ustar 00 <?php
/**
* Base Importer class.
*
* @package WPForms
* @author WPForms
* @since 1.4.2
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Importer implements WPForms_Importer_Interface {
/**
* Importer name.
*
* @since 1.4.2
*
* @var string
*/
public $name;
/**
* Importer name in slug format.
*
* @since 1.4.2
*
* @var string
*/
public $slug;
/**
* Importer plugin path.
*
* @since 1.4.2
*
* @var string
*/
public $path;
/**
* Primary class constructor.
*
* @since 1.4.2
*/
public function __construct() {
$this->init();
// Add to list of available importers.
add_filter( 'wpforms_importers', array( $this, 'register' ), 10, 1 );
// Return array of all available forms.
add_filter( "wpforms_importer_forms_{$this->slug}", array( $this, 'get_forms' ), 10, 1 );
// Import a specific form with AJAX.
add_action( "wp_ajax_wpforms_import_form_{$this->slug}", array( $this, 'import_form' ) );
}
/**
* Add to list of registered importers.
*
* @since 1.4.2
*
* @param array $importers List of supported importers.
*
* @return array
*/
public function register( $importers = array() ) {
$importers[ $this->slug ] = array(
'name' => $this->name,
'slug' => $this->slug,
'path' => $this->path,
'installed' => file_exists( trailingslashit( WP_PLUGIN_DIR ) . $this->path ),
'active' => $this->is_active(),
);
return $importers;
}
/**
* If the importer source is available.
*
* @since 1.4.2
*
* @return bool
*/
protected function is_active() {
return is_plugin_active( $this->path );
}
/**
* Add the new form to the database and return AJAX data.
*
* @since 1.4.2
*
* @param array $form Form to import.
* @param array $unsupported List of unsupported fields.
* @param array $upgrade_plain List of fields, that are supported inside the paid WPForms, but not in Lite.
* @param array $upgrade_omit No field alternative in WPForms.
*/
public function add_form( $form, $unsupported = array(), $upgrade_plain = array(), $upgrade_omit = array() ) {
// Create empty form so we have an ID to work with.
$form_id = wp_insert_post( array(
'post_status' => 'publish',
'post_type' => 'wpforms',
) );
if ( empty( $form_id ) || is_wp_error( $form_id ) ) {
wp_send_json_success( array(
'error' => true,
'name' => sanitize_text_field( $form['settings']['form_title'] ),
'msg' => esc_html__( 'There was an error while creating a new form.', 'wpforms-lite' ),
) );
}
$form['id'] = $form_id;
$form['field_id'] = count( $form['fields'] ) + 1;
// Update the form with all our compiled data.
wpforms()->form->update( $form_id, $form );
// Make note that this form has been imported.
$this->track_import( $form['settings']['import_form_id'], $form_id );
// Build and send final AJAX response!
wp_send_json_success( array(
'name' => $form['settings']['form_title'],
'edit' => esc_url_raw( admin_url( 'admin.php?page=wpforms-builder&view=fields&form_id=' . $form_id ) ),
'preview' => wpforms_get_form_preview_url( $form_id ),
'unsupported' => $unsupported,
'upgrade_plain' => $upgrade_plain,
'upgrade_omit' => $upgrade_omit,
) );
}
/**
* After a form has been successfully imported we track it, so that in the
* future we can alert users if they try to import a form that has already
* been imported.
*
* @since 1.4.2
*
* @param int $source_id Imported plugin form ID.
* @param int $wpforms_id WPForms form ID.
*/
public function track_import( $source_id, $wpforms_id ) {
$imported = get_option( 'wpforms_imported', array() );
$imported[ $this->slug ][ $wpforms_id ] = $source_id;
update_option( 'wpforms_imported', $imported, false );
}
}
home/xbodynamge/lebauwcentre/wp-content/plugins/wpforms-lite/includes/providers/class-base.php 0000644 00000102364 15114437452 0027105 0 ustar 00 <?php
/**
* Provider class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Provider {
/**
* Provider addon version.
*
* @since 1.0.0
*
* @var string
*/
protected $version;
/**
* Provider name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Provider name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Holds the API connections.
*
* @since 1.0.0
*
* @var mixed
*/
public $api = false;
/**
* Service icon.
*
* @since 1.0.0
*
* @var string
*/
public $icon;
/**
* Service icon.
*
* @since 1.2.3
*
* @var string
*/
public $type;
/**
* Form data and settings.
*
* @since 1.2.3
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->type = esc_html__( 'Connection', 'wpforms-lite' );
$this->init();
// Add to list of available providers.
add_filter( 'wpforms_providers_available', array( $this, 'register_provider' ), $this->priority, 1 );
// Process builder AJAX requests.
add_action( "wp_ajax_wpforms_provider_ajax_{$this->slug}", array( $this, 'process_ajax' ) );
// Process entry.
add_action( 'wpforms_process_complete', array( $this, 'process_entry' ), 5, 4 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_providers_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_providers_panel_content', array( $this, 'builder_output' ), $this->priority );
// Remove provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_disconnect', array( $this, 'integrations_tab_disconnect' ) );
// Add new provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_add', array( $this, 'integrations_tab_add' ) );
// Add providers sections to the Settings Integrations tab.
add_action( 'wpforms_settings_providers', array( $this, 'integrations_tab_options' ), $this->priority, 2 );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered providers.
*
* @since 1.0.0
*
* @param array $providers Array of all active providers.
*
* @return array
*/
public function register_provider( $providers = array() ) {
$providers[ $this->slug ] = $this->name;
return $providers;
}
/**
* Process the Builder AJAX requests.
*
* @since 1.0.0
*/
public function process_ajax() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
$name = ! empty( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
$task = ! empty( $_POST['task'] ) ? sanitize_text_field( wp_unslash( $_POST['task'] ) ) : '';
$id = ! empty( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '';
$connection_id = ! empty( $_POST['connection_id'] ) ? sanitize_text_field( wp_unslash( $_POST['connection_id'] ) ) : '';
$account_id = ! empty( $_POST['account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) : '';
$list_id = ! empty( $_POST['list_id'] ) ? sanitize_text_field( wp_unslash( $_POST['list_id'] ) ) : '';
$data = ! empty( $_POST['data'] ) ? array_map( 'sanitize_text_field', wp_parse_args( wp_unslash( $_POST['data'] ) ) ) : array(); //phpcs:ignore
/*
* Create new connection.
*/
if ( 'new_connection' === $task ) {
$connection = $this->output_connection(
'',
array(
'connection_name' => $name,
),
$id
);
wp_send_json_success(
array(
'html' => $connection,
)
);
}
/*
* Create new Provider account.
*/
if ( 'new_account' === $task ) {
$auth = $this->api_auth( $data, $id );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => $auth->get_error_message(),
)
);
} else {
$accounts = $this->output_accounts(
$connection_id,
array(
'account_id' => $auth,
)
);
wp_send_json_success(
array(
'html' => $accounts,
)
);
}
}
/*
* Select/Toggle Provider accounts.
*/
if ( 'select_account' === $task ) {
$lists = $this->output_lists(
$connection_id,
array(
'account_id' => $account_id,
)
);
if ( is_wp_error( $lists ) ) {
wp_send_json_error(
array(
'error' => $lists->get_error_message(),
)
);
} else {
wp_send_json_success(
array(
'html' => $lists,
)
);
}
}
/*
* Select/Toggle Provider account lists.
*/
if ( 'select_list' === $task ) {
$fields = $this->output_fields(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
),
$id
);
if ( is_wp_error( $fields ) ) {
wp_send_json_error(
array(
'error' => $fields->get_error_message(),
)
);
} else {
$groups = $this->output_groups(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
)
);
$conditionals = $this->output_conditionals(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
),
array(
'id' => absint( $_POST['form_id'] ), //phpcs:ignore
)
);
$options = $this->output_options(
$connection_id,
array(
'account_id' => $account_id,
'list_id' => $list_id,
)
);
wp_send_json_success(
array(
'html' => $groups . $fields . $conditionals . $options,
)
);
}
}
die();
}
/**
* Process and submit entry to provider.
*
* @since 1.0.0
*
* @param array $fields List of fields in a form.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param int $entry_id Saved entry ID.
*/
public function process_entry( $fields, $entry, $form_data, $entry_id ) {
}
/**
* Process conditional fields.
*
* @since 1.0.0
*
* @param array $fields List of fields with their data and settings.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param array $connection List of connection settings.
*
* @return bool
*/
public function process_conditionals( $fields, $entry, $form_data, $connection ) {
if ( empty( $connection['conditional_logic'] ) || empty( $connection['conditionals'] ) ) {
return true;
}
$process = wpforms_conditional_logic()->process( $fields, $form_data, $connection['conditionals'] );
if ( ! empty( $connection['conditional_type'] ) && 'stop' === $connection['conditional_type'] ) {
$process = ! $process;
}
return $process;
}
/**
* Retrieve all available forms in a field.
*
* Not all fields should be available for merge tags so we compare against a
* white-list. Also some fields, such as Name, should have additional
* variations.
*
* @since 1.0.0
*
* @param object|bool $form
* @param array $whitelist
*
* @return bool|array
*/
public function get_form_fields( $form = false, $whitelist = array() ) {
// Accept form (post) object or form ID.
if ( is_object( $form ) ) {
$form = wpforms_decode( $form->post_content );
} elseif ( is_numeric( $form ) ) {
$form = wpforms()->form->get(
$form,
array(
'content_only' => true,
)
);
}
if ( ! is_array( $form ) || empty( $form['fields'] ) ) {
return false;
}
// White list of field types to allow.
$allowed_form_fields = array(
'text',
'textarea',
'select',
'radio',
'checkbox',
'email',
'address',
'url',
'name',
'hidden',
'date-time',
'phone',
'number',
);
$allowed_form_fields = apply_filters( 'wpforms_providers_fields', $allowed_form_fields );
$whitelist = ! empty( $whitelist ) ? $whitelist : $allowed_form_fields;
$form_fields = $form['fields'];
foreach ( $form_fields as $id => $form_field ) {
if ( ! in_array( $form_field['type'], $whitelist, true ) ) {
unset( $form_fields[ $id ] );
}
}
return $form_fields;
}
/**
* Get form fields ready for select list options.
*
* In this function we also do the logic to limit certain fields to certain
* provider field types.
*
* @since 1.0.0
*
* @param array $form_fields
* @param string $form_field_type
*
* @return array
*/
public function get_form_field_select( $form_fields = array(), $form_field_type = '' ) {
if ( empty( $form_fields ) || empty( $form_field_type ) ) {
return array();
}
$formatted = array();
// Include only specific field types.
foreach ( $form_fields as $id => $form_field ) {
// Email.
if (
'email' === $form_field_type &&
! in_array( $form_field['type'], array( 'text', 'email' ), true )
) {
unset( $form_fields[ $id ] );
}
// Address.
if (
'address' === $form_field_type &&
! in_array( $form_field['type'], array( 'address' ), true )
) {
unset( $form_fields[ $id ] );
}
}
// Format.
foreach ( $form_fields as $id => $form_field ) {
// Complex Name field.
if ( 'name' === $form_field['type'] ) {
// Full Name.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Full)', 'wpforms-lite' ),
$form_field['label']
),
);
// First Name.
if ( strpos( $form_field['format'], 'first' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'first',
'type' => $form_field['type'],
'subtype' => 'first',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (First)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Middle Name.
if ( strpos( $form_field['format'], 'middle' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'middle',
'type' => $form_field['type'],
'subtype' => 'middle',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Middle)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Last Name.
if ( strpos( $form_field['format'], 'last' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'last',
'type' => $form_field['type'],
'subtype' => 'last',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Last)', 'wpforms-lite' ),
$form_field['label']
),
);
}
} else {
// All other fields.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => $form_field['label'],
);
}
}
return $formatted;
}
/************************************************************************
* API methods - these methods interact directly with the provider API. *
************************************************************************/
/**
* Authenticate with the provider API.
*
* @since 1.0.0
*
* @param array $data
* @param string $form_id
*
* @return mixed id or error object
*/
public function api_auth( $data = array(), $form_id = '' ) {
}
/**
* Establish connection object to provider API.
*
* @since 1.0.0
*
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_connect( $account_id ) {
}
/**
* Retrieve provider account lists.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_lists( $connection_id = '', $account_id = '' ) {
}
/**
* Retrieve provider account list groups.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_groups( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/**
* Retrieve provider account list fields.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_fields( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/*************************************************************************
* Output methods - these methods generally return HTML for the builder. *
*************************************************************************/
/**
* Connection HTML.
*
* This method compiles all the HTML necessary for a connection to a provider.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form Form id or form data.
*
* @return string
*/
public function output_connection( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) ) {
$connection_id = 'connection_' . uniqid();
}
if ( empty( $connection ) || empty( $form ) ) {
return '';
}
$output = sprintf( '<div class="wpforms-provider-connection" data-provider="%s" data-connection_id="%s">', $this->slug, $connection_id );
$output .= $this->output_connection_header( $connection_id, $connection );
$output .= $this->output_auth();
$output .= $this->output_accounts( $connection_id, $connection );
$lists = $this->output_lists( $connection_id, $connection );
$output .= ! is_wp_error( $lists ) ? $lists : '';
$output .= $this->output_groups( $connection_id, $connection );
$fields = $this->output_fields( $connection_id, $connection, $form );
$output .= ! is_wp_error( $fields ) ? $fields : '';
$output .= $this->output_conditionals( $connection_id, $connection, $form );
$output .= $this->output_options( $connection_id, $connection );
$output .= '</div>';
return $output;
}
/**
* Connection header HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_connection_header( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$output = '<div class="wpforms-provider-connection-header">';
$output .= sprintf( '<span>%s</span>', sanitize_text_field( $connection['connection_name'] ) );
$output .= '<button class="wpforms-provider-connection-delete"><i class="fa fa-times-circle"></i></button>';
$output .= sprintf( '<input type="hidden" name="providers[%s][%s][connection_name]" value="%s">', $this->slug, $connection_id, esc_attr( $connection['connection_name'] ) );
$output .= '</div>';
return $output;
}
/**
* Provider account authorize fields HTML.
*
* @since 1.0.0
*
* @return mixed
*/
public function output_auth() {
}
/**
* Provider account select HTML.
*
* @since 1.0.0
*
* @param string $connection_id Unique connection ID.
* @param array $connection Array of connection data.
*
* @return string
*/
public function output_accounts( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$providers = wpforms_get_providers_options();
if ( empty( $providers[ $this->slug ] ) ) {
return '';
}
$output = '<div class="wpforms-provider-accounts wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Account', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][account_id]">', $this->slug, $connection_id );
foreach ( $providers[ $this->slug ] as $key => $provider_details ) {
$selected = ! empty( $connection['account_id'] ) ? $connection['account_id'] : '';
$output .= sprintf(
'<option value="%s" %s>%s</option>',
$key,
selected( $selected, $key, false ),
esc_html( $provider_details['label'] )
);
}
$output .= sprintf( '<option value="">%s</a>', esc_html__( 'Add New Account', 'wpforms-lite' ) );
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account lists HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return WP_Error|string
*/
public function output_lists( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) ) {
return '';
}
$lists = $this->api_lists( $connection_id, $connection['account_id'] );
$selected = ! empty( $connection['list_id'] ) ? $connection['list_id'] : '';
if ( is_wp_error( $lists ) ) {
return $lists;
}
$output = '<div class="wpforms-provider-lists wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select List', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][list_id]">', $this->slug, $connection_id );
if ( ! empty( $lists ) ) {
foreach ( $lists as $list ) {
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $list['id'] ),
selected( $selected, $list['id'], false ),
esc_attr( $list['name'] )
);
}
}
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account list groups HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_groups( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) ) {
return '';
}
$groupsets = $this->api_groups( $connection_id, $connection['account_id'], $connection['list_id'] );
if ( is_wp_error( $groupsets ) ) {
return '';
}
$output = '<div class="wpforms-provider-groups wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Groups', 'wpforms-lite' ) );
$output .= sprintf( '<p>%s</p>', esc_html__( 'We also noticed that you have some segments in your list. You can select specific list segments below if needed. This is optional.', 'wpforms-lite' ) );
$output .= '<div class="wpforms-provider-groups-list">';
foreach ( $groupsets as $groupset ) {
$output .= sprintf( '<p>%s</p>', esc_html( $groupset['name'] ) );
foreach ( $groupset['groups'] as $group ) {
$selected = ! empty( $connection['groups'] ) && ! empty( $connection['groups'][ $groupset['id'] ] ) ? in_array( $group['name'], $connection['groups'][ $groupset['id'] ], true ) : false;
$output .= sprintf(
'<span><input id="group_%s" type="checkbox" value="%s" name="providers[%s][%s][groups][%s][%s]" %s><label for="group_%s">%s</label></span>',
esc_attr( $group['id'] ),
esc_attr( $group['name'] ),
$this->slug,
$connection_id,
$groupset['id'],
$group['id'],
checked( $selected, true, false ),
esc_attr( $group['id'] ),
esc_attr( $group['name'] )
);
}
}
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* Provider account list fields HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form
*
* @return WP_Error|string
*/
public function output_fields( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) || empty( $form ) ) {
return '';
}
$provider_fields = $this->api_fields( $connection_id, $connection['account_id'], $connection['list_id'] );
$form_fields = $this->get_form_fields( $form );
if ( is_wp_error( $provider_fields ) ) {
return $provider_fields;
}
$output = '<div class="wpforms-provider-fields wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'List Fields', 'wpforms-lite' ) );
// Table with all the fields.
$output .= '<table>';
$output .= sprintf( '<thead><tr><th>%s</th><th>%s</th></thead>', esc_html__( 'List Fields', 'wpforms-lite' ), esc_html__( 'Available Form Fields', 'wpforms-lite' ) );
$output .= '<tbody>';
foreach ( $provider_fields as $provider_field ) :
$output .= '<tr>';
$output .= '<td>';
$output .= esc_html( $provider_field['name'] );
if (
! empty( $provider_field['req'] ) &&
$provider_field['req'] == '1'
) {
$output .= '<span class="required">*</span>';
}
$output .= '<td>';
$output .= sprintf( '<select name="providers[%s][%s][fields][%s]">', $this->slug, $connection_id, esc_attr( $provider_field['tag'] ) );
$output .= '<option value=""></option>';
$options = $this->get_form_field_select( $form_fields, $provider_field['field_type'] );
foreach ( $options as $option ) {
$value = sprintf( '%d.%s.%s', $option['id'], $option['key'], $option['provider_type'] );
$selected = ! empty( $connection['fields'][ $provider_field['tag'] ] ) ? selected( $connection['fields'][ $provider_field['tag'] ], $value, false ) : '';
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $value ), $selected, esc_html( $option['label'] ) );
}
$output .= '</select>';
$output .= '</td>';
$output .= '</tr>';
endforeach;
$output .= '</tbody>';
$output .= '</table>';
$output .= '</div>';
return $output;
}
/**
* Provider connection conditional options HTML
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param string|array $form
*
* @return string
*/
public function output_conditionals( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection['account_id'] ) ) {
return '';
}
return wpforms_conditional_logic()->builder_block(
array(
'form' => $this->form_data,
'type' => 'panel',
'panel' => $this->slug,
'parent' => 'providers',
'subsection' => $connection_id,
'reference' => esc_html__( 'Marketing provider connection', 'wpforms-lite' ),
),
false
);
}
/**
* Provider account list options HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_options( $connection_id = '', $connection = array() ) {
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.2.3
*/
public function builder_form_data() {
if ( ! empty( $_GET['form_id'] ) && empty( $this->form_data ) ) {
$this->form_data = wpforms()->form->get(
absint( $_GET['form_id'] ),
array(
'content_only' => true,
)
);
}
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
$form_data = $this->form_data;
$providers = wpforms_get_providers_options();
if ( ! empty( $form_data['providers'][ $this->slug ] ) && ! empty( $providers[ $this->slug ] ) ) {
foreach ( $form_data['providers'][ $this->slug ] as $connection_id => $connection ) {
foreach ( $providers[ $this->slug ] as $account_id => $connections ) {
if (
! empty( $connection['account_id'] ) &&
$connection['account_id'] === $account_id
) {
echo $this->output_connection( $connection_id, $connection, $form_data );
}
}
}
}
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$form_data = $this->form_data;
$configured = ! empty( $form_data['providers'][ $this->slug ] ) ? 'configured' : '';
$configured = apply_filters( 'wpforms_providers_' . $this->slug . '_configured', $configured );
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . esc_attr( $configured ) . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<?php $this->builder_output_before(); ?>
<div class="wpforms-panel-content-section-title">
<?php echo $this->name; ?>
<button class="wpforms-provider-connections-add" data-form_id="<?php echo absint( $_GET['form_id'] ); ?>"
data-provider="<?php echo esc_attr( $this->slug ); ?>"
data-type="<?php echo esc_attr( strtolower( $this->type ) ); ?>">
<?php
printf(
/* translators: %s - Provider type. */
esc_html__( 'Add New %s', 'wpforms-lite' ),
esc_html( $this->type )
);
?>
</button>
</div>
<div class="wpforms-provider-connections-wrap wpforms-clear">
<div class="wpforms-provider-connections">
<?php $this->builder_content(); ?>
</div>
</div>
<?php $this->builder_output_after(); ?>
</div>
<?php
}
/**
* Optionally output content before the main builder output.
*
* @since 1.3.6
*/
public function builder_output_before() {
}
/**
* Optionally output content after the main builder output.
*
* @since 1.3.6
*/
public function builder_output_after() {
}
/*************************************************************************
* Integrations tab methods - these methods relate to the settings page. *
*************************************************************************/
/**
* Form fields to add a new provider account.
*
* @since 1.0.0
*/
public function integrations_tab_new_form() {
}
/**
* AJAX to disconnect a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_disconnect() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['provider'] ) || empty( $_POST['key'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$providers = wpforms_get_providers_options();
if ( ! empty( $providers[ $_POST['provider'] ][ $_POST['key'] ] ) ) {
unset( $providers[ $_POST['provider'] ][ $_POST['key'] ] );
update_option( 'wpforms_providers', $providers );
wp_send_json_success();
} else {
wp_send_json_error(
array(
'error' => esc_html__( 'Connection missing', 'wpforms-lite' ),
)
);
}
}
/**
* AJAX to add a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_add() {
if ( $_POST['provider'] !== $this->slug ) { //phpcs:ignore
return;
}
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['data'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$data = wp_parse_args( $_POST['data'], array() );
$auth = $this->api_auth( $data, '' );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Could not connect to the provider.', 'wpforms-lite' ),
'error_msg' => $auth->get_error_message(),
)
);
} else {
$account = '<li class="wpforms-clear">';
$account .= '<span class="label">' . sanitize_text_field( $data['label'] ) . '</span>';
/* translators: %s - Connection date. */
$account .= '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format', time() ) ) ) . '</span>';
$account .= '<span class="remove"><a href="#" data-provider="' . $this->slug . '" data-key="' . esc_attr( $auth ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a></span>';
$account .= '</li>';
wp_send_json_success(
array(
'html' => $account,
)
);
}
}
/**
* Add provider to the Settings Integrations tab.
*
* @since 1.0.0
*
* @param array $active Array of active connections.
* @param array $settings Array of all connections settings.
*/
public function integrations_tab_options( $active, $settings ) {
$connected = ! empty( $active[ $this->slug ] );
$accounts = ! empty( $settings[ $this->slug ] ) ? $settings[ $this->slug ] : array();
$class = $connected && $accounts ? 'connected' : '';
$arrow = 'right';
/* translators: %s - provider name. */
$title_connect_to = sprintf( esc_html__( 'Connect to %s', 'wpforms-lite' ), esc_html( $this->name ) );
// This lets us highlight a specific service by a special link.
if ( ! empty( $_GET['wpforms-integration'] ) ) { //phpcs:ignore
if ( $this->slug === $_GET['wpforms-integration'] ) { //phpcs:ignore
$class .= ' focus-in';
$arrow = 'down';
} else {
$class .= ' focus-out';
}
}
?>
<div id="wpforms-integration-<?php echo esc_attr( $this->slug ); ?>" class="wpforms-settings-provider wpforms-clear <?php echo esc_attr( $this->slug ); ?> <?php echo esc_attr( $class ); ?>">
<div class="wpforms-settings-provider-header wpforms-clear" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-logo">
<i title="<?php esc_attr_e( 'Show Accounts', 'wpforms-lite' ); ?>" class="fa fa-chevron-<?php echo esc_attr( $arrow ); ?>"></i>
<img src="<?php echo esc_url( $this->icon ); ?>">
</div>
<div class="wpforms-settings-provider-info">
<h3><?php echo esc_html( $this->name ); ?></h3>
<p>
<?php
/* translators: %s - provider name. */
printf( esc_html__( 'Integrate %s with WPForms', 'wpforms-lite' ), esc_html( $this->name ) );
?>
</p>
<span class="connected-indicator green"><i class="fa fa-check-circle-o"></i> <?php esc_html_e( 'Connected', 'wpforms-lite' ); ?></span>
</div>
</div>
<div class="wpforms-settings-provider-accounts" id="provider-<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-accounts-list">
<ul>
<?php
if ( ! empty( $accounts ) ) {
foreach ( $accounts as $key => $account ) {
echo '<li class="wpforms-clear">';
echo '<span class="label">' . esc_html( $account['label'] ) . '</span>';
/* translators: %s - Connection date. */
echo '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format' ), intval( $account['date'] ) ) ) . '</span>';
echo '<span class="remove"><a href="#" data-provider="' . esc_attr( $this->slug ) . '" data-key="' . esc_attr( $key ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a></span>';
echo '</li>';
}
}
?>
</ul>
</div>
<p class="wpforms-settings-provider-accounts-toggle">
<a class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey" href="#" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<i class="fa fa-plus"></i> <?php esc_html_e( 'Add New Account', 'wpforms-lite' ); ?>
</a>
</p>
<div class="wpforms-settings-provider-accounts-connect">
<form>
<p><?php esc_html_e( 'Please fill out all of the fields below to add your new provider account.', 'wpforms-lite' ); ?></span></p>
<p class="wpforms-settings-provider-accounts-connect-fields">
<?php $this->integrations_tab_new_form(); ?>
</p>
<button type="submit" class="wpforms-btn wpforms-btn-md wpforms-btn-orange wpforms-settings-provider-connect"
data-provider="<?php echo esc_attr( $this->slug ); ?>" title="<?php echo esc_attr( $title_connect_to ); ?>">
<?php echo esc_html( $title_connect_to ); ?>
</button>
</form>
</div>
</div>
</div>
<?php
}
/**
* Error wrapper for WP_Error.
*
* @since 1.0.0
*
* @param string $message
* @param string $parent
*
* @return WP_Error
*/
public function error( $message = '', $parent = '0' ) {
return new WP_Error( $this->slug . '-error', $message );
}
}
home/xbodynamge/namtation/wp-content/plugins/wpforms-lite/includes/admin/importers/class-base.php 0000644 00000007455 15114440624 0027516 0 ustar 00 <?php
/**
* Base Importer class.
*
* @package WPForms
* @author WPForms
* @since 1.4.2
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Importer implements WPForms_Importer_Interface {
/**
* Importer name.
*
* @since 1.4.2
*
* @var string
*/
public $name;
/**
* Importer name in slug format.
*
* @since 1.4.2
*
* @var string
*/
public $slug;
/**
* Importer plugin path.
*
* @since 1.4.2
*
* @var string
*/
public $path;
/**
* Primary class constructor.
*
* @since 1.4.2
*/
public function __construct() {
$this->init();
// Add to list of available importers.
add_filter( 'wpforms_importers', array( $this, 'register' ), 10, 1 );
// Return array of all available forms.
add_filter( "wpforms_importer_forms_{$this->slug}", array( $this, 'get_forms' ), 10, 1 );
// Import a specific form with AJAX.
add_action( "wp_ajax_wpforms_import_form_{$this->slug}", array( $this, 'import_form' ) );
}
/**
* Add to list of registered importers.
*
* @since 1.4.2
*
* @param array $importers List of supported importers.
*
* @return array
*/
public function register( $importers = array() ) {
$importers[ $this->slug ] = array(
'name' => $this->name,
'slug' => $this->slug,
'path' => $this->path,
'installed' => file_exists( trailingslashit( WP_PLUGIN_DIR ) . $this->path ),
'active' => $this->is_active(),
);
return $importers;
}
/**
* If the importer source is available.
*
* @since 1.4.2
*
* @return bool
*/
protected function is_active() {
return is_plugin_active( $this->path );
}
/**
* Add the new form to the database and return AJAX data.
*
* @since 1.4.2
*
* @param array $form Form to import.
* @param array $unsupported List of unsupported fields.
* @param array $upgrade_plain List of fields, that are supported inside the paid WPForms, but not in Lite.
* @param array $upgrade_omit No field alternative in WPForms.
*/
public function add_form( $form, $unsupported = array(), $upgrade_plain = array(), $upgrade_omit = array() ) {
// Create empty form so we have an ID to work with.
$form_id = wp_insert_post( array(
'post_status' => 'publish',
'post_type' => 'wpforms',
) );
if ( empty( $form_id ) || is_wp_error( $form_id ) ) {
wp_send_json_success( array(
'error' => true,
'name' => sanitize_text_field( $form['settings']['form_title'] ),
'msg' => esc_html__( 'There was an error while creating a new form.', 'wpforms-lite' ),
) );
}
$form['id'] = $form_id;
$form['field_id'] = count( $form['fields'] ) + 1;
// Update the form with all our compiled data.
wpforms()->form->update( $form_id, $form );
// Make note that this form has been imported.
$this->track_import( $form['settings']['import_form_id'], $form_id );
// Build and send final AJAX response!
wp_send_json_success( array(
'name' => $form['settings']['form_title'],
'edit' => esc_url_raw( admin_url( 'admin.php?page=wpforms-builder&view=fields&form_id=' . $form_id ) ),
'preview' => wpforms_get_form_preview_url( $form_id ),
'unsupported' => $unsupported,
'upgrade_plain' => $upgrade_plain,
'upgrade_omit' => $upgrade_omit,
) );
}
/**
* After a form has been successfully imported we track it, so that in the
* future we can alert users if they try to import a form that has already
* been imported.
*
* @since 1.4.2
*
* @param int $source_id Imported plugin form ID.
* @param int $wpforms_id WPForms form ID.
*/
public function track_import( $source_id, $wpforms_id ) {
$imported = get_option( 'wpforms_imported', array() );
$imported[ $this->slug ][ $wpforms_id ] = $source_id;
update_option( 'wpforms_imported', $imported, false );
}
}
xbodynamge/namtation/wp-content/plugins/wpforms-lite/includes/admin/builder/panels/class-base.php 0000644 00000010770 15114445370 0030320 0 ustar 00 home <?php
/**
* Base panel class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
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 integer
*/
public $order = 50;
/**
* If panel contains a sidebar element or is full width.
*
* @since 1.0.0
* @var boolean
*/
public $sidebar = false;
/**
* Contains form object if we have one.
*
* @since 1.0.0
* @var object
*/
public $form;
/**
* Contains array of the form data (post_content).
*
* @since 1.0.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Load form if found.
$form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
$this->form = wpforms()->form->get( $form_id );
$this->form_data = $this->form ? wpforms_decode( $this->form->post_content ) : false;
// Bootstrap.
$this->init();
// Load panel specific enqueues.
add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ), 15 );
// Primary panel button.
add_action( 'wpforms_builder_panel_buttons', array( $this, 'button' ), $this->order, 2 );
// Output.
add_action( 'wpforms_builder_panels', array( $this, 'panel_output' ), $this->order, 2 );
}
/**
* 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
}
/**
* Outputs the contents of the panel.
*
* @since 1.0.0
*
* @param object $form
* @param string $view
*/
public function panel_output( $form, $view ) {
$active = $view === $this->slug ? 'active' : '';
$wrap = $this->sidebar ? 'wpforms-panel-sidebar-content' : 'wpforms-panel-full-content';
printf( '<div class="wpforms-panel %s" id="wpforms-panel-%s">', $active, esc_attr( $this->slug ) );
printf( '<div class="wpforms-panel-name">%s</div>', $this->name );
printf( '<div class="%s">', $wrap );
if ( true === $this->sidebar ) {
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>';
}
/**
* Outputs the panel's sidebar if we have one.
*
* @since 1.0.0
*/
public function panel_sidebar() {
}
/**
* Outputs panel sidebar sections.
*
* @since 1.0.0
*
* @param string $name
* @param string $slug
* @param string $icon
*/
public function panel_sidebar_section( $name, $slug, $icon = '' ) {
$class = '';
$class .= $slug === 'default' ? ' default' : '';
$class .= ! empty( $icon ) ? ' icon' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section wpforms-panel-sidebar-section-' . esc_attr( $slug ) . $class . '" 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>';
}
/**
* Outputs the panel's primary content.
*
* @since 1.0.0
*/
public function panel_content() {
}
}
home/xbodynamge/namtation/wp-content/plugins/wpforms-lite/includes/analytics/class-base.php 0000644 00000006557 15114524731 0026375 0 ustar 00 <?php
/**
* Analytics integration class.
*
* @package WPForms
* @author WPForms
* @since 1.4.5
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Analytics_Integration {
/**
* Payment name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Payment name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Payment icon.
*
* @since 1.0.0
* @var string
*/
public $icon;
/**
* Form data and settings.
*
* @since 1.1.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->init();
// Add to list of available analytics.
add_filter( 'wpforms_analytics_available', array( $this, 'register_analytics' ), $this->priority, 1 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_analytics_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_analytics_panel_content', array( $this, 'builder_output' ), $this->priority );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered analytics.
*
* @since 1.0.0
*
* @param array $analytics
*
* @return array
*/
public function register_analytics( $analytics = array() ) {
$analytics[ $this->slug ] = $this->name;
return $analytics;
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.1.0
*/
public function builder_form_data() {
$this->form_data = WPForms_Builder::instance()->form_data;
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$configured = ! empty( $this->form_data['analytics'][ $this->slug ]['enable'] ) ? 'configured' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . $configured . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<div class="wpforms-panel-content-section-title">
<?php echo esc_html( $this->name ); ?>
</div>
<div class="wpforms-payment-settings wpforms-clear">
<?php $this->builder_content(); ?>
</div>
</div>
<?php
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
}
}
home/xbodynamge/dev/wp-content/plugins/wpforms-lite/includes/analytics/class-base.php 0000644 00000006557 15114565422 0025163 0 ustar 00 <?php
/**
* Analytics integration class.
*
* @package WPForms
* @author WPForms
* @since 1.4.5
* @license GPL-2.0+
* @copyright Copyright (c) 2017, WPForms LLC
*/
abstract class WPForms_Analytics_Integration {
/**
* Payment name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Payment name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Payment icon.
*
* @since 1.0.0
* @var string
*/
public $icon;
/**
* Form data and settings.
*
* @since 1.1.0
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->init();
// Add to list of available analytics.
add_filter( 'wpforms_analytics_available', array( $this, 'register_analytics' ), $this->priority, 1 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_analytics_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_analytics_panel_content', array( $this, 'builder_output' ), $this->priority );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered analytics.
*
* @since 1.0.0
*
* @param array $analytics
*
* @return array
*/
public function register_analytics( $analytics = array() ) {
$analytics[ $this->slug ] = $this->name;
return $analytics;
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.1.0
*/
public function builder_form_data() {
$this->form_data = WPForms_Builder::instance()->form_data;
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$configured = ! empty( $this->form_data['analytics'][ $this->slug ]['enable'] ) ? 'configured' : '';
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . $configured . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<div class="wpforms-panel-content-section-title">
<?php echo esc_html( $this->name ); ?>
</div>
<div class="wpforms-payment-settings wpforms-clear">
<?php $this->builder_content(); ?>
</div>
</div>
<?php
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
}
}
home/xbodynamge/dev/wp-content/plugins/wpforms-lite/includes/fields/class-base.php 0000644 00000161025 15114650743 0024433 0 ustar 00 <?php
/**
* Base field template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Field {
/**
* Full name of the field type, eg "Paragraph Text".
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Type of the field, eg "textarea".
*
* @since 1.0.0
*
* @var string
*/
public $type;
/**
* 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 integer
*/
public $order = 1;
/**
* Field group the field belongs to.
*
* @since 1.0.0
*
* @var string
*/
public $group = 'standard';
/**
* Placeholder to hold default value(s) for some field types.
*
* @since 1.0.0
*
* @var mixed
*/
public $defaults;
/**
* Current form ID in the admin builder.
*
* @since 1.1.1
*
* @var int|bool
*/
public $form_id;
/**
* Current form data in.
*
* @since 1.1.1
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*
* @param bool $init Pass false to allow to shortcut the whole initialization, if needed.
*/
public function __construct( $init = true ) {
if ( ! $init ) {
return;
}
// The form ID is to be accessed in the builder.
$this->form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
// Bootstrap.
$this->init();
// Add fields tab.
add_filter( 'wpforms_builder_fields_buttons', array( $this, 'field_button' ), 15 );
// Field options tab.
add_action( "wpforms_builder_fields_options_{$this->type}", array( $this, 'field_options' ), 10 );
// Preview fields.
add_action( "wpforms_builder_fields_previews_{$this->type}", array( $this, 'field_preview' ), 10 );
// AJAX Add new field.
add_action( "wp_ajax_wpforms_new_field_{$this->type}", array( $this, 'field_new' ) );
// Display field input elements on front-end.
add_action( "wpforms_display_field_{$this->type}", array( $this, 'field_display' ), 10, 3 );
// Validation on submit.
add_action( "wpforms_process_validate_{$this->type}", array( $this, 'validate' ), 10, 3 );
// Format.
add_action( "wpforms_process_format_{$this->type}", array( $this, 'format' ), 10, 3 );
// Prefill.
add_filter( 'wpforms_field_properties', array( $this, 'field_prefill_value_property' ), 10, 3 );
}
/**
* All systems go. Used by subclasses. Required.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*/
abstract public function init();
/**
* Prefill field value with either fallback or dynamic data.
* Needs to be public (although internal) to be used in WordPress hooks.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
* @param array $form_data Prepared form data/settings.
*
* @return array Modified field properties.
*/
public function field_prefill_value_property( $properties, $field, $form_data ) {
// Process only for current field.
if ( $this->type !== $field['type'] ) {
return $properties;
}
// Set the form data, so we can reuse it later, even on front-end.
$this->form_data = $form_data;
// Dynamic data.
if ( ! empty( $this->form_data['settings']['dynamic_population'] ) ) {
$properties = $this->field_prefill_value_property_dynamic( $properties, $field );
}
// Fallback data, rewrites dynamic because user-submitted data is more important.
$properties = $this->field_prefill_value_property_fallback( $properties, $field );
return $properties;
}
/**
* As we are processing user submitted data - ignore all admin-defined defaults.
* Preprocess choices-related fields only.
*
* @since 1.5.0
*
* @param array $field Field data and settings.
* @param array $properties Properties we are modifying.
*/
protected function field_prefill_remove_choices_defaults( $field, &$properties ) {
if (
! empty( $field['dynamic_choices'] ) ||
! empty( $field['choices'] )
) {
array_walk_recursive(
$properties['inputs'],
function ( &$value, $key ) {
if ( 'default' === $key ) {
$value = false;
}
}
);
}
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_dynamic_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
// For dynamic population we require $_GET.
if ( empty( $_GET ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_dynamic_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a dynamic value, that we get from $_GET.
* The pattern is: wpf4_12_primary, where:
* 4 - form_id,
* 12 - field_id,
* first - input key.
* As 'primary' is our default input key, "wpf4_12_primary" and "wpf4_12" are the same.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_dynamic( $properties, $field ) {
if ( ! $this->is_dynamic_population_allowed( $properties, $field ) ) {
return $properties;
}
// Iterate over each GET key, parse, and scrap data from there.
foreach ( $_GET as $key => $raw_value ) { // phpcs:ignore
preg_match( '/wpf(\d+)_(\d+)(.*)/i', $key, $matches );
if ( empty( $matches ) || ! is_array( $matches ) ) {
continue;
}
// Required.
$form_id = absint( $matches[1] );
$field_id = absint( $matches[2] );
$input = 'primary';
// Optional.
if ( ! empty( $matches[3] ) ) {
$input = sanitize_key( trim( $matches[3], '_' ) );
}
// Both form and field IDs should be the same as current form/field.
if (
(int) $this->form_data['id'] !== $form_id ||
(int) $field['id'] !== $field_id
) {
// Go to the next GET param.
continue;
}
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* Some fields (like checkboxes) support multiple selection.
* We do not support nested values, so omit them.
* Example: ?wpf771_19_wpforms[fields][19][address1]=test
* In this case:
* $input = wpforms
* $raw_value = [fields=>[]]
* $single_value = [19=>[]]
* There is no reliable way to clean those things out.
* So we will ignore the value altogether if it's an array.
* We support only single value numeric arrays, like these:
* ?wpf771_19[]=test1&wpf771_19[]=test2
* ?wpf771_19_value[]=test1&wpf771_19_value[]=test2
* ?wpf771_41_r3_c2[]=1&wpf771_41_r1_c4[]=1
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, $input, $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, $input, $properties, $field );
}
}
return $properties;
}
/**
* Get the value, that is used to prefill via dynamic or fallback population.
* Based on field data and current properties.
*
* @since 1.5.0
*
* @param string $raw_value Value from a GET param, always a string.
* @param string $input Represent a subfield inside the field. May be empty.
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function get_field_populated_single_property_value( $raw_value, $input, $properties, $field ) {
if ( ! is_string( $raw_value ) ) {
return $properties;
}
$get_value = stripslashes( sanitize_text_field( $raw_value ) );
// For fields that have dynamic choices we need to add extra logic.
if ( ! empty( $field['dynamic_choices'] ) ) {
$default_key = null;
foreach ( $properties['inputs'] as $input_key => $input_arr ) {
// Dynamic choices support only integers in its values.
if ( absint( $get_value ) === $input_arr['attr']['value'] ) {
$default_key = $input_key;
// Stop iterating over choices.
break;
}
}
// Redefine default choice only if dynamic value has changed anything.
if ( null !== $default_key ) {
foreach ( $properties['inputs'] as $input_key => $choice_arr ) {
if ( $input_key === $default_key ) {
$properties['inputs'][ $input_key ]['default'] = true;
// Stop iterating over choices.
break;
}
}
}
} elseif ( ! empty( $field['choices'] ) && is_array( $field['choices'] ) ) {
$default_key = null;
// For fields that have normal choices we need to add extra logic.
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( isset( $field['show_values'] ) ) {
if (
isset( $choice_arr['value'] ) &&
strtoupper( $choice_arr['value'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
} else {
if (
isset( $choice_arr['label'] ) &&
strtoupper( $choice_arr['label'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
}
}
// Redefine default choice only if population value has changed anything.
if ( null !== $default_key ) {
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( $choice_key === $default_key ) {
$properties['inputs'][ $choice_key ]['default'] = true;
break;
}
}
}
} else {
/*
* For other types of fields we need to check that
* the key is registered for the defined field in inputs array.
*/
if (
! empty( $input ) &&
isset( $properties['inputs'][ $input ] )
) {
$properties['inputs'][ $input ]['attr']['value'] = $get_value;
}
}
return $properties;
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_fallback_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
/*
* Commented out to allow partial fail for complex multi-inputs fields.
* Example: name field with first/last format and being required, filled out only first.
* On submit we will preserve those sub-inputs that are not empty and display an error for an empty.
*/
// Do not populate if there are errors for that field.
/*
$errors = wpforms()->process->errors;
if ( ! empty( $errors[ $this->form_data['id'] ][ $field['id'] ] ) ) {
$allowed = false;
}
*/
// Require form id being the same for submitted and currently rendered form.
if (
! empty( $_POST['wpforms']['id'] ) && // phpcs:ignore
(int) $_POST['wpforms']['id'] !== (int) $this->form_data['id'] // phpcs:ignore
) {
$allowed = false;
}
// Require $_POST of submitted field.
if ( empty( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
$allowed = false;
}
// Require field (processed and rendered) being the same.
if ( ! isset( $_POST['wpforms']['fields'][ $field['id'] ] ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_fallback_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a fallback value from form submission (in case of JS validation failed), that we get from $_POST.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_fallback( $properties, $field ) {
if ( ! $this->is_fallback_population_allowed( $properties, $field ) ) {
return $properties;
}
if ( empty( $_POST['wpforms']['fields'] ) || ! is_array( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
return $properties;
}
// We got user submitted raw data (not processed, will be done later).
$raw_value = $_POST['wpforms']['fields'][ $field['id'] ]; // phpcs:ignore
$input = 'primary';
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* For this particular field this value may be either array or a string.
* In array - this is a complex field, like address.
* The key in array will be a sub-input (address1, state), and its appropriate value.
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $input => $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, sanitize_key( $input ), $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, sanitize_key( $input ), $properties, $field );
}
return $properties;
}
/**
* Create the button for the 'Add Fields' tab, inside the form editor.
*
* @since 1.0.0
*
* @param array $fields List of form fields with their data.
*
* @return array
*/
public function field_button( $fields ) {
// Add field information to fields array.
$fields[ $this->group ]['fields'][] = array(
'order' => $this->order,
'name' => $this->name,
'type' => $this->type,
'icon' => $this->icon,
);
// Wipe hands clean.
return $fields;
}
/**
* Creates the field options panel. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_options( $field );
/**
* Creates the field preview. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_preview( $field );
/**
* Helper function to create field option elements.
*
* Field option elements are pieces that help create a field option.
* They are used to quickly build field options.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_element( $option, $field, $args = array(), $echo = true ) {
$id = (int) $field['id'];
$class = ! empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
$slug = ! empty( $args['slug'] ) ? sanitize_title( $args['slug'] ) : '';
$data = '';
$output = '';
if ( ! empty( $args['data'] ) ) {
foreach ( $args['data'] as $arg_key => $val ) {
if ( is_array( $val ) ) {
$val = wp_json_encode( $val );
}
$data .= ' data-' . $arg_key . '=\'' . $val . '\'';
}
}
switch ( $option ) {
// Row.
case 'row':
$output = sprintf(
'<div class="wpforms-field-option-row wpforms-field-option-row-%s %s" id="wpforms-field-option-row-%d-%s" data-field-id="%d">%s</div>',
$slug,
$class,
$id,
$slug,
$id,
$args['content']
);
break;
// Label.
case 'label':
$output = sprintf( '<label for="wpforms-field-option-%d-%s">%s', $id, $slug, esc_html( $args['value'] ) );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
if ( isset( $args['after_tooltip'] ) && ! empty( $args['after_tooltip'] ) ) {
$output .= $args['after_tooltip'];
}
$output .= '</label>';
break;
// Text input.
case 'text':
$type = ! empty( $args['type'] ) ? esc_attr( $args['type'] ) : 'text';
$placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : '';
$before = ! empty( $args['before'] ) ? '<span class="before-input">' . esc_html( $args['before'] ) . '</span>' : '';
if ( ! empty( $before ) ) {
$class .= ' has-before';
}
$output = sprintf( '%s<input type="%s" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="%s" placeholder="%s" %s>', $before, $type, $class, $id, $slug, $id, $slug, esc_attr( $args['value'] ), $placeholder, $data );
break;
// Textarea.
case 'textarea':
$rows = ! empty( $args['rows'] ) ? (int) $args['rows'] : '3';
$output = sprintf( '<textarea class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" rows="%d" %s>%s</textarea>', $class, $id, $slug, $id, $slug, $rows, $data, $args['value'] );
break;
// Checkbox.
case 'checkbox':
$checked = checked( '1', $args['value'], false );
$output = sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s>', $class, $id, $slug, $id, $slug, $checked, $data );
$output .= sprintf( '<label for="wpforms-field-option-%d-%s" class="inline">%s', $id, $slug, $args['desc'] );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
$output .= '</label>';
break;
// Toggle.
case 'toggle':
$checked = checked( '1', $args['value'], false );
$icon = $args['value'] ? 'fa-toggle-on' : 'fa-toggle-off';
$cls = $args['value'] ? 'wpforms-on' : 'wpforms-off';
$status = $args['value'] ? esc_html__( 'On', 'wpforms-lite' ) : esc_html__( 'Off', 'wpforms-lite' );
$output = sprintf( '<span class="wpforms-toggle-icon %s"><i class="fa %s" aria-hidden="true"></i> <span class="wpforms-toggle-icon-label">%s</span>', $cls, $icon, $status );
$output .= sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s></span>', $class, $id, $slug, $id, $slug, $checked, $data );
break;
// Select.
case 'select':
$options = $args['options'];
$value = isset( $args['value'] ) ? $args['value'] : '';
$output = sprintf( '<select class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" %s>', $class, $id, $slug, $id, $slug, $data );
foreach ( $options as $arg_key => $arg_option ) {
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $arg_key ), selected( $arg_key, $value, false ), $arg_option );
}
$output .= '</select>';
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Helper function to create common field options that are used frequently.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_option( $option, $field, $args = array(), $echo = true ) {
switch ( $option ) {
/**
* Basic Fields.
*/
/*
* Basic Options markup.
*/
case 'basic-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
if ( 'open' === $markup ) {
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-basic" id="wpforms-field-option-basic-%d">', $field['id'] );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <span>(ID #%d)</span> <i class="fa fa-angle-down"></i></a>', $this->name, $field['id'] );
$output .= sprintf( '<div class="wpforms-field-option-group-inner %s">', $class );
} else {
$output = '</div></div>';
}
break;
/*
* Field Label.
*/
case 'label':
$value = ! empty( $field['label'] ) ? esc_attr( $field['label'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field label. Field labels are recommended and can be hidden in the Advanced Settings.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'label', 'value' => esc_html__( 'Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'label', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label', 'content' => $output ), false );
break;
/*
* Field Description.
*/
case 'description':
$value = ! empty( $field['description'] ) ? esc_attr( $field['description'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field description.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'description', 'value' => esc_html__( 'Description', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'description', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'description', 'content' => $output ), false );
break;
/*
* Field Required toggle.
*/
case 'required':
$default = ! empty( $args['default'] ) ? $args['default'] : '0';
$value = isset( $field['required'] ) ? $field['required'] : $default;
$tooltip = esc_html__( 'Check this option to mark the field required. A form will not submit unless all required fields are provided.', 'wpforms-lite' );
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'required', 'value' => $value, 'desc' => esc_html__( 'Required', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'required', 'content' => $output ), false );
break;
/*
* Field Meta (field type and ID).
*/
case 'meta':
$output = sprintf( '<label>%s</label>', 'Type' );
$output .= sprintf( '<p class="meta">%s <span class="id">(ID #%d)</span></p>', $this->name, $field['id'] );
$output = $this->field_element( 'row', $field, array( 'slug' => 'meta', 'content' => $output ), false );
break;
/*
* Code Block.
*/
case 'code':
$value = ! empty( $field['code'] ) ? esc_textarea( $field['code'] ) : '';
$tooltip = esc_html__( 'Enter code for the form field.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'code', 'value' => esc_html__( 'Code', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'code', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'code', 'content' => $output ), false );
break;
/*
* Choices.
*/
case 'choices':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$label = ! empty( $args['label'] ) ? esc_html( $args['label'] ) : esc_html__( 'Choices', 'wpforms-lite' );
$class = array();
if ( ! empty( $field['show_values'] ) ) {
$class[] = 'show-values';
}
if ( ! empty( $field['dynamic_choices'] ) ) {
$class[] = 'wpforms-hidden';
}
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => $label,
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
'after_tooltip' => '<a href="#" class="toggle-bulk-add-display"><i class="fa fa-download"></i> <span>' . esc_html__( 'Bulk Add', 'wpforms-lite' ) . '</span></a>',
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="%s" name="%s[default]" class="default" value="1" %s>',
'checkbox' === $this->type ? 'checkbox' : 'radio',
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value">',
$base,
esc_attr( $value['value'] )
);
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Field note: dynamic status.
$source = '';
$type = '';
$dynamic = ! empty( $field['dynamic_choices'] ) ? esc_html( $field['dynamic_choices'] ) : '';
if ( 'post_type' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'post type', 'wpforms-lite' );
$pt = get_post_type_object( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( null !== $pt ) {
$source = $pt->labels->name;
}
} elseif ( 'taxonomy' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'taxonomy', 'wpforms-lite' );
$tax = get_taxonomy( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( false !== $tax ) {
$source = $tax->labels->name;
}
}
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
empty( $dynamic ) && ! empty( $field[ 'dynamic_' . $dynamic ] ) ? '' : 'wpforms-hidden'
);
$note .= sprintf(
/* translators: %1$s - source name; %2$s - type name. */
esc_html__( 'Choices are dynamically populated from the %1$s %2$s.', 'wpforms' ),
'<span class="dynamic-name">' . $source . '</span>',
'<span class="dynamic-type">' . $type . '</span>'
);
$note .= '</div>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld . $note,
),
false
);
break;
/*
* Choices for payments.
*/
case 'choices_payments':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$class = array();
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => esc_html__( 'Items', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="radio" name="%s[default]" class="default" value="1" %s>',
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value value wpforms-money-input" placeholder="%s">',
$base,
esc_attr( $value['value'] ),
wpforms_format_amount( 0 )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld,
),
false
);
break;
/*
* Choices Images.
*/
case 'choices_images':
// Field note: Image tips.
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden'
);
$note .= esc_html__( 'Images are not cropped or resized. For best results, they should be the same size and 250x250 pixels or smaller.', 'wpforms-lite' );
$note .= '</div>';
// Field contents.
$fld = $this->field_element(
'checkbox',
$field,
array(
'slug' => 'choices_images',
'value' => isset( $field['choices_images'] ) ? '1' : '0',
'desc' => esc_html__( 'Use image choices', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Check this option to enable using images with the choices.', 'wpforms-lite' ),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images',
'class' => ! empty( $field['dynamic_choices'] ) ? 'wpforms-hidden' : '',
'content' => $note . $fld,
),
false
);
break;
/*
* Choices Images Style.
*/
case 'choices_images_style':
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices_images_style',
'value' => esc_html__( 'Image Choice Style', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Select the style for the image choices.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = $this->field_element(
'select',
$field,
array(
'slug' => 'choices_images_style',
'value' => ! empty( $field['choices_images_style'] ) ? esc_attr( $field['choices_images_style'] ) : 'modern',
'options' => array(
'modern' => esc_html__( 'Modern', 'wpforms-lite' ),
'classic' => esc_html__( 'Classic', 'wpforms-lite' ),
'none' => esc_html__( 'None', 'wpforms-lite' ),
),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images_style',
'content' => $lbl . $fld,
'class' => ! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden',
),
false
);
break;
/**
* Advanced Fields.
*/
/*
* Default value.
*/
case 'default_value':
$value = ! empty( $field['default_value'] ) ? esc_attr( $field['default_value'] ) : '';
$tooltip = esc_html__( 'Enter text for the default form field value.', 'wpforms-lite' );
$toggle = '<a href="#" class="toggle-smart-tag-display" data-type="other"><i class="fa fa-tags"></i> <span>' . esc_html__( 'Show Smart Tags', 'wpforms-lite' ) . '</span></a>';
$output = $this->field_element( 'label', $field, array( 'slug' => 'default_value', 'value' => esc_html__( 'Default Value', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'default_value', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'default_value', 'content' => $output ), false );
break;
/*
* Size.
*/
case 'size':
$value = ! empty( $field['size'] ) ? esc_attr( $field['size'] ) : 'medium';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
$tooltip = esc_html__( 'Select the default form field size.', 'wpforms-lite' );
$options = array(
'small' => esc_html__( 'Small', 'wpforms-lite' ),
'medium' => esc_html__( 'Medium', 'wpforms-lite' ),
'large' => esc_html__( 'Large', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'size', 'value' => esc_html__( 'Field Size', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'size', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'size', 'content' => $output, 'class' => $class ), false );
break;
/*
* Advanced Options markup.
*/
case 'advanced-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
if ( 'open' === $markup ) {
$override = apply_filters( 'wpforms_advanced_options_override', false );
$override = ! empty( $override ) ? 'style="display:' . $override . ';"' : '';
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-advanced wpforms-hide" id="wpforms-field-option-advanced-%d" %s>', $field['id'], $override );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <i class="fa fa-angle-right"></i></a>', esc_html__( 'Advanced Options', 'wpforms-lite' ) );
$output .= '<div class="wpforms-field-option-group-inner">';
} else {
$output = '</div></div>';
}
break;
/*
* Placeholder.
*/
case 'placeholder':
$value = ! empty( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field placeholder.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'placeholder', 'value' => esc_html__( 'Placeholder Text', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'placeholder', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'placeholder', 'content' => $output ), false );
break;
/*
* CSS classes.
*/
case 'css':
$toggle = '';
$value = ! empty( $field['css'] ) ? esc_attr( $field['css'] ) : '';
$tooltip = esc_html__( 'Enter CSS class names for the form field container. Class names should be separated with spaces.', 'wpforms-lite' );
if ( 'pagebreak' !== $field['type'] ) {
$toggle = '<a href="#" class="toggle-layout-selector-display"><i class="fa fa-th-large"></i> <span>' . esc_html__( 'Show Layouts', 'wpforms-lite' ) . '</span></a>';
}
// Build output.
$output = $this->field_element( 'label', $field, array( 'slug' => 'css', 'value' => esc_html__( 'CSS Classes', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'css', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'css', 'content' => $output ), false );
break;
/*
* Hide Label.
*/
case 'label_hide':
$value = isset( $field['label_hide'] ) ? $field['label_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'label_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label_hide', 'content' => $output ), false );
break;
/*
* Hide Sub-Labels.
*/
case 'sublabel_hide':
$value = isset( $field['sublabel_hide'] ) ? $field['sublabel_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field sub-label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'sublabel_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Sub-Labels', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'sublabel_hide', 'content' => $output ), false );
break;
/*
* Input Columns.
*/
case 'input_columns':
$value = ! empty( $field['input_columns'] ) ? esc_attr( $field['input_columns'] ) : '';
$tooltip = esc_html__( 'Select the layout for displaying field choices.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'One Column', 'wpforms-lite' ),
'2' => esc_html__( 'Two Columns', 'wpforms-lite' ),
'3' => esc_html__( 'Three Columns', 'wpforms-lite' ),
'inline' => esc_html__( 'Inline', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'input_columns', 'value' => esc_html__( 'Choice Layout', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'input_columns', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'input_columns', 'content' => $output ), false );
break;
/*
* Dynamic Choices.
*/
case 'dynamic_choices':
$value = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
$tooltip = esc_html__( 'Select auto-populate method to use.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'Off', 'wpforms-lite' ),
'post_type' => esc_html__( 'Post Type', 'wpforms-lite' ),
'taxonomy' => esc_html__( 'Taxonomy', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'dynamic_choices', 'value' => esc_html__( 'Dynamic Choices', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'dynamic_choices', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'dynamic_choices', 'content' => $output ), false );
break;
/*
* Dynamic Choices Source.
*/
case 'dynamic_choices_source':
$output = '';
$type = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
if ( ! empty( $type ) ) {
$type_name = '';
$items = array();
if ( 'post_type' === $type ) {
$type_name = esc_html__( 'Post Type', 'wpforms-lite' );
$items = get_post_types(
array(
'public' => true,
),
'objects'
);
unset( $items['attachment'] );
} elseif ( 'taxonomy' === $type ) {
$type_name = esc_html__( 'Taxonomy', 'wpforms-lite' );
$items = get_taxonomies(
array(
'public' => true,
),
'objects'
);
unset( $items['post_format'] );
}
/* translators: %s - dynamic source type name. */
$tooltip = sprintf( esc_html__( 'Select %s to use for auto-populating field choices.', 'wpforms-lite' ), $type_name );
/* translators: %s - dynamic source type name. */
$label = sprintf( esc_html__( 'Dynamic %s Source', 'wpforms-lite' ), $type_name );
$options = array();
$source = ! empty( $field[ 'dynamic_' . $type ] ) ? esc_attr( $field[ 'dynamic_' . $type ] ) : '';
foreach ( $items as $key => $item ) {
$options[ $key ] = $item->labels->name;
}
// Field option label.
$option_label = $this->field_element(
'label',
$field,
array(
'slug' => 'dynamic_' . $type,
'value' => $label,
'tooltip' => $tooltip,
),
false
);
// Field option select input.
$option_input = $this->field_element(
'select',
$field,
array(
'slug' => 'dynamic_' . $type,
'options' => $options,
'value' => $source,
),
false
);
// Field option row (markup) including label and input.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'dynamic_' . $type,
'content' => $option_label . $option_input,
),
false
);
} // End if().
break;
}
if ( ! $echo ) {
return $output;
}
if ( in_array( $option, array( 'basic-options', 'advanced-options' ), true ) ) {
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_before_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_bottom_{$option}", $field, $this );
}
echo $output; // WPCS: XSS ok.
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_top_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_after_{$option}", $field, $this );
}
} else {
echo $output; // WPCS: XSS ok.
}
}
/**
* Helper function to create common field options that are used frequently
* in the field preview.
*
* @since 1.0.0
* @since 1.5.0 Added support for <select> HTML tag for choices.
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed Print or return a string.
*/
public function field_preview_option( $option, $field, $args = array(), $echo = true ) {
$output = '';
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
switch ( $option ) {
case 'label':
$label = isset( $field['label'] ) && ! empty( $field['label'] ) ? esc_html( $field['label'] ) : '';
$output = sprintf( '<label class="label-title %s"><span class="text">%s</span><span class="required">*</span></label>', $class, $label );
break;
case 'description':
$description = isset( $field['description'] ) && ! empty( $field['description'] ) ? $field['description'] : '';
$description = strpos( $class, 'nl2br' ) !== false ? nl2br( $description ) : $description;
$output = sprintf( '<div class="description %s">%s</div>', $class, $description );
break;
case 'choices':
$fields_w_choices = array( 'checkbox', 'gdpr-checkbox', 'select', 'payment-select', 'radio', 'payment-multiple' );
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$dynamic = ! empty( $field['dynamic_choices'] ) ? $field['dynamic_choices'] : false;
$total = 0;
/*
* Check to see if this field is configured for Dynamic Choices,
* either auto populating from a post type or a taxonomy.
*/
if ( ! empty( $field['dynamic_post_type'] ) ) {
switch ( $dynamic ) {
case 'post_type':
// Post type dynamic populating.
$total_obj = wp_count_posts( $field['dynamic_post_type'] );
$total = isset( $total_obj->publish ) ? (int) $total_obj->publish : 0;
$values = array();
$posts = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_post_type_args',
array(
'post_type' => $field['dynamic_post_type'],
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
),
$field,
$this->form_id
),
true
);
foreach ( $posts as $post ) {
$values[] = array(
'label' => $post->post_title,
);
}
break;
case 'taxonomy':
// Taxonomy dynamic populating.
$total = (int) wp_count_terms( $field['dynamic_taxonomy'] );
$values = array();
$terms = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_taxonomy_args',
array(
'taxonomy' => $field['dynamic_taxonomy'],
'hide_empty' => false,
),
$field,
$this->form_id
),
true
);
foreach ( $terms as $term ) {
$values[] = array(
'label' => $term->name,
);
}
break;
}
}
// Notify if dynamic choices source is currently empty.
if ( empty( $values ) ) {
$values = array(
'label' => esc_html__( '(empty)', 'wpforms-lite' ),
);
}
// Build output.
if ( ! in_array( $field['type'], $fields_w_choices, true ) ) {
break;
}
switch ( $field['type'] ) {
case 'checkbox':
case 'gdpr-checkbox':
$type = 'checkbox';
break;
case 'select':
case 'payment-select':
$type = 'select';
break;
default:
$type = 'radio';
break;
}
$list_class = array( 'primary-input' );
$with_images = empty( $field['dynamic_choices'] ) && ! empty( $field['choices_images'] );
if ( $with_images ) {
$list_class[] = 'wpforms-image-choices';
$list_class[] = 'wpforms-image-choices-' . sanitize_html_class( $field['choices_images_style'] );
}
// Special rules for <select>-based fields.
if ( 'select' === $type ) {
$placeholder = ! empty( $field['placeholder'] ) ? $field['placeholder'] : '';
$output = sprintf(
'<select class="%s" disabled>',
wpforms_sanitize_classes( $list_class, true )
);
// Optional placeholder.
if ( ! empty( $placeholder ) ) {
$output .= sprintf(
'<option value="" class="placeholder">%s</option>',
esc_html( $placeholder )
);
}
// Build the select options (even though user can only see 1st option).
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? (bool) $value['default'] : false;
$selected = ! empty( $placeholder ) ? '' : selected( true, $default, false );
$output .= sprintf(
'<option %s>%s</option>',
$selected,
esc_html( $value['label'] )
);
}
$output .= '</select>';
} else {
// Normal checkbox/radio-based fields.
$output = sprintf(
'<ul class="%s">',
wpforms_sanitize_classes( $list_class, true )
);
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? $value['default'] : '';
$selected = checked( '1', $default, false );
$input_class = array();
$item_class = array();
if ( ! empty( $value['default'] ) ) {
$item_class[] = 'wpforms-selected';
}
if ( $with_images ) {
$item_class[] = 'wpforms-image-choices-item';
}
$output .= sprintf(
'<li class="%s">',
wpforms_sanitize_classes( $item_class, true )
);
if ( $with_images ) {
if ( in_array( $field['choices_images_style'], array( 'modern', 'classic' ), true ) ) {
$input_class[] = 'wpforms-screen-reader-element';
}
$output .= '<label>';
$output .= sprintf(
'<span class="wpforms-image-choices-image"><img src="%s" alt="%s"%s></span>',
! empty( $value['image'] ) ? esc_url( $value['image'] ) : WPFORMS_PLUGIN_URL . 'assets/images/placeholder-200x125.png',
esc_attr( $value['label'] ),
! empty( $value['label'] ) ? ' title="' . esc_attr( $value['label'] ) . '"' : ''
);
if ( 'none' === $field['choices_images_style'] ) {
$output .= '<br>';
}
$output .= sprintf(
'<input type="%s" class="%s" %s disabled>',
$type,
wpforms_sanitize_classes( $input_class, true ),
$selected
);
$output .= '<span class="wpforms-image-choices-label">' . wp_kses_post( $value['label'] ) . '</span>';
$output .= '</label>';
} else {
$output .= sprintf(
'<input type="%s" %s disabled>%s',
$type,
$selected,
$value['label']
);
}
$output .= '</li>';
}
$output .= '</ul>';
}
/*
* Dynamic population is enabled and contains more than 20 items,
* include a note about results displayed.
*/
if ( $total > 20 ) {
$output .= '<div class="wpforms-alert-dynamic wpforms-alert wpforms-alert-warning">';
$output .= sprintf(
wp_kses(
/* translators: %d - total amount of choices. */
__( 'Showing the first 20 choices.<br> All %d choices will be displayed when viewing the form.', 'wpforms-lite' ),
array(
'br' => array(),
)
),
$total
);
$output .= '</div>';
}
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Create a new field in the admin AJAX editor.
*
* @since 1.0.0
*/
public function field_new() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
die( esc_html__( 'You do not have permission.', 'wpforms-lite' ) );
}
// Check for form ID.
if ( ! isset( $_POST['id'] ) || empty( $_POST['id'] ) ) {
die( esc_html__( 'No form ID found', 'wpforms-lite' ) );
}
// Check for field type to add.
if ( ! isset( $_POST['type'] ) || empty( $_POST['type'] ) ) {
die( esc_html__( 'No field type found', 'wpforms-lite' ) );
}
// Grab field data.
$field_args = ! empty( $_POST['defaults'] ) ? (array) $_POST['defaults'] : array();
$field_type = esc_attr( $_POST['type'] );
$field_id = wpforms()->form->next_field_id( $_POST['id'] );
$field = array(
'id' => $field_id,
'type' => $field_type,
'label' => $this->name,
'description' => '',
);
$field = wp_parse_args( $field_args, $field );
$field = apply_filters( 'wpforms_field_new_default', $field );
$field_required = apply_filters( 'wpforms_field_new_required', '', $field );
$field_class = apply_filters( 'wpforms_field_new_class', '', $field );
// Field types that default to required.
if ( ! empty( $field_required ) ) {
$field_required = 'required';
$field['required'] = '1';
}
// Build Preview.
ob_start();
$this->field_preview( $field );
$prev = ob_get_clean();
$preview = sprintf( '<div class="wpforms-field wpforms-field-%s %s %s" id="wpforms-field-%d" data-field-id="%d" data-field-type="%s">', $field_type, $field_required, $field_class, $field['id'], $field['id'], $field_type );
$preview .= sprintf( '<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' ) );
$preview .= sprintf( '<a href="#" class="wpforms-field-delete" title="%s"><i class="fa fa-times-circle"></i></a>', esc_attr__( 'Delete Field', 'wpforms-lite' ) );
$preview .= sprintf( '<span class="wpforms-field-helper">%s</span>', esc_html__( 'Click to edit. Drag to reorder.', 'wpforms-lite' ) );
$preview .= $prev;
$preview .= '</div>';
// Build Options.
$options = sprintf( '<div class="wpforms-field-option wpforms-field-option-%s" id="wpforms-field-option-%d" data-field-id="%d">', esc_attr( $field['type'] ), $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][id]" value="%d" class="wpforms-field-option-hidden-id">', $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][type]" value="%s" class="wpforms-field-option-hidden-type">', $field['id'], esc_attr( $field['type'] ) );
ob_start();
$this->field_options( $field );
$options .= ob_get_clean();
$options .= '</div>';
// Prepare to return compiled results.
wp_send_json_success(
array(
'form_id' => (int) $_POST['id'],
'field' => $field,
'preview' => $preview,
'options' => $options,
)
);
}
/**
* Display the field input elements on the frontend.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
* @param array $field_atts Field attributes.
* @param array $form_data Form data and settings.
*/
abstract public function field_display( $field, $field_atts, $form_data );
/**
* Display field input errors if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param array $field Field data and settings.
*/
public function field_display_error( $key, $field ) {
// Need an error.
if ( empty( $field['properties']['error']['value'][ $key ] ) ) {
return;
}
printf(
'<label class="wpforms-error" for="%s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
esc_html( $field['properties']['error']['value'][ $key ] )
);
}
/**
* Display field input sublabel if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param string $position Sublabel position.
* @param array $field Field data and settings.
*/
public function field_display_sublabel( $key, $position, $field ) {
// Need a sublabel value.
if ( empty( $field['properties']['inputs'][ $key ]['sublabel']['value'] ) ) {
return;
}
$pos = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['position'] ) ? $field['properties']['inputs'][ $key ]['sublabel']['position'] : 'after';
$hidden = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['hidden'] ) ? 'wpforms-sublabel-hide' : '';
if ( $pos !== $position ) {
return;
}
printf(
'<label for="%s" class="wpforms-field-sublabel %s %s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
sanitize_html_class( $pos ),
$hidden,
$field['properties']['inputs'][ $key ]['sublabel']['value']
);
}
/**
* Validates field on form submit.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param array $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function validate( $field_id, $field_submit, $form_data ) {
// Basic required check - If field is marked as required, check for entry data.
if ( ! empty( $form_data['fields'][ $field_id ]['required'] ) && empty( $field_submit ) && '0' != $field_submit ) {
wpforms()->process->errors[ $form_data['id'] ][ $field_id ] = wpforms_get_required_label();
}
}
/**
* Formats and sanitizes field.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param array $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function format( $field_id, $field_submit, $form_data ) {
if ( is_array( $field_submit ) ) {
$field_submit = array_filter( $field_submit );
$field_submit = implode( "\r\n", $field_submit );
}
$name = ! empty( $form_data['fields'][ $field_id ]['label'] ) ? sanitize_text_field( $form_data['fields'][ $field_id ]['label'] ) : '';
// Sanitize but keep line breaks.
$value = wpforms_sanitize_textarea_field( $field_submit );
wpforms()->process->fields[ $field_id ] = array(
'name' => $name,
'value' => $value,
'id' => absint( $field_id ),
'type' => $this->type,
);
}
}
home/xbodynamge/dev/wp-content/plugins/wpforms-lite/includes/providers/class-base.php 0000644 00000101206 15114657365 0025204 0 ustar 00 <?php
/**
* Provider class.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Provider {
/**
* Provider addon version.
*
* @since 1.0.0
*
* @var string
*/
protected $version;
/**
* Provider name.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Provider name in slug format.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Load priority.
*
* @since 1.0.0
*
* @var int
*/
public $priority = 10;
/**
* Holds the API connections.
*
* @since 1.0.0
*
* @var mixed
*/
public $api = false;
/**
* Service icon.
*
* @since 1.0.0
*
* @var string
*/
public $icon;
/**
* Service icon.
*
* @since 1.2.3
*
* @var string
*/
public $type;
/**
* Form data and settings.
*
* @since 1.2.3
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->type = esc_html__( 'Connection', 'wpforms-lite' );
$this->init();
// Add to list of available providers.
add_filter( 'wpforms_providers_available', array( $this, 'register_provider' ), $this->priority, 1 );
// Process builder AJAX requests.
add_action( "wp_ajax_wpforms_provider_ajax_{$this->slug}", array( $this, 'process_ajax' ) );
// Process entry.
add_action( 'wpforms_process_complete', array( $this, 'process_entry' ), 5, 4 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', array( $this, 'builder_form_data' ) );
// Output builder sidebar.
add_action( 'wpforms_providers_panel_sidebar', array( $this, 'builder_sidebar' ), $this->priority );
// Output builder content.
add_action( 'wpforms_providers_panel_content', array( $this, 'builder_output' ), $this->priority );
// Remove provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_disconnect', array( $this, 'integrations_tab_disconnect' ) );
// Add new provider from Settings Integrations tab.
add_action( 'wp_ajax_wpforms_settings_provider_add', array( $this, 'integrations_tab_add' ) );
// Add providers sections to the Settings Integrations tab.
add_action( 'wpforms_settings_providers', array( $this, 'integrations_tab_options' ), $this->priority, 2 );
}
/**
* All systems go. Used by subclasses.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add to list of registered providers.
*
* @since 1.0.0
*
* @param array $providers Array of all active providers.
*
* @return array
*/
public function register_provider( $providers = array() ) {
$providers[ $this->slug ] = $this->name;
return $providers;
}
/**
* Process the Builder AJAX requests.
*
* @since 1.0.0
*/
public function process_ajax() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
/*
* Create new connection.
*/
if ( 'new_connection' === $_POST['task'] ) {
$connection = $this->output_connection(
'',
array(
'connection_name' => stripslashes( $_POST['name'] ),
),
$_POST['id']
);
wp_send_json_success(
array(
'html' => $connection,
)
);
}
/*
* Create new Provider account.
*/
if ( 'new_account' === $_POST['task'] ) {
$auth = $this->api_auth( stripslashes_deep( wp_parse_args( $_POST['data'], array() ) ), $_POST['id'] );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => $auth->get_error_message(),
)
);
} else {
$accounts = $this->output_accounts(
$_POST['connection_id'],
array(
'account_id' => $auth,
)
);
wp_send_json_success(
array(
'html' => $accounts,
)
);
}
}
/*
* Select/Toggle Provider accounts.
*/
if ( 'select_account' === $_POST['task'] ) {
$lists = $this->output_lists(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
)
);
if ( is_wp_error( $lists ) ) {
wp_send_json_error(
array(
'error' => $lists->get_error_message(),
)
);
} else {
wp_send_json_success(
array(
'html' => $lists,
)
);
}
}
/*
* Select/Toggle Provider account lists.
*/
if ( 'select_list' === $_POST['task'] ) {
$fields = $this->output_fields( $_POST['connection_id'], array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
), $_POST['id'] );
if ( is_wp_error( $fields ) ) {
wp_send_json_error(
array(
'error' => $fields->get_error_message(),
)
);
} else {
$groups = $this->output_groups(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
)
);
$conditionals = $this->output_conditionals(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
),
array(
'id' => absint( $_POST['form_id'] ),
)
);
$options = $this->output_options(
$_POST['connection_id'],
array(
'account_id' => $_POST['account_id'],
'list_id' => $_POST['list_id'],
)
);
wp_send_json_success(
array(
'html' => $groups . $fields . $conditionals . $options,
)
);
}
}
die();
}
/**
* Process and submit entry to provider.
*
* @since 1.0.0
*
* @param array $fields List of fields in a form.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param int $entry_id Saved entry ID.
*/
public function process_entry( $fields, $entry, $form_data, $entry_id ) {
}
/**
* Process conditional fields.
*
* @since 1.0.0
*
* @param array $fields List of fields with their data and settings.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param array $connection List of connection settings.
*
* @return bool
*/
public function process_conditionals( $fields, $entry, $form_data, $connection ) {
if ( empty( $connection['conditional_logic'] ) || empty( $connection['conditionals'] ) ) {
return true;
}
$process = wpforms_conditional_logic()->process( $fields, $form_data, $connection['conditionals'] );
if ( ! empty( $connection['conditional_type'] ) && 'stop' === $connection['conditional_type'] ) {
$process = ! $process;
}
return $process;
}
/**
* Retrieve all available forms in a field.
*
* Not all fields should be available for merge tags so we compare against a
* white-list. Also some fields, such as Name, should have additional
* variations.
*
* @since 1.0.0
*
* @param object|bool $form
* @param array $whitelist
*
* @return bool|array
*/
public function get_form_fields( $form = false, $whitelist = array() ) {
// Accept form (post) object or form ID.
if ( is_object( $form ) ) {
$form = wpforms_decode( $form->post_content );
} elseif ( is_numeric( $form ) ) {
$form = wpforms()->form->get(
$form,
array(
'content_only' => true,
)
);
}
if ( ! is_array( $form ) || empty( $form['fields'] ) ) {
return false;
}
// White list of field types to allow.
$allowed_form_fields = array(
'text',
'textarea',
'select',
'radio',
'checkbox',
'email',
'address',
'url',
'name',
'hidden',
'date-time',
'phone',
'number',
);
$allowed_form_fields = apply_filters( 'wpforms_providers_fields', $allowed_form_fields );
$whitelist = ! empty( $whitelist ) ? $whitelist : $allowed_form_fields;
$form_fields = $form['fields'];
foreach ( $form_fields as $id => $form_field ) {
if ( ! in_array( $form_field['type'], $whitelist, true ) ) {
unset( $form_fields[ $id ] );
}
}
return $form_fields;
}
/**
* Get form fields ready for select list options.
*
* In this function we also do the logic to limit certain fields to certain
* provider field types.
*
* @since 1.0.0
*
* @param array $form_fields
* @param string $form_field_type
*
* @return array
*/
public function get_form_field_select( $form_fields = array(), $form_field_type = '' ) {
if ( empty( $form_fields ) || empty( $form_field_type ) ) {
return array();
}
$formatted = array();
// Include only specific field types.
foreach ( $form_fields as $id => $form_field ) {
// Email.
if (
'email' === $form_field_type &&
! in_array( $form_field['type'], array( 'text', 'email' ), true )
) {
unset( $form_fields[ $id ] );
}
// Address.
if (
'address' === $form_field_type &&
! in_array( $form_field['type'], array( 'address' ), true )
) {
unset( $form_fields[ $id ] );
}
}
// Format.
foreach ( $form_fields as $id => $form_field ) {
// Complex Name field.
if ( 'name' === $form_field['type'] ) {
// Full Name.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Full)', 'wpforms-lite' ),
$form_field['label']
),
);
// First Name.
if ( strpos( $form_field['format'], 'first' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'first',
'type' => $form_field['type'],
'subtype' => 'first',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (First)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Middle Name.
if ( strpos( $form_field['format'], 'middle' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'middle',
'type' => $form_field['type'],
'subtype' => 'middle',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Middle)', 'wpforms-lite' ),
$form_field['label']
),
);
}
// Last Name.
if ( strpos( $form_field['format'], 'last' ) !== false ) {
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'last',
'type' => $form_field['type'],
'subtype' => 'last',
'provider_type' => $form_field_type,
'label' => sprintf(
/* translators: %s - Name field label. */
esc_html__( '%s (Last)', 'wpforms-lite' ),
$form_field['label']
),
);
}
} else {
// All other fields.
$formatted[] = array(
'id' => $form_field['id'],
'key' => 'value',
'type' => $form_field['type'],
'subtype' => '',
'provider_type' => $form_field_type,
'label' => $form_field['label'],
);
}
}
return $formatted;
}
/************************************************************************
* API methods - these methods interact directly with the provider API. *
************************************************************************/
/**
* Authenticate with the provider API.
*
* @since 1.0.0
*
* @param array $data
* @param string $form_id
*
* @return mixed id or error object
*/
public function api_auth( $data = array(), $form_id = '' ) {
}
/**
* Establish connection object to provider API.
*
* @since 1.0.0
*
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_connect( $account_id ) {
}
/**
* Retrieve provider account lists.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
*
* @return mixed array or error object
*/
public function api_lists( $connection_id = '', $account_id = '' ) {
}
/**
* Retrieve provider account list groups.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_groups( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/**
* Retrieve provider account list fields.
*
* @since 1.0.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
*/
public function api_fields( $connection_id = '', $account_id = '', $list_id = '' ) {
}
/*************************************************************************
* Output methods - these methods generally return HTML for the builder. *
*************************************************************************/
/**
* Connection HTML.
*
* This method compiles all the HTML necessary for a connection to a provider.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form Form id or form data.
*
* @return string
*/
public function output_connection( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) ) {
$connection_id = 'connection_' . uniqid();
}
if ( empty( $connection ) || empty( $form ) ) {
return '';
}
$output = sprintf( '<div class="wpforms-provider-connection" data-provider="%s" data-connection_id="%s">', $this->slug, $connection_id );
$output .= $this->output_connection_header( $connection_id, $connection );
$output .= $this->output_auth();
$output .= $this->output_accounts( $connection_id, $connection );
$lists = $this->output_lists( $connection_id, $connection );
$output .= ! is_wp_error( $lists ) ? $lists : '';
$output .= $this->output_groups( $connection_id, $connection );
$fields = $this->output_fields( $connection_id, $connection, $form );
$output .= ! is_wp_error( $fields ) ? $fields : '';
$output .= $this->output_conditionals( $connection_id, $connection, $form );
$output .= $this->output_options( $connection_id, $connection );
$output .= '</div>';
return $output;
}
/**
* Connection header HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_connection_header( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$output = '<div class="wpforms-provider-connection-header">';
$output .= sprintf( '<span>%s</span>', sanitize_text_field( $connection['connection_name'] ) );
$output .= '<button class="wpforms-provider-connection-delete"><i class="fa fa-times-circle"></i></button>';
$output .= sprintf( '<input type="hidden" name="providers[%s][%s][connection_name]" value="%s">', $this->slug, $connection_id, esc_attr( $connection['connection_name'] ) );
$output .= '</div>';
return $output;
}
/**
* Provider account authorize fields HTML.
*
* @since 1.0.0
*
* @return mixed
*/
public function output_auth() {
}
/**
* Provider account select HTML.
*
* @since 1.0.0
*
* @param string $connection_id Unique connection ID.
* @param array $connection Array of connection data.
*
* @return string
*/
public function output_accounts( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection ) ) {
return '';
}
$providers = wpforms_get_providers_options();
if ( empty( $providers[ $this->slug ] ) ) {
return '';
}
$output = '<div class="wpforms-provider-accounts wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Account', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][account_id]">', $this->slug, $connection_id );
foreach ( $providers[ $this->slug ] as $key => $provider_details ) {
$selected = ! empty( $connection['account_id'] ) ? $connection['account_id'] : '';
$output .= sprintf(
'<option value="%s" %s>%s</option>',
$key,
selected( $selected, $key, false ),
esc_html( $provider_details['label'] )
);
}
$output .= sprintf( '<option value="">%s</a>', esc_html__( 'Add New Account', 'wpforms-lite' ) );
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account lists HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return WP_Error|string
*/
public function output_lists( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) ) {
return '';
}
$lists = $this->api_lists( $connection_id, $connection['account_id'] );
$selected = ! empty( $connection['list_id'] ) ? $connection['list_id'] : '';
if ( is_wp_error( $lists ) ) {
return $lists;
}
$output = '<div class="wpforms-provider-lists wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select List', 'wpforms-lite' ) );
$output .= sprintf( '<select name="providers[%s][%s][list_id]">', $this->slug, $connection_id );
if ( ! empty( $lists ) ) {
foreach ( $lists as $list ) {
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $list['id'] ),
selected( $selected, $list['id'], false ),
esc_attr( $list['name'] )
);
}
}
$output .= '</select>';
$output .= '</div>';
return $output;
}
/**
* Provider account list groups HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_groups( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) ) {
return '';
}
$groupsets = $this->api_groups( $connection_id, $connection['account_id'], $connection['list_id'] );
if ( is_wp_error( $groupsets ) ) {
return '';
}
$output = '<div class="wpforms-provider-groups wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'Select Groups', 'wpforms-lite' ) );
$output .= sprintf( '<p>%s</p>', esc_html__( 'We also noticed that you have some segments in your list. You can select specific list segments below if needed. This is optional.', 'wpforms-lite' ) );
$output .= '<div class="wpforms-provider-groups-list">';
foreach ( $groupsets as $groupset ) {
$output .= sprintf( '<p>%s</p>', esc_html( $groupset['name'] ) );
foreach ( $groupset['groups'] as $group ) {
$selected = ! empty( $connection['groups'] ) && ! empty( $connection['groups'][ $groupset['id'] ] ) ? in_array( $group['name'], $connection['groups'][ $groupset['id'] ], true ) : false;
$output .= sprintf(
'<span><input id="group_%s" type="checkbox" value="%s" name="providers[%s][%s][groups][%s][%s]" %s><label for="group_%s">%s</label></span>',
esc_attr( $group['id'] ),
esc_attr( $group['name'] ),
$this->slug,
$connection_id,
$groupset['id'],
$group['id'],
checked( $selected, true, false ),
esc_attr( $group['id'] ),
esc_attr( $group['name'] )
);
}
}
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* Provider account list fields HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param mixed $form
*
* @return WP_Error|string
*/
public function output_fields( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) || empty( $form ) ) {
return '';
}
$provider_fields = $this->api_fields( $connection_id, $connection['account_id'], $connection['list_id'] );
$form_fields = $this->get_form_fields( $form );
if ( is_wp_error( $provider_fields ) ) {
return $provider_fields;
}
$output = '<div class="wpforms-provider-fields wpforms-connection-block">';
$output .= sprintf( '<h4>%s</h4>', esc_html__( 'List Fields', 'wpforms-lite' ) );
// Table with all the fields.
$output .= '<table>';
$output .= sprintf( '<thead><tr><th>%s</th><th>%s</th></thead>', esc_html__( 'List Fields', 'wpforms-lite' ), esc_html__( 'Available Form Fields', 'wpforms-lite' ) );
$output .= '<tbody>';
foreach ( $provider_fields as $provider_field ) :
$output .= '<tr>';
$output .= '<td>';
$output .= esc_html( $provider_field['name'] );
if (
! empty( $provider_field['req'] ) &&
$provider_field['req'] == '1'
) {
$output .= '<span class="required">*</span>';
}
$output .= '<td>';
$output .= sprintf( '<select name="providers[%s][%s][fields][%s]">', $this->slug, $connection_id, esc_attr( $provider_field['tag'] ) );
$output .= '<option value=""></option>';
$options = $this->get_form_field_select( $form_fields, $provider_field['field_type'] );
foreach ( $options as $option ) {
$value = sprintf( '%d.%s.%s', $option['id'], $option['key'], $option['provider_type'] );
$selected = ! empty( $connection['fields'][ $provider_field['tag'] ] ) ? selected( $connection['fields'][ $provider_field['tag'] ], $value, false ) : '';
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $value ), $selected, esc_html( $option['label'] ) );
}
$output .= '</select>';
$output .= '</td>';
$output .= '</tr>';
endforeach;
$output .= '</tbody>';
$output .= '</table>';
$output .= '</div>';
return $output;
}
/**
* Provider connection conditional options HTML
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
* @param string|array $form
*
* @return string
*/
public function output_conditionals( $connection_id = '', $connection = array(), $form = '' ) {
if ( empty( $connection['account_id'] ) ) {
return '';
}
return wpforms_conditional_logic()->builder_block(
array(
'form' => $this->form_data,
'type' => 'panel',
'panel' => $this->slug,
'parent' => 'providers',
'subsection' => $connection_id,
'reference' => esc_html__( 'Marketing provider connection', 'wpforms-lite' ),
),
false
);
}
/**
* Provider account list options HTML.
*
* @since 1.0.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_options( $connection_id = '', $connection = array() ) {
}
/********************************************************
* Builder methods - these methods _build_ the Builder. *
********************************************************/
/**
* Fetch and store the current form data when in the builder.
*
* @since 1.2.3
*/
public function builder_form_data() {
if ( ! empty( $_GET['form_id'] ) && empty( $this->form_data ) ) {
$this->form_data = wpforms()->form->get(
absint( $_GET['form_id'] ),
array(
'content_only' => true,
)
);
}
}
/**
* Display content inside the panel content area.
*
* @since 1.0.0
*/
public function builder_content() {
$form_data = $this->form_data;
$providers = wpforms_get_providers_options();
if ( ! empty( $form_data['providers'][ $this->slug ] ) && ! empty( $providers[ $this->slug ] ) ) {
foreach ( $form_data['providers'][ $this->slug ] as $connection_id => $connection ) {
foreach ( $providers[ $this->slug ] as $account_id => $connections ) {
if (
! empty( $connection['account_id'] ) &&
$connection['account_id'] === $account_id
) {
echo $this->output_connection( $connection_id, $connection, $form_data );
}
}
}
}
}
/**
* Display content inside the panel sidebar area.
*
* @since 1.0.0
*/
public function builder_sidebar() {
$form_data = $this->form_data;
$configured = ! empty( $form_data['providers'][ $this->slug ] ) ? 'configured' : '';
$configured = apply_filters( 'wpforms_providers_' . $this->slug . '_configured', $configured );
echo '<a href="#" class="wpforms-panel-sidebar-section icon ' . esc_attr( $configured ) . ' wpforms-panel-sidebar-section-' . esc_attr( $this->slug ) . '" data-section="' . esc_attr( $this->slug ) . '">';
echo '<img src="' . esc_url( $this->icon ) . '">';
echo esc_html( $this->name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
if ( ! empty( $configured ) ) {
echo '<i class="fa fa-check-circle-o"></i>';
}
echo '</a>';
}
/**
* Wraps the builder content with the required markup.
*
* @since 1.0.0
*/
public function builder_output() {
?>
<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( $this->slug ); ?>"
id="<?php echo esc_attr( $this->slug ); ?>-provider">
<?php $this->builder_output_before(); ?>
<div class="wpforms-panel-content-section-title">
<?php echo $this->name; ?>
<button class="wpforms-provider-connections-add" data-form_id="<?php echo absint( $_GET['form_id'] ); ?>"
data-provider="<?php echo esc_attr( $this->slug ); ?>"
data-type="<?php echo esc_attr( strtolower( $this->type ) ); ?>">
<?php
printf(
/* translators: %s - Provider type. */
esc_html__( 'Add New %s', 'wpforms-lite' ),
esc_html( $this->type )
);
?>
</button>
</div>
<div class="wpforms-provider-connections-wrap wpforms-clear">
<div class="wpforms-provider-connections">
<?php $this->builder_content(); ?>
</div>
</div>
<?php $this->builder_output_after(); ?>
</div>
<?php
}
/**
* Optionally output content before the main builder output.
*
* @since 1.3.6
*/
public function builder_output_before() {
}
/**
* Optionally output content after the main builder output.
*
* @since 1.3.6
*/
public function builder_output_after() {
}
/*************************************************************************
* Integrations tab methods - these methods relate to the settings page. *
*************************************************************************/
/**
* Form fields to add a new provider account.
*
* @since 1.0.0
*/
public function integrations_tab_new_form() {
}
/**
* AJAX to disconnect a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_disconnect() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['provider'] ) || empty( $_POST['key'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$providers = wpforms_get_providers_options();
if ( ! empty( $providers[ $_POST['provider'] ][ $_POST['key'] ] ) ) {
unset( $providers[ $_POST['provider'] ][ $_POST['key'] ] );
update_option( 'wpforms_providers', $providers );
wp_send_json_success();
} else {
wp_send_json_error(
array(
'error' => esc_html__( 'Connection missing', 'wpforms-lite' ),
)
);
}
}
/**
* AJAX to add a provider from the settings integrations tab.
*
* @since 1.0.0
*/
public function integrations_tab_add() {
if ( $_POST['provider'] !== $this->slug ) { //phpcs:ignore
return;
}
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
array(
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
)
);
}
if ( empty( $_POST['data'] ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Missing data', 'wpforms-lite' ),
)
);
}
$data = wp_parse_args( $_POST['data'], array() );
$auth = $this->api_auth( $data, '' );
if ( is_wp_error( $auth ) ) {
wp_send_json_error(
array(
'error' => esc_html__( 'Could not connect to the provider.', 'wpforms-lite' ),
'error_msg' => $auth->get_error_message(),
)
);
} else {
$account = '<li>';
$account .= '<span class="label">' . sanitize_text_field( $data['label'] ) . '</span>';
/* translators: %s - Connection date. */
$account .= '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format', time() ) ) ) . '</span>';
$account .= '<a href="#" data-provider="' . $this->slug . '" data-key="' . esc_attr( $auth ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a>';
$account .= '</li>';
wp_send_json_success(
array(
'html' => $account,
)
);
}
}
/**
* Add provider to the Settings Integrations tab.
*
* @since 1.0.0
*
* @param array $active Array of active connections.
* @param array $settings Array of all connections settings.
*/
public function integrations_tab_options( $active, $settings ) {
$connected = ! empty( $active[ $this->slug ] );
$accounts = ! empty( $settings[ $this->slug ] ) ? $settings[ $this->slug ] : array();
$class = $connected && $accounts ? 'connected' : '';
$arrow = 'right';
/* translators: %s - provider name. */
$title_connect_to = sprintf( esc_html__( 'Connect to %s', 'wpforms-lite' ), esc_html( $this->name ) );
// This lets us highlight a specific service by a special link.
if ( ! empty( $_GET['wpforms-integration'] ) ) { //phpcs:ignore
if ( $this->slug === $_GET['wpforms-integration'] ) { //phpcs:ignore
$class .= ' focus-in';
$arrow = 'down';
} else {
$class .= ' focus-out';
}
}
?>
<div id="wpforms-integration-<?php echo esc_attr( $this->slug ); ?>" class="wpforms-settings-provider wpforms-clear <?php echo esc_attr( $this->slug ); ?> <?php echo esc_attr( $class ); ?>">
<div class="wpforms-settings-provider-header wpforms-clear" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-logo">
<i title="<?php esc_attr_e( 'Show Accounts', 'wpforms-lite' ); ?>" class="fa fa-chevron-<?php echo esc_attr( $arrow ); ?>"></i>
<img src="<?php echo esc_url( $this->icon ); ?>">
</div>
<div class="wpforms-settings-provider-info">
<h3><?php echo esc_html( $this->name ); ?></h3>
<p>
<?php
/* translators: %s - provider name. */
printf( esc_html__( 'Integrate %s with WPForms', 'wpforms-lite' ), esc_html( $this->name ) );
?>
</p>
<span class="connected-indicator green"><i class="fa fa-check-circle-o"></i> <?php esc_html_e( 'Connected', 'wpforms-lite' ); ?></span>
</div>
</div>
<div class="wpforms-settings-provider-accounts" id="provider-<?php echo esc_attr( $this->slug ); ?>">
<div class="wpforms-settings-provider-accounts-list">
<ul>
<?php
if ( ! empty( $accounts ) ) {
foreach ( $accounts as $key => $account ) {
echo '<li class="wpforms-clear">';
echo '<span class="label">' . esc_html( $account['label'] ) . '</span>';
/* translators: %s - Connection date. */
echo '<span class="date">' . sprintf( esc_html__( 'Connected on: %s', 'wpforms-lite' ), date_i18n( get_option( 'date_format' ), intval( $account['date'] ) ) ) . '</span>';
echo '<span class="remove"><a href="#" data-provider="' . esc_attr( $this->slug ) . '" data-key="' . esc_attr( $key ) . '">' . esc_html__( 'Disconnect', 'wpforms-lite' ) . '</a></span>';
echo '</li>';
}
}
?>
</ul>
</div>
<p class="wpforms-settings-provider-accounts-toggle">
<a class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey" href="#" data-provider="<?php echo esc_attr( $this->slug ); ?>">
<i class="fa fa-plus"></i> <?php esc_html_e( 'Add New Account', 'wpforms-lite' ); ?>
</a>
</p>
<div class="wpforms-settings-provider-accounts-connect">
<form>
<p><?php esc_html_e( 'Please fill out all of the fields below to add your new provider account.', 'wpforms-lite' ); ?></span></p>
<p class="wpforms-settings-provider-accounts-connect-fields">
<?php $this->integrations_tab_new_form(); ?>
</p>
<button type="submit" class="wpforms-btn wpforms-btn-md wpforms-btn-orange wpforms-settings-provider-connect"
data-provider="<?php echo esc_attr( $this->slug ); ?>" title="<?php echo esc_attr( $title_connect_to ); ?>">
<?php echo esc_html( $title_connect_to ); ?>
</button>
</form>
</div>
</div>
</div>
<?php
}
/**
* Error wrapper for WP_Error.
*
* @since 1.0.0
*
* @param string $message
* @param string $parent
*
* @return WP_Error
*/
public function error( $message = '', $parent = '0' ) {
return new WP_Error( $this->slug . '-error', $message );
}
}
home/xbodynamge/dev/wp-content/plugins/wpforms-lite/includes/templates/class-base.php 0000644 00000010547 15115010203 0025143 0 ustar 00 <?php
/**
* Base form template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Template {
/**
* Full name of the template, eg "Contact Form".
*
* @since 1.0.0
* @var string
*/
public $name;
/**
* Slug of the template, eg "contact-form" - no spaces.
*
* @since 1.0.0
* @var string
*/
public $slug;
/**
* Short description the template.
*
* @since 1.0.0
* @var string
*/
public $description = '';
/**
* Short description of the fields included with the template.
*
* @since 1.0.0
* @var string
*/
public $includes = '';
/**
* URL of the icon to display in the admin area.
*
* @since 1.0.0
* @var string
*/
public $icon = '';
/**
* Array of data that is assigned to the post_content on form creation.
*
* @since 1.0.0
* @var array
*/
public $data;
/**
* Priority to show in the list of available templates.
*
* @since 1.0.0
* @var int
*/
public $priority = 20;
/**
* Core or additional template.
*
* @since 1.4.0
* @var bool
*/
public $core = false;
/**
* Modal message to display when the template is applied.
*
* @since 1.0.0
* @var array
*/
public $modal = '';
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Bootstrap.
$this->init();
$type = $this->core ? '_core' : '';
add_filter( "wpforms_form_templates{$type}", array( $this, 'template_details' ), $this->priority );
add_filter( 'wpforms_create_form_args', array( $this, 'template_data' ), 10, 2 );
add_filter( 'wpforms_save_form_args', array( $this, 'template_replace' ), 10, 3 );
add_filter( 'wpforms_builder_template_active', array( $this, 'template_active' ), 10, 2 );
}
/**
* Let's get started.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Add basic template details to the Add New Form admin screen.
*
* @since 1.0.0
*
* @param array $templates
*
* @return array
*/
public function template_details( $templates ) {
$templates[] = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
);
return $templates;
}
/**
* Add template data when form is created.
*
* @since 1.0.0
*
* @param array $args
* @param array $data
*
* @return array
*/
public function template_data( $args, $data ) {
if ( ! empty( $data ) && ! empty( $data['template'] ) ) {
if ( $data['template'] === $this->slug ) {
$args['post_content'] = wpforms_encode( $this->data );
}
}
return $args;
}
/**
* Replace template on post update if triggered.
*
* @since 1.0.0
*
* @param array $form
* @param array $data
* @param array $args
*
* @return array
*/
public function template_replace( $form, $data, $args ) {
if ( ! empty( $args['template'] ) ) {
if ( $args['template'] === $this->slug ) {
$new = $this->data;
$new['settings'] = ! empty( $form['post_content']['settings'] ) ? $form['post_content']['settings'] : array();
$form['post_content'] = wpforms_encode( $new );
}
}
return $form;
}
/**
* Pass information about the active template back to the builder.
*
* @since 1.0.0
*
* @param array $details
* @param object $form
*
* @return array
*/
public function template_active( $details, $form ) {
if ( empty( $form ) ) {
return;
}
$form_data = wpforms_decode( $form->post_content );
if ( empty( $this->modal ) || empty( $form_data['meta']['template'] ) || $this->slug !== $form_data['meta']['template'] ) {
return $details;
} else {
$display = $this->template_modal_conditional( $form_data );
}
$template = array(
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'includes' => $this->includes,
'icon' => $this->icon,
'modal' => $this->modal,
'modal_display' => $display,
);
return $template;
}
/**
* Conditional to determine if the template informational modal screens
* should display.
*
* @since 1.0.0
*
* @param array $form_data Form data and settings.
*
* @return boolean
*/
public function template_modal_conditional( $form_data ) {
return false;
}
}
home/xbodynamge/namtation/wp-content/plugins/wpforms-lite/includes/fields/class-base.php 0000644 00000161735 15115017343 0025651 0 ustar 00 <?php
/**
* Base field template.
*
* @package WPForms
* @author WPForms
* @since 1.0.0
* @license GPL-2.0+
* @copyright Copyright (c) 2016, WPForms LLC
*/
abstract class WPForms_Field {
/**
* Full name of the field type, eg "Paragraph Text".
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Type of the field, eg "textarea".
*
* @since 1.0.0
*
* @var string
*/
public $type;
/**
* 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 integer
*/
public $order = 1;
/**
* Field group the field belongs to.
*
* @since 1.0.0
*
* @var string
*/
public $group = 'standard';
/**
* Placeholder to hold default value(s) for some field types.
*
* @since 1.0.0
*
* @var mixed
*/
public $defaults;
/**
* Current form ID in the admin builder.
*
* @since 1.1.1
*
* @var int|bool
*/
public $form_id;
/**
* Current form data in.
*
* @since 1.1.1
*
* @var array
*/
public $form_data;
/**
* Primary class constructor.
*
* @since 1.0.0
*
* @param bool $init Pass false to allow to shortcut the whole initialization, if needed.
*/
public function __construct( $init = true ) {
if ( ! $init ) {
return;
}
// The form ID is to be accessed in the builder.
$this->form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
// Bootstrap.
$this->init();
// Add fields tab.
add_filter( 'wpforms_builder_fields_buttons', array( $this, 'field_button' ), 15 );
// Field options tab.
add_action( "wpforms_builder_fields_options_{$this->type}", array( $this, 'field_options' ), 10 );
// Preview fields.
add_action( "wpforms_builder_fields_previews_{$this->type}", array( $this, 'field_preview' ), 10 );
// AJAX Add new field.
add_action( "wp_ajax_wpforms_new_field_{$this->type}", array( $this, 'field_new' ) );
// Display field input elements on front-end.
add_action( "wpforms_display_field_{$this->type}", array( $this, 'field_display' ), 10, 3 );
// Validation on submit.
add_action( "wpforms_process_validate_{$this->type}", array( $this, 'validate' ), 10, 3 );
// Format.
add_action( "wpforms_process_format_{$this->type}", array( $this, 'format' ), 10, 3 );
// Prefill.
add_filter( 'wpforms_field_properties', array( $this, 'field_prefill_value_property' ), 10, 3 );
}
/**
* All systems go. Used by subclasses. Required.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*/
abstract public function init();
/**
* Prefill field value with either fallback or dynamic data.
* Needs to be public (although internal) to be used in WordPress hooks.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
* @param array $form_data Prepared form data/settings.
*
* @return array Modified field properties.
*/
public function field_prefill_value_property( $properties, $field, $form_data ) {
// Process only for current field.
if ( $this->type !== $field['type'] ) {
return $properties;
}
// Set the form data, so we can reuse it later, even on front-end.
$this->form_data = $form_data;
// Dynamic data.
if ( ! empty( $this->form_data['settings']['dynamic_population'] ) ) {
$properties = $this->field_prefill_value_property_dynamic( $properties, $field );
}
// Fallback data, rewrites dynamic because user-submitted data is more important.
$properties = $this->field_prefill_value_property_fallback( $properties, $field );
return $properties;
}
/**
* As we are processing user submitted data - ignore all admin-defined defaults.
* Preprocess choices-related fields only.
*
* @since 1.5.0
*
* @param array $field Field data and settings.
* @param array $properties Properties we are modifying.
*/
protected function field_prefill_remove_choices_defaults( $field, &$properties ) {
if (
! empty( $field['dynamic_choices'] ) ||
! empty( $field['choices'] )
) {
array_walk_recursive(
$properties['inputs'],
function ( &$value, $key ) {
if ( 'default' === $key ) {
$value = false;
}
if ( 'wpforms-selected' === $value ) {
$value = '';
}
}
);
}
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_dynamic_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
// For dynamic population we require $_GET.
if ( empty( $_GET ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_dynamic_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a dynamic value, that we get from $_GET.
* The pattern is: wpf4_12_primary, where:
* 4 - form_id,
* 12 - field_id,
* first - input key.
* As 'primary' is our default input key, "wpf4_12_primary" and "wpf4_12" are the same.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_dynamic( $properties, $field ) {
if ( ! $this->is_dynamic_population_allowed( $properties, $field ) ) {
return $properties;
}
// Iterate over each GET key, parse, and scrap data from there.
foreach ( $_GET as $key => $raw_value ) { // phpcs:ignore
preg_match( '/wpf(\d+)_(\d+)(.*)/i', $key, $matches );
if ( empty( $matches ) || ! is_array( $matches ) ) {
continue;
}
// Required.
$form_id = absint( $matches[1] );
$field_id = absint( $matches[2] );
$input = 'primary';
// Optional.
if ( ! empty( $matches[3] ) ) {
$input = sanitize_key( trim( $matches[3], '_' ) );
}
// Both form and field IDs should be the same as current form/field.
if (
(int) $this->form_data['id'] !== $form_id ||
(int) $field['id'] !== $field_id
) {
// Go to the next GET param.
continue;
}
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* Some fields (like checkboxes) support multiple selection.
* We do not support nested values, so omit them.
* Example: ?wpf771_19_wpforms[fields][19][address1]=test
* In this case:
* $input = wpforms
* $raw_value = [fields=>[]]
* $single_value = [19=>[]]
* There is no reliable way to clean those things out.
* So we will ignore the value altogether if it's an array.
* We support only single value numeric arrays, like these:
* ?wpf771_19[]=test1&wpf771_19[]=test2
* ?wpf771_19_value[]=test1&wpf771_19_value[]=test2
* ?wpf771_41_r3_c2[]=1&wpf771_41_r1_c4[]=1
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, $input, $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, $input, $properties, $field );
}
}
return $properties;
}
/**
* Get the value, that is used to prefill via dynamic or fallback population.
* Based on field data and current properties.
*
* @since 1.5.0
*
* @param string $raw_value Value from a GET param, always a string.
* @param string $input Represent a subfield inside the field. May be empty.
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function get_field_populated_single_property_value( $raw_value, $input, $properties, $field ) {
if ( ! is_string( $raw_value ) ) {
return $properties;
}
$get_value = stripslashes( sanitize_text_field( $raw_value ) );
// For fields that have dynamic choices we need to add extra logic.
if ( ! empty( $field['dynamic_choices'] ) ) {
$default_key = null;
foreach ( $properties['inputs'] as $input_key => $input_arr ) {
// Dynamic choices support only integers in its values.
if ( absint( $get_value ) === $input_arr['attr']['value'] ) {
$default_key = $input_key;
// Stop iterating over choices.
break;
}
}
// Redefine default choice only if dynamic value has changed anything.
if ( null !== $default_key ) {
foreach ( $properties['inputs'] as $input_key => $choice_arr ) {
if ( $input_key === $default_key ) {
$properties['inputs'][ $input_key ]['default'] = true;
$properties['inputs'][ $input_key ]['container']['class'][] = 'wpforms-selected';
// Stop iterating over choices.
break;
}
}
}
} elseif ( ! empty( $field['choices'] ) && is_array( $field['choices'] ) ) {
$default_key = null;
// For fields that have normal choices we need to add extra logic.
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( isset( $field['show_values'] ) ) {
if (
isset( $choice_arr['value'] ) &&
strtoupper( $choice_arr['value'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
} else {
if (
isset( $choice_arr['label'] ) &&
strtoupper( $choice_arr['label'] ) === strtoupper( $get_value )
) {
$default_key = $choice_key;
// Stop iterating over choices.
break;
}
}
}
// Redefine default choice only if population value has changed anything.
if ( null !== $default_key ) {
foreach ( $field['choices'] as $choice_key => $choice_arr ) {
if ( $choice_key === $default_key ) {
$properties['inputs'][ $choice_key ]['default'] = true;
$properties['inputs'][ $choice_key ]['container']['class'][] = 'wpforms-selected';
break;
}
}
}
} else {
/*
* For other types of fields we need to check that
* the key is registered for the defined field in inputs array.
*/
if (
! empty( $input ) &&
isset( $properties['inputs'][ $input ] )
) {
$properties['inputs'][ $input ]['attr']['value'] = $get_value;
}
}
return $properties;
}
/**
* Whether current field can be populated dynamically.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_fallback_population_allowed( $properties, $field ) {
$allowed = true;
// Allow population on front-end only.
if ( is_admin() ) {
$allowed = false;
}
/*
* Commented out to allow partial fail for complex multi-inputs fields.
* Example: name field with first/last format and being required, filled out only first.
* On submit we will preserve those sub-inputs that are not empty and display an error for an empty.
*/
// Do not populate if there are errors for that field.
/*
$errors = wpforms()->process->errors;
if ( ! empty( $errors[ $this->form_data['id'] ][ $field['id'] ] ) ) {
$allowed = false;
}
*/
// Require form id being the same for submitted and currently rendered form.
if (
! empty( $_POST['wpforms']['id'] ) && // phpcs:ignore
(int) $_POST['wpforms']['id'] !== (int) $this->form_data['id'] // phpcs:ignore
) {
$allowed = false;
}
// Require $_POST of submitted field.
if ( empty( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
$allowed = false;
}
// Require field (processed and rendered) being the same.
if ( ! isset( $_POST['wpforms']['fields'][ $field['id'] ] ) ) { // phpcs:ignore
$allowed = false;
}
return apply_filters( 'wpforms_field_is_fallback_population_allowed', $allowed, $properties, $field );
}
/**
* Prefill the field value with a fallback value from form submission (in case of JS validation failed), that we get from $_POST.
*
* @since 1.5.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return array Modified field properties.
*/
protected function field_prefill_value_property_fallback( $properties, $field ) {
if ( ! $this->is_fallback_population_allowed( $properties, $field ) ) {
return $properties;
}
if ( empty( $_POST['wpforms']['fields'] ) || ! is_array( $_POST['wpforms']['fields'] ) ) { // phpcs:ignore
return $properties;
}
// We got user submitted raw data (not processed, will be done later).
$raw_value = $_POST['wpforms']['fields'][ $field['id'] ]; // phpcs:ignore
$input = 'primary';
if ( ! empty( $raw_value ) ) {
$this->field_prefill_remove_choices_defaults( $field, $properties );
}
/*
* For this particular field this value may be either array or a string.
* In array - this is a complex field, like address.
* The key in array will be a sub-input (address1, state), and its appropriate value.
*/
if ( is_array( $raw_value ) ) {
foreach ( $raw_value as $input => $single_value ) {
$properties = $this->get_field_populated_single_property_value( $single_value, sanitize_key( $input ), $properties, $field );
}
} else {
$properties = $this->get_field_populated_single_property_value( $raw_value, sanitize_key( $input ), $properties, $field );
}
return $properties;
}
/**
* Create the button for the 'Add Fields' tab, inside the form editor.
*
* @since 1.0.0
*
* @param array $fields List of form fields with their data.
*
* @return array
*/
public function field_button( $fields ) {
// Add field information to fields array.
$fields[ $this->group ]['fields'][] = array(
'order' => $this->order,
'name' => $this->name,
'type' => $this->type,
'icon' => $this->icon,
);
// Wipe hands clean.
return $fields;
}
/**
* Creates the field options panel. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_options( $field );
/**
* Creates the field preview. Used by subclasses.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
*/
abstract public function field_preview( $field );
/**
* Helper function to create field option elements.
*
* Field option elements are pieces that help create a field option.
* They are used to quickly build field options.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_element( $option, $field, $args = array(), $echo = true ) {
$id = (int) $field['id'];
$class = ! empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
$slug = ! empty( $args['slug'] ) ? sanitize_title( $args['slug'] ) : '';
$data = '';
$output = '';
if ( ! empty( $args['data'] ) ) {
foreach ( $args['data'] as $arg_key => $val ) {
if ( is_array( $val ) ) {
$val = wp_json_encode( $val );
}
$data .= ' data-' . $arg_key . '=\'' . $val . '\'';
}
}
switch ( $option ) {
// Row.
case 'row':
$output = sprintf(
'<div class="wpforms-field-option-row wpforms-field-option-row-%s %s" id="wpforms-field-option-row-%d-%s" data-field-id="%d">%s</div>',
$slug,
$class,
$id,
$slug,
$id,
$args['content']
);
break;
// Label.
case 'label':
$output = sprintf( '<label for="wpforms-field-option-%d-%s">%s', $id, $slug, esc_html( $args['value'] ) );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
if ( isset( $args['after_tooltip'] ) && ! empty( $args['after_tooltip'] ) ) {
$output .= $args['after_tooltip'];
}
$output .= '</label>';
break;
// Text input.
case 'text':
$type = ! empty( $args['type'] ) ? esc_attr( $args['type'] ) : 'text';
$placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : '';
$before = ! empty( $args['before'] ) ? '<span class="before-input">' . esc_html( $args['before'] ) . '</span>' : '';
if ( ! empty( $before ) ) {
$class .= ' has-before';
}
$output = sprintf( '%s<input type="%s" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="%s" placeholder="%s" %s>', $before, $type, $class, $id, $slug, $id, $slug, esc_attr( $args['value'] ), $placeholder, $data );
break;
// Textarea.
case 'textarea':
$rows = ! empty( $args['rows'] ) ? (int) $args['rows'] : '3';
$output = sprintf( '<textarea class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" rows="%d" %s>%s</textarea>', $class, $id, $slug, $id, $slug, $rows, $data, $args['value'] );
break;
// Checkbox.
case 'checkbox':
$checked = checked( '1', $args['value'], false );
$output = sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s>', $class, $id, $slug, $id, $slug, $checked, $data );
$output .= sprintf( '<label for="wpforms-field-option-%d-%s" class="inline">%s', $id, $slug, $args['desc'] );
if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
$output .= ' ' . sprintf( '<i class="fa fa-question-circle wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
$output .= '</label>';
break;
// Toggle.
case 'toggle':
$checked = checked( '1', $args['value'], false );
$icon = $args['value'] ? 'fa-toggle-on' : 'fa-toggle-off';
$cls = $args['value'] ? 'wpforms-on' : 'wpforms-off';
$status = $args['value'] ? esc_html__( 'On', 'wpforms-lite' ) : esc_html__( 'Off', 'wpforms-lite' );
$output = sprintf( '<span class="wpforms-toggle-icon %s"><i class="fa %s" aria-hidden="true"></i> <span class="wpforms-toggle-icon-label">%s</span>', $cls, $icon, $status );
$output .= sprintf( '<input type="checkbox" class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" value="1" %s %s></span>', $class, $id, $slug, $id, $slug, $checked, $data );
break;
// Select.
case 'select':
$options = $args['options'];
$value = isset( $args['value'] ) ? $args['value'] : '';
$output = sprintf( '<select class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" %s>', $class, $id, $slug, $id, $slug, $data );
foreach ( $options as $arg_key => $arg_option ) {
$output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $arg_key ), selected( $arg_key, $value, false ), $arg_option );
}
$output .= '</select>';
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Helper function to create common field options that are used frequently.
*
* @since 1.0.0
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed echo or return string
*/
public function field_option( $option, $field, $args = array(), $echo = true ) {
switch ( $option ) {
/**
* Basic Fields.
*/
/*
* Basic Options markup.
*/
case 'basic-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
if ( 'open' === $markup ) {
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-basic" id="wpforms-field-option-basic-%d">', $field['id'] );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <span>(ID #%d)</span> <i class="fa fa-angle-down"></i></a>', $this->name, $field['id'] );
$output .= sprintf( '<div class="wpforms-field-option-group-inner %s">', $class );
} else {
$output = '</div></div>';
}
break;
/*
* Field Label.
*/
case 'label':
$value = ! empty( $field['label'] ) ? esc_attr( $field['label'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field label. Field labels are recommended and can be hidden in the Advanced Settings.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'label', 'value' => esc_html__( 'Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'label', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label', 'content' => $output ), false );
break;
/*
* Field Description.
*/
case 'description':
$value = ! empty( $field['description'] ) ? esc_attr( $field['description'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field description.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'description', 'value' => esc_html__( 'Description', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'description', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'description', 'content' => $output ), false );
break;
/*
* Field Required toggle.
*/
case 'required':
$default = ! empty( $args['default'] ) ? $args['default'] : '0';
$value = isset( $field['required'] ) ? $field['required'] : $default;
$tooltip = esc_html__( 'Check this option to mark the field required. A form will not submit unless all required fields are provided.', 'wpforms-lite' );
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'required', 'value' => $value, 'desc' => esc_html__( 'Required', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'required', 'content' => $output ), false );
break;
/*
* Field Meta (field type and ID).
*/
case 'meta':
$output = sprintf( '<label>%s</label>', 'Type' );
$output .= sprintf( '<p class="meta">%s <span class="id">(ID #%d)</span></p>', $this->name, $field['id'] );
$output = $this->field_element( 'row', $field, array( 'slug' => 'meta', 'content' => $output ), false );
break;
/*
* Code Block.
*/
case 'code':
$value = ! empty( $field['code'] ) ? esc_textarea( $field['code'] ) : '';
$tooltip = esc_html__( 'Enter code for the form field.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'code', 'value' => esc_html__( 'Code', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'textarea', $field, array( 'slug' => 'code', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'code', 'content' => $output ), false );
break;
/*
* Choices.
*/
case 'choices':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$label = ! empty( $args['label'] ) ? esc_html( $args['label'] ) : esc_html__( 'Choices', 'wpforms-lite' );
$class = array();
if ( ! empty( $field['show_values'] ) ) {
$class[] = 'show-values';
}
if ( ! empty( $field['dynamic_choices'] ) ) {
$class[] = 'wpforms-hidden';
}
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => $label,
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
'after_tooltip' => '<a href="#" class="toggle-bulk-add-display"><i class="fa fa-download"></i> <span>' . esc_html__( 'Bulk Add', 'wpforms-lite' ) . '</span></a>',
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="%s" name="%s[default]" class="default" value="1" %s>',
'checkbox' === $this->type ? 'checkbox' : 'radio',
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value">',
$base,
esc_attr( $value['value'] )
);
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Field note: dynamic status.
$source = '';
$type = '';
$dynamic = ! empty( $field['dynamic_choices'] ) ? esc_html( $field['dynamic_choices'] ) : '';
if ( 'post_type' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'post type', 'wpforms-lite' );
$pt = get_post_type_object( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( null !== $pt ) {
$source = $pt->labels->name;
}
} elseif ( 'taxonomy' === $dynamic && ! empty( $field[ 'dynamic_' . $dynamic ] ) ) {
$type = esc_html__( 'taxonomy', 'wpforms-lite' );
$tax = get_taxonomy( $field[ 'dynamic_' . $dynamic ] );
$source = '';
if ( false !== $tax ) {
$source = $tax->labels->name;
}
}
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
empty( $dynamic ) && ! empty( $field[ 'dynamic_' . $dynamic ] ) ? '' : 'wpforms-hidden'
);
$note .= sprintf(
/* translators: %1$s - source name; %2$s - type name. */
esc_html__( 'Choices are dynamically populated from the %1$s %2$s.', 'wpforms' ),
'<span class="dynamic-name">' . $source . '</span>',
'<span class="dynamic-type">' . $type . '</span>'
);
$note .= '</div>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld . $note,
),
false
);
break;
/*
* Choices for payments.
*/
case 'choices_payments':
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$class = array();
$input_type = in_array( $field['type'], array( 'payment-multiple', 'payment-select' ), true ) ? 'radio' : 'checkbox';
if ( ! empty( $field['choices_images'] ) ) {
$class[] = 'show-images';
}
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices',
'value' => esc_html__( 'Items', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Add choices for the form field.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = sprintf(
'<ul data-next-id="%s" class="choices-list %s" data-field-id="%d" data-field-type="%s">',
max( array_keys( $values ) ) + 1,
wpforms_sanitize_classes( $class, true ),
$field['id'],
$this->type
);
foreach ( $values as $key => $value ) {
$default = ! empty( $value['default'] ) ? $value['default'] : '';
$base = sprintf( 'fields[%s][choices][%s]', $field['id'], $key );
$image = ! empty( $value['image'] ) ? $value['image'] : '';
$image_btn = '';
$fld .= '<li data-key="' . absint( $key ) . '">';
$fld .= sprintf(
'<input type="%s" name="%s[default]" class="default" value="1" %s>',
$input_type,
$base,
checked( '1', $default, false )
);
$fld .= '<span class="move"><i class="fa fa-bars"></i></span>';
$fld .= sprintf(
'<input type="text" name="%s[label]" value="%s" class="label">',
$base,
esc_attr( $value['label'] )
);
$fld .= sprintf(
'<input type="text" name="%s[value]" value="%s" class="value wpforms-money-input" placeholder="%s">',
$base,
esc_attr( $value['value'] ),
wpforms_format_amount( 0 )
);
$fld .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a><a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
$fld .= '<div class="wpforms-image-upload">';
$fld .= '<div class="preview">';
if ( ! empty( $image ) ) {
$fld .= sprintf(
'<a href="#" title="%s" class="wpforms-image-upload-remove"><img src="%s"></a>',
esc_attr__( 'Remove Image', 'wpforms-lite' ),
esc_url_raw( $image )
);
$image_btn = ' style="display:none;"';
}
$fld .= '</div>';
$fld .= sprintf(
'<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-btn-block wpforms-image-upload-add" data-after-upload="hide"%s>%s</button>',
$image_btn,
esc_html__( 'Upload Image', 'wpforms-lite' )
);
$fld .= sprintf(
'<input type="hidden" name="%s[image]" value="%s" class="source">',
$base,
esc_url_raw( $image )
);
$fld .= '</div>';
$fld .= '</li>';
}
$fld .= '</ul>';
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices',
'content' => $lbl . $fld,
),
false
);
break;
/*
* Choices Images.
*/
case 'choices_images':
// Field note: Image tips.
$note = sprintf(
'<div class="wpforms-alert-warning wpforms-alert-small wpforms-alert %s">',
! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden'
);
$note .= esc_html__( 'Images are not cropped or resized. For best results, they should be the same size and 250x250 pixels or smaller.', 'wpforms-lite' );
$note .= '</div>';
// Field contents.
$fld = $this->field_element(
'checkbox',
$field,
array(
'slug' => 'choices_images',
'value' => isset( $field['choices_images'] ) ? '1' : '0',
'desc' => esc_html__( 'Use image choices', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Check this option to enable using images with the choices.', 'wpforms-lite' ),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images',
'class' => ! empty( $field['dynamic_choices'] ) ? 'wpforms-hidden' : '',
'content' => $note . $fld,
),
false
);
break;
/*
* Choices Images Style.
*/
case 'choices_images_style':
// Field label.
$lbl = $this->field_element(
'label',
$field,
array(
'slug' => 'choices_images_style',
'value' => esc_html__( 'Image Choice Style', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Select the style for the image choices.', 'wpforms-lite' ),
),
false
);
// Field contents.
$fld = $this->field_element(
'select',
$field,
array(
'slug' => 'choices_images_style',
'value' => ! empty( $field['choices_images_style'] ) ? esc_attr( $field['choices_images_style'] ) : 'modern',
'options' => array(
'modern' => esc_html__( 'Modern', 'wpforms-lite' ),
'classic' => esc_html__( 'Classic', 'wpforms-lite' ),
'none' => esc_html__( 'None', 'wpforms-lite' ),
),
),
false
);
// Final field output.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'choices_images_style',
'content' => $lbl . $fld,
'class' => ! empty( $field['choices_images'] ) ? '' : 'wpforms-hidden',
),
false
);
break;
/**
* Advanced Fields.
*/
/*
* Default value.
*/
case 'default_value':
$value = ! empty( $field['default_value'] ) ? esc_attr( $field['default_value'] ) : '';
$tooltip = esc_html__( 'Enter text for the default form field value.', 'wpforms-lite' );
$toggle = '<a href="#" class="toggle-smart-tag-display" data-type="other"><i class="fa fa-tags"></i> <span>' . esc_html__( 'Show Smart Tags', 'wpforms-lite' ) . '</span></a>';
$output = $this->field_element( 'label', $field, array( 'slug' => 'default_value', 'value' => esc_html__( 'Default Value', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'default_value', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'default_value', 'content' => $output ), false );
break;
/*
* Size.
*/
case 'size':
$value = ! empty( $field['size'] ) ? esc_attr( $field['size'] ) : 'medium';
$class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
$tooltip = esc_html__( 'Select the default form field size.', 'wpforms-lite' );
$options = array(
'small' => esc_html__( 'Small', 'wpforms-lite' ),
'medium' => esc_html__( 'Medium', 'wpforms-lite' ),
'large' => esc_html__( 'Large', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'size', 'value' => esc_html__( 'Field Size', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'size', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'size', 'content' => $output, 'class' => $class ), false );
break;
/*
* Advanced Options markup.
*/
case 'advanced-options':
$markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
if ( 'open' === $markup ) {
$override = apply_filters( 'wpforms_advanced_options_override', false );
$override = ! empty( $override ) ? 'style="display:' . $override . ';"' : '';
$output = sprintf( '<div class="wpforms-field-option-group wpforms-field-option-group-advanced wpforms-hide" id="wpforms-field-option-advanced-%d" %s>', $field['id'], $override );
$output .= sprintf( '<a href="#" class="wpforms-field-option-group-toggle">%s <i class="fa fa-angle-right"></i></a>', esc_html__( 'Advanced Options', 'wpforms-lite' ) );
$output .= '<div class="wpforms-field-option-group-inner">';
} else {
$output = '</div></div>';
}
break;
/*
* Placeholder.
*/
case 'placeholder':
$value = ! empty( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : '';
$tooltip = esc_html__( 'Enter text for the form field placeholder.', 'wpforms-lite' );
$output = $this->field_element( 'label', $field, array( 'slug' => 'placeholder', 'value' => esc_html__( 'Placeholder Text', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'placeholder', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'placeholder', 'content' => $output ), false );
break;
/*
* CSS classes.
*/
case 'css':
$toggle = '';
$value = ! empty( $field['css'] ) ? esc_attr( $field['css'] ) : '';
$tooltip = esc_html__( 'Enter CSS class names for the form field container. Class names should be separated with spaces.', 'wpforms-lite' );
if ( 'pagebreak' !== $field['type'] ) {
$toggle = '<a href="#" class="toggle-layout-selector-display"><i class="fa fa-th-large"></i> <span>' . esc_html__( 'Show Layouts', 'wpforms-lite' ) . '</span></a>';
}
// Build output.
$output = $this->field_element( 'label', $field, array( 'slug' => 'css', 'value' => esc_html__( 'CSS Classes', 'wpforms-lite' ), 'tooltip' => $tooltip, 'after_tooltip' => $toggle ), false );
$output .= $this->field_element( 'text', $field, array( 'slug' => 'css', 'value' => $value ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'css', 'content' => $output ), false );
break;
/*
* Hide Label.
*/
case 'label_hide':
$value = isset( $field['label_hide'] ) ? $field['label_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'label_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Label', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'label_hide', 'content' => $output ), false );
break;
/*
* Hide Sub-Labels.
*/
case 'sublabel_hide':
$value = isset( $field['sublabel_hide'] ) ? $field['sublabel_hide'] : '0';
$tooltip = esc_html__( 'Check this option to hide the form field sub-label.', 'wpforms-lite' );
// Build output.
$output = $this->field_element( 'checkbox', $field, array( 'slug' => 'sublabel_hide', 'value' => $value, 'desc' => esc_html__( 'Hide Sub-Labels', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'sublabel_hide', 'content' => $output ), false );
break;
/*
* Input Columns.
*/
case 'input_columns':
$value = ! empty( $field['input_columns'] ) ? esc_attr( $field['input_columns'] ) : '';
$tooltip = esc_html__( 'Select the layout for displaying field choices.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'One Column', 'wpforms-lite' ),
'2' => esc_html__( 'Two Columns', 'wpforms-lite' ),
'3' => esc_html__( 'Three Columns', 'wpforms-lite' ),
'inline' => esc_html__( 'Inline', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'input_columns', 'value' => esc_html__( 'Choice Layout', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'input_columns', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'input_columns', 'content' => $output ), false );
break;
/*
* Dynamic Choices.
*/
case 'dynamic_choices':
$value = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
$tooltip = esc_html__( 'Select auto-populate method to use.', 'wpforms-lite' );
$options = array(
'' => esc_html__( 'Off', 'wpforms-lite' ),
'post_type' => esc_html__( 'Post Type', 'wpforms-lite' ),
'taxonomy' => esc_html__( 'Taxonomy', 'wpforms-lite' ),
);
$output = $this->field_element( 'label', $field, array( 'slug' => 'dynamic_choices', 'value' => esc_html__( 'Dynamic Choices', 'wpforms-lite' ), 'tooltip' => $tooltip ), false );
$output .= $this->field_element( 'select', $field, array( 'slug' => 'dynamic_choices', 'value' => $value, 'options' => $options ), false );
$output = $this->field_element( 'row', $field, array( 'slug' => 'dynamic_choices', 'content' => $output ), false );
break;
/*
* Dynamic Choices Source.
*/
case 'dynamic_choices_source':
$output = '';
$type = ! empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
if ( ! empty( $type ) ) {
$type_name = '';
$items = array();
if ( 'post_type' === $type ) {
$type_name = esc_html__( 'Post Type', 'wpforms-lite' );
$items = get_post_types(
array(
'public' => true,
),
'objects'
);
unset( $items['attachment'] );
} elseif ( 'taxonomy' === $type ) {
$type_name = esc_html__( 'Taxonomy', 'wpforms-lite' );
$items = get_taxonomies(
array(
'public' => true,
),
'objects'
);
unset( $items['post_format'] );
}
/* translators: %s - dynamic source type name. */
$tooltip = sprintf( esc_html__( 'Select %s to use for auto-populating field choices.', 'wpforms-lite' ), $type_name );
/* translators: %s - dynamic source type name. */
$label = sprintf( esc_html__( 'Dynamic %s Source', 'wpforms-lite' ), $type_name );
$options = array();
$source = ! empty( $field[ 'dynamic_' . $type ] ) ? esc_attr( $field[ 'dynamic_' . $type ] ) : '';
foreach ( $items as $key => $item ) {
$options[ $key ] = $item->labels->name;
}
// Field option label.
$option_label = $this->field_element(
'label',
$field,
array(
'slug' => 'dynamic_' . $type,
'value' => $label,
'tooltip' => $tooltip,
),
false
);
// Field option select input.
$option_input = $this->field_element(
'select',
$field,
array(
'slug' => 'dynamic_' . $type,
'options' => $options,
'value' => $source,
),
false
);
// Field option row (markup) including label and input.
$output = $this->field_element(
'row',
$field,
array(
'slug' => 'dynamic_' . $type,
'content' => $option_label . $option_input,
),
false
);
} // End if().
break;
}
if ( ! $echo ) {
return $output;
}
if ( in_array( $option, array( 'basic-options', 'advanced-options' ), true ) ) {
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_before_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_bottom_{$option}", $field, $this );
}
echo $output; // WPCS: XSS ok.
if ( 'open' === $markup ) {
do_action( "wpforms_field_options_top_{$option}", $field, $this );
}
if ( 'close' === $markup ) {
do_action( "wpforms_field_options_after_{$option}", $field, $this );
}
} else {
echo $output; // WPCS: XSS ok.
}
}
/**
* Helper function to create common field options that are used frequently
* in the field preview.
*
* @since 1.0.0
* @since 1.5.0 Added support for <select> HTML tag for choices.
*
* @param string $option Field option to render.
* @param array $field Field data and settings.
* @param array $args Field preview arguments.
* @param boolean $echo Print or return the value. Print by default.
*
* @return mixed Print or return a string.
*/
public function field_preview_option( $option, $field, $args = array(), $echo = true ) {
$output = '';
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
switch ( $option ) {
case 'label':
$label = isset( $field['label'] ) && ! empty( $field['label'] ) ? esc_html( $field['label'] ) : '';
$output = sprintf( '<label class="label-title %s"><span class="text">%s</span><span class="required">*</span></label>', $class, $label );
break;
case 'description':
$description = isset( $field['description'] ) && ! empty( $field['description'] ) ? $field['description'] : '';
$description = strpos( $class, 'nl2br' ) !== false ? nl2br( $description ) : $description;
$output = sprintf( '<div class="description %s">%s</div>', $class, $description );
break;
case 'choices':
$fields_w_choices = array( 'checkbox', 'gdpr-checkbox', 'select', 'payment-select', 'radio', 'payment-multiple', 'payment-checkbox' );
$values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
$dynamic = ! empty( $field['dynamic_choices'] ) ? $field['dynamic_choices'] : false;
$total = 0;
/*
* Check to see if this field is configured for Dynamic Choices,
* either auto populating from a post type or a taxonomy.
*/
if ( ! empty( $field['dynamic_post_type'] ) ) {
switch ( $dynamic ) {
case 'post_type':
// Post type dynamic populating.
$total_obj = wp_count_posts( $field['dynamic_post_type'] );
$total = isset( $total_obj->publish ) ? (int) $total_obj->publish : 0;
$values = array();
$posts = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_post_type_args',
array(
'post_type' => $field['dynamic_post_type'],
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
),
$field,
$this->form_id
),
true
);
foreach ( $posts as $post ) {
$values[] = array(
'label' => $post->post_title,
);
}
break;
case 'taxonomy':
// Taxonomy dynamic populating.
$total = (int) wp_count_terms( $field['dynamic_taxonomy'] );
$values = array();
$terms = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_taxonomy_args',
array(
'taxonomy' => $field['dynamic_taxonomy'],
'hide_empty' => false,
),
$field,
$this->form_id
),
true
);
foreach ( $terms as $term ) {
$values[] = array(
'label' => $term->name,
);
}
break;
}
}
// Notify if dynamic choices source is currently empty.
if ( empty( $values ) ) {
$values = array(
'label' => esc_html__( '(empty)', 'wpforms-lite' ),
);
}
// Build output.
if ( ! in_array( $field['type'], $fields_w_choices, true ) ) {
break;
}
switch ( $field['type'] ) {
case 'checkbox':
case 'gdpr-checkbox':
case 'payment-checkbox':
$type = 'checkbox';
break;
case 'select':
case 'payment-select':
$type = 'select';
break;
default:
$type = 'radio';
break;
}
$list_class = array( 'primary-input' );
$with_images = empty( $field['dynamic_choices'] ) && ! empty( $field['choices_images'] );
if ( $with_images ) {
$list_class[] = 'wpforms-image-choices';
$list_class[] = 'wpforms-image-choices-' . sanitize_html_class( $field['choices_images_style'] );
}
// Special rules for <select>-based fields.
if ( 'select' === $type ) {
$placeholder = ! empty( $field['placeholder'] ) ? $field['placeholder'] : '';
$output = sprintf(
'<select class="%s" disabled>',
wpforms_sanitize_classes( $list_class, true )
);
// Optional placeholder.
if ( ! empty( $placeholder ) ) {
$output .= sprintf(
'<option value="" class="placeholder">%s</option>',
esc_html( $placeholder )
);
}
// Build the select options (even though user can only see 1st option).
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? (bool) $value['default'] : false;
$selected = ! empty( $placeholder ) ? '' : selected( true, $default, false );
$output .= sprintf(
'<option %s>%s</option>',
$selected,
esc_html( $value['label'] )
);
}
$output .= '</select>';
} else {
// Normal checkbox/radio-based fields.
$output = sprintf(
'<ul class="%s">',
wpforms_sanitize_classes( $list_class, true )
);
foreach ( $values as $key => $value ) {
$default = isset( $value['default'] ) ? $value['default'] : '';
$selected = checked( '1', $default, false );
$input_class = array();
$item_class = array();
if ( ! empty( $value['default'] ) ) {
$item_class[] = 'wpforms-selected';
}
if ( $with_images ) {
$item_class[] = 'wpforms-image-choices-item';
}
$output .= sprintf(
'<li class="%s">',
wpforms_sanitize_classes( $item_class, true )
);
if ( $with_images ) {
if ( in_array( $field['choices_images_style'], array( 'modern', 'classic' ), true ) ) {
$input_class[] = 'wpforms-screen-reader-element';
}
$output .= '<label>';
$output .= sprintf(
'<span class="wpforms-image-choices-image"><img src="%s" alt="%s"%s></span>',
! empty( $value['image'] ) ? esc_url( $value['image'] ) : WPFORMS_PLUGIN_URL . 'assets/images/placeholder-200x125.png',
esc_attr( $value['label'] ),
! empty( $value['label'] ) ? ' title="' . esc_attr( $value['label'] ) . '"' : ''
);
if ( 'none' === $field['choices_images_style'] ) {
$output .= '<br>';
}
$output .= sprintf(
'<input type="%s" class="%s" %s disabled>',
$type,
wpforms_sanitize_classes( $input_class, true ),
$selected
);
$output .= '<span class="wpforms-image-choices-label">' . wp_kses_post( $value['label'] ) . '</span>';
$output .= '</label>';
} else {
$output .= sprintf(
'<input type="%s" %s disabled>%s',
$type,
$selected,
$value['label']
);
}
$output .= '</li>';
}
$output .= '</ul>';
}
/*
* Dynamic population is enabled and contains more than 20 items,
* include a note about results displayed.
*/
if ( $total > 20 ) {
$output .= '<div class="wpforms-alert-dynamic wpforms-alert wpforms-alert-warning">';
$output .= sprintf(
wp_kses(
/* translators: %d - total amount of choices. */
__( 'Showing the first 20 choices.<br> All %d choices will be displayed when viewing the form.', 'wpforms-lite' ),
array(
'br' => array(),
)
),
$total
);
$output .= '</div>';
}
break;
}
if ( ! $echo ) {
return $output;
}
echo $output; // WPCS: XSS ok.
}
/**
* Create a new field in the admin AJAX editor.
*
* @since 1.0.0
*/
public function field_new() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
die( esc_html__( 'You do not have permission.', 'wpforms-lite' ) );
}
// Check for form ID.
if ( ! isset( $_POST['id'] ) || empty( $_POST['id'] ) ) {
die( esc_html__( 'No form ID found', 'wpforms-lite' ) );
}
// Check for field type to add.
if ( ! isset( $_POST['type'] ) || empty( $_POST['type'] ) ) {
die( esc_html__( 'No field type found', 'wpforms-lite' ) );
}
// Grab field data.
$field_args = ! empty( $_POST['defaults'] ) ? (array) $_POST['defaults'] : array();
$field_type = esc_attr( $_POST['type'] );
$field_id = wpforms()->form->next_field_id( $_POST['id'] );
$field = array(
'id' => $field_id,
'type' => $field_type,
'label' => $this->name,
'description' => '',
);
$field = wp_parse_args( $field_args, $field );
$field = apply_filters( 'wpforms_field_new_default', $field );
$field_required = apply_filters( 'wpforms_field_new_required', '', $field );
$field_class = apply_filters( 'wpforms_field_new_class', '', $field );
// Field types that default to required.
if ( ! empty( $field_required ) ) {
$field_required = 'required';
$field['required'] = '1';
}
// Build Preview.
ob_start();
$this->field_preview( $field );
$prev = ob_get_clean();
$preview = sprintf( '<div class="wpforms-field wpforms-field-%s %s %s" id="wpforms-field-%d" data-field-id="%d" data-field-type="%s">', $field_type, $field_required, $field_class, $field['id'], $field['id'], $field_type );
$preview .= sprintf( '<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' ) );
$preview .= sprintf( '<a href="#" class="wpforms-field-delete" title="%s"><i class="fa fa-trash"></i></a>', esc_attr__( 'Delete Field', 'wpforms-lite' ) );
$preview .= sprintf( '<span class="wpforms-field-helper">%s</span>', esc_html__( 'Click to edit. Drag to reorder.', 'wpforms-lite' ) );
$preview .= $prev;
$preview .= '</div>';
// Build Options.
$options = sprintf( '<div class="wpforms-field-option wpforms-field-option-%s" id="wpforms-field-option-%d" data-field-id="%d">', esc_attr( $field['type'] ), $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][id]" value="%d" class="wpforms-field-option-hidden-id">', $field['id'], $field['id'] );
$options .= sprintf( '<input type="hidden" name="fields[%d][type]" value="%s" class="wpforms-field-option-hidden-type">', $field['id'], esc_attr( $field['type'] ) );
ob_start();
$this->field_options( $field );
$options .= ob_get_clean();
$options .= '</div>';
// Prepare to return compiled results.
wp_send_json_success(
array(
'form_id' => (int) $_POST['id'],
'field' => $field,
'preview' => $preview,
'options' => $options,
)
);
}
/**
* Display the field input elements on the frontend.
*
* @since 1.0.0
* @since 1.5.0 Converted to abstract method, as it's required for all fields.
*
* @param array $field Field data and settings.
* @param array $field_atts Field attributes.
* @param array $form_data Form data and settings.
*/
abstract public function field_display( $field, $field_atts, $form_data );
/**
* Display field input errors if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param array $field Field data and settings.
*/
public function field_display_error( $key, $field ) {
// Need an error.
if ( empty( $field['properties']['error']['value'][ $key ] ) ) {
return;
}
printf(
'<label class="wpforms-error" for="%s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
esc_html( $field['properties']['error']['value'][ $key ] )
);
}
/**
* Display field input sublabel if present.
*
* @since 1.3.7
*
* @param string $key Input key.
* @param string $position Sublabel position.
* @param array $field Field data and settings.
*/
public function field_display_sublabel( $key, $position, $field ) {
// Need a sublabel value.
if ( empty( $field['properties']['inputs'][ $key ]['sublabel']['value'] ) ) {
return;
}
$pos = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['position'] ) ? $field['properties']['inputs'][ $key ]['sublabel']['position'] : 'after';
$hidden = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['hidden'] ) ? 'wpforms-sublabel-hide' : '';
if ( $pos !== $position ) {
return;
}
printf(
'<label for="%s" class="wpforms-field-sublabel %s %s">%s</label>',
esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
sanitize_html_class( $pos ),
$hidden,
$field['properties']['inputs'][ $key ]['sublabel']['value']
);
}
/**
* Validates field on form submit.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param array $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function validate( $field_id, $field_submit, $form_data ) {
// Basic required check - If field is marked as required, check for entry data.
if ( ! empty( $form_data['fields'][ $field_id ]['required'] ) && empty( $field_submit ) && '0' != $field_submit ) {
wpforms()->process->errors[ $form_data['id'] ][ $field_id ] = wpforms_get_required_label();
}
}
/**
* Formats and sanitizes field.
*
* @since 1.0.0
*
* @param int $field_id Field ID.
* @param mixed $field_submit Field value that was submitted.
* @param array $form_data Form data and settings.
*/
public function format( $field_id, $field_submit, $form_data ) {
if ( is_array( $field_submit ) ) {
$field_submit = array_filter( $field_submit );
$field_submit = implode( "\r\n", $field_submit );
}
$name = ! empty( $form_data['fields'][ $field_id ]['label'] ) ? sanitize_text_field( $form_data['fields'][ $field_id ]['label'] ) : '';
// Sanitize but keep line breaks.
$value = wpforms_sanitize_textarea_field( $field_submit );
wpforms()->process->fields[ $field_id ] = array(
'name' => $name,
'value' => $value,
'id' => absint( $field_id ),
'type' => $this->type,
);
}
}