render();
self::page_footer();
}
/**
* Prepare form settings fields.
*
* @since 2.5
*
* @param array $form Form being edited.
*
* @return array
*/
public static function form_settings_fields( $form ) {
$fields = array(
'form_basics' => array(
'title' => esc_html__( 'Form Basics', 'gravityforms' ),
'fields' => array(
array(
'name' => 'title',
'type' => 'text',
'label' => esc_html__( 'Form Title', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_title', '', true ),
'required' => true,
'validation_callback' => function( $field, $value ) use ( $form ) {
// If value is empty, set error.
if ( rgblank( $value ) ) {
$field->set_error( rgobj( $field, 'error_message' ) );
return;
}
// Get forms.
$forms = GFFormsModel::get_forms();
// Loop through forms, look for duplicate title.
foreach ( $forms as $f ) {
// If form does not have a duplicate title, skip.
if ( strtolower( $f->title ) !== strtolower( $value ) ) {
continue;
}
// If form ID matches, skip.
if ( (int) $form['id'] === (int) $f->id ) {
continue;
}
// Set field error.
$field->set_error( esc_html__( 'The form title you have entered has already been used. Please enter a unique form title.', 'gravityforms' ) );
return;
}
$field->do_validation( $value );
},
),
array(
'name' => 'description',
'type' => 'textarea',
'label' => esc_html__( 'Form Description', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_description', '', true ),
'allow_html' => true,
),
),
),
'form_layout' => array(
'title' => esc_html__( 'Form Layout', 'gravityforms' ),
'fields' => array(
array(
'name' => 'labelPlacement',
'type' => 'select',
'label' => esc_html__( 'Label Placement', 'gravityforms' ),
'default_value' => 'top_label',
'tooltip' => gform_tooltip( 'form_label_placement', '', true ),
'choices' => array(
array(
'label' => __( 'Top aligned', 'gravityforms' ),
'value' => 'top_label',
),
array(
'label' => __( 'Left aligned', 'gravityforms' ),
'value' => 'left_label',
),
array(
'label' => __( 'Right aligned', 'gravityforms' ),
'value' => 'right_label',
),
),
),
array(
'name' => 'descriptionPlacement',
'type' => 'select',
'label' => esc_html__( 'Description Placement', 'gravityforms' ),
'default_value' => 'below',
'tooltip' => gform_tooltip( 'form_description_placement', '', true ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'labelPlacement',
'values' => array( 'top_label' ),
),
),
),
'choices' => array(
array(
'label' => __( 'Below inputs', 'gravityforms' ),
'value' => 'below',
),
array(
'label' => __( 'Above inputs', 'gravityforms' ),
'value' => 'above',
),
),
),
array(
'name' => 'subLabelPlacement',
'type' => 'select',
'label' => esc_html__( 'Sub-Label Placement', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_sub_label_placement', '', true ),
'choices' => array(
array(
'label' => __( 'Below inputs', 'gravityforms' ),
'value' => 'below',
),
array(
'label' => __( 'Above inputs', 'gravityforms' ),
'value' => 'above',
),
),
),
array(
'name' => 'validationSummary',
'type' => 'toggle',
'label' => esc_html__( 'Validation Summary', 'gravityforms' ),
'default_value' => false,
'tooltip' => gform_tooltip( 'validation_summary', '', true ),
),
array(
'name' => 'requiredIndicator',
'label' => esc_html__( 'Required Field Indicator', 'gravityforms' ),
'type' => 'radio',
'default_value' => ( GFCommon::is_legacy_markup_enabled( $form ) ) ? 'asterisk' : 'text',
'horizontal' => true,
'tooltip' => gform_tooltip( 'form_required_indicator', '', true ),
'choices' => array(
array(
'label' => esc_html__( 'Text: (Required)', 'gravityforms' ),
'value' => 'text',
),
array(
'label' => esc_html__( 'Asterisk: *', 'gravityforms' ),
'value' => 'asterisk',
),
array(
'label' => esc_html__( 'Custom:', 'gravityforms' ),
'value' => 'custom',
),
),
),
array(
'name' => 'customRequiredIndicator',
'type' => 'text',
'label' => esc_html__( 'Custom Required Indicator', 'gravityforms' ),
'default_value' => esc_html__( '(Required)', 'gravityforms' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'requiredIndicator',
'values' => array( 'custom' ),
),
),
),
),
array(
'name' => 'cssClass',
'type' => 'text',
'label' => esc_html__( 'CSS Class Name', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_css_class', '', true ),
),
),
),
'form_button' => array(
'title' => esc_html__( 'Form Button', 'gravityforms' ),
'fields' => array(
array(
'name' => 'buttonType',
'label' => esc_html__( 'Input Type', 'gravityforms' ),
'type' => 'radio',
'default_value' => 'text',
'horizontal' => true,
'choices' => array(
array(
'label' => esc_html__( 'Text', 'gravityforms' ),
'value' => 'text',
),
array(
'label' => esc_html__( 'Image', 'gravityforms' ),
'value' => 'image',
),
),
),
array(
'name' => 'buttonText',
'type' => 'text',
'label' => esc_html__( 'Button Text', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_button_text', '', true ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'buttonType',
'values' => array( 'text' ),
),
),
),
),
array(
'name' => 'buttonImageURL',
'type' => 'text',
'label' => esc_html__( 'Button Image URL', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_button_image', '', true ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'buttonType',
'values' => array( 'image' ),
),
),
),
),
array(
'name' => 'form_button_conditional_logic',
'label' => esc_html__( 'Conditional Logic', 'gravityforms ' ),
'type' => 'conditional_logic',
'object_type' => 'form_button',
'checkbox' => array(
'label' => esc_html__( 'Enable conditional logic', 'gravityforms' ),
'hidden' => false,
),
),
),
),
'save_and_continue' => array(
'title' => esc_html__( 'Save and Continue', 'gravityforms' ),
'fields' => array(
array(
'name' => 'saveEnabled',
'type' => 'toggle',
'label' => __( 'Enable Save and Continue', 'gravityforms' ),
),
array(
'name' => 'saveButtonText',
'type' => 'text',
'label' => esc_html__( 'Link Text', 'gravityforms' ),
'default_value' => __( 'Save and Continue Later', 'gravityforms' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'saveEnabled',
),
),
),
'description' => sprintf(
'
',
esc_html( 'This feature stores potentially private and sensitive data on this server and protects it with a unique link which is displayed to the user on the page in plain, unencrypted text. The link is similar to a password so it\'s strongly advisable to ensure that the page enforces a secure connection (HTTPS) before activating this setting.', 'gravityforms' ),
esc_html( 'When this setting is activated two confirmations and one notification are automatically generated and can be modified in their respective editors. When this setting is deactivated the confirmations and the notification will be deleted automatically and any modifications will be lost.', 'gravityforms' )
),
),
),
),
'restrictions' => array(
'title' => esc_html__( 'Restrictions', 'gravityforms' ),
'fields' => array(
array(
'name' => 'limitEntries',
'type' => 'checkbox',
'label' => __( 'Limit number of entries', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_limit_entries', '', true ),
'choices' => array(
array(
'name' => 'limitEntries',
'label' => __( 'Enable entry limit', 'gravityforms' ),
),
),
'fields' => array(
array(
'name' => 'limitEntriesNumber',
'type' => 'text_and_select',
'label' => __( 'Number of Entries', 'gravityforms' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'limitEntries',
),
),
),
'inputs' => array(
'text' => array(
'name' => 'limitEntriesCount',
'input_type' => 'number',
),
'select' => array(
'name' => 'limitEntriesPeriod',
'choices' => array(
array(
'label' => __( 'total entries', 'gravityforms' ),
'value' => '',
),
array(
'label' => __( 'per day', 'gravityforms' ),
'value' => 'day',
),
array(
'label' => __( 'per week', 'gravityforms' ),
'value' => 'week',
),
array(
'label' => __( 'per month', 'gravityforms' ),
'value' => 'month',
),
array(
'label' => __( 'per year', 'gravityforms' ),
'value' => 'year',
),
),
),
),
),
array(
'name' => 'limitEntriesMessage',
'type' => 'textarea',
'label' => esc_html__( 'Entry Limit Reached Message', 'gravityforms' ),
'allow_html' => true,
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'limitEntries',
),
),
),
),
),
),
array(
'name' => 'scheduleForm',
'type' => 'checkbox',
'label' => __( 'Schedule Form', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_schedule_form', '', true ),
'choices' => array(
array(
'name' => 'scheduleForm',
'label' => __( 'Schedule Form', 'gravityforms' ),
),
),
'fields' => array(
array(
'name' => 'scheduleStart',
'type' => 'date_time',
'label' => esc_html__( 'Schedule Start Date/Time', 'gravityforms' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'scheduleForm',
),
),
),
),
array(
'name' => 'scheduleEnd',
'type' => 'date_time',
'label' => esc_html__( 'Schedule Form End Date/Time', 'gravityforms' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'scheduleForm',
),
),
),
),
array(
'name' => 'schedulePendingMessage',
'type' => 'textarea',
'label' => esc_html__( 'Form Pending Message', 'gravityforms' ),
'allow_html' => true,
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'scheduleForm',
),
),
),
),
array(
'name' => 'scheduleMessage',
'type' => 'textarea',
'label' => esc_html__( 'Form Expired Message', 'gravityforms' ),
'allow_html' => true,
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'scheduleForm',
),
),
),
),
),
),
array(
'name' => 'requireLogin',
'type' => 'checkbox',
'label' => __( 'Require user to be logged in', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_require_login', '', true ),
'choices' => array(
array(
'name' => 'requireLogin',
'label' => __( 'Require user to be logged in', 'gravityforms' ),
),
),
'fields' => array(
array(
'name' => 'requireLoginMessage',
'type' => 'textarea',
'label' => esc_html__( 'Require Login Message', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_require_login_message', '', true ),
'allow_html' => true,
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'requireLogin',
),
),
),
),
),
),
),
),
'form_options' => array(
'title' => esc_html__( 'Form Options', 'gravityforms' ),
'fields' => array(
array(
'name' => 'enableHoneypot',
'type' => 'toggle',
'label' => __( 'Anti-spam honeypot', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_honeypot', '', true ),
),
array(
'name' => 'enableAnimation',
'type' => 'toggle',
'label' => __( 'Animated transitions', 'gravityforms' ),
'tooltip' => gform_tooltip( 'form_animation', '', true ),
),
array(
'name' => 'markupVersion',
'type' => 'toggle',
'label' => __( 'Enable legacy markup', 'gravityforms' ),
'default_value' => rgar( $form, 'markupVersion' ) ? $form['markupVersion'] : 1,
'tooltip' => gform_tooltip( 'form_legacy_markup', '', true ),
),
),
),
);
/**
* Filters the form settings before they are displayed.
*
* @deprecated
* @since 1.7
*
* @param array $form_settings The form settings.
* @param array $form The Form Object.
*/
$legacy_settings = apply_filters( 'gform_form_settings', array(), $form );
// If legacy settings exist, add to fields.
if ( ! empty( $legacy_settings ) ) {
// Add section.
$fields['legacy_settings'] = array(
'title' => esc_html__( 'Legacy Settings', 'gravityforms' ),
'fields' => array(
array(
'name' => 'legacy',
'type' => 'html',
'html' => function() {
$form_id = rgget( 'id' );
$form = GFFormsModel::get_form_meta( $form_id );
$legacy_settings = apply_filters( 'gform_form_settings', array(), $form );
$html = '';
return $html;
},
),
),
);
}
/**
* Filters the form settings fields before they are displayed.
*
* @since 2.5
*
* @param array $fields Form settings fields.
* @param array $form Form Object.
*/
$fields = gf_apply_filters( array( 'gform_form_settings_fields', rgar( $form, 'id' ) ), $fields, $form );
return $fields;
}
// # SETTINGS RENDERER ---------------------------------------------------------------------------------------------
/**
* Initialize Plugin Settings fields renderer.
*
* @since 2.5
*/
public static function initialize_settings_renderer() {
require_once( GFCommon::get_base_path() . '/form_detail.php' );
$form_id = rgget( 'id' );
$form = GFFormsModel::get_form_meta( $form_id );
$form = gf_apply_filters( array( 'gform_admin_pre_render', $form_id ), $form );
// Initialize new settings renderer.
$renderer = new Settings(
array(
'fields' => array_values( self::form_settings_fields( $form ) ),
'initial_values' => self::get_initial_values( $form ),
'save_callback' => function( $values ) use ( &$form ) {
// Get form object.
$form_id = rgget( 'id' );
$form = GFFormsModel::get_form_meta( $form_id );
// Set form version.
$form['version'] = GFForms::$version;
// Save custom settings fields to the form object if they don't already exist there.
$form = self::save_changed_form_settings_fields( $form, $values );
// Form Basics
$form['title'] = rgar( $values, 'title' );
$form['description'] = rgar( $values, 'description' );
// Form Layout
$form['labelPlacement'] = GFCommon::whitelist( rgar( $values, 'labelPlacement' ), array( 'top_label', 'left_label', 'right_label' ) );
$form['descriptionPlacement'] = GFCommon::whitelist( rgar( $values, 'descriptionPlacement' ), array( 'below', 'above' ) );
$form['subLabelPlacement'] = GFCommon::whitelist( rgar( $values, 'subLabelPlacement' ), array( 'below', 'above' ) );
$form['validationSummary'] = rgar( $values, 'validationSummary', false );
$form['requiredIndicator'] = GFCommon::whitelist( rgar( $values, 'requiredIndicator' ), array( 'text', 'asterisk', 'custom' ) );
$form['customRequiredIndicator'] = rgar( $values, 'customRequiredIndicator' );
$form['cssClass'] = rgar( $values, 'cssClass' );
// Form Button
$form['button']['type'] = GFCommon::whitelist( rgar( $values, 'buttonType' ), array( 'text', 'image' ) );
$form['button']['text'] = rgar( $values, 'buttonText' );
$form['button']['imageUrl'] = rgar( $values, 'buttonImageURL' );
$form['button']['conditionalLogic'] = rgar( $values, 'form_button_conditional_logic' ) ? rgar( $values, 'form_button_conditional_logic_object' ) : null;
// Save and Continue
$form['save']['enabled'] = (bool) rgar( $values, 'saveEnabled' );
$form['save']['button']['type'] = 'link';
$form['save']['button']['text'] = rgar( $values, 'saveButtonText' );
// Limit Entries
$form['limitEntries'] = (bool) rgar( $values, 'limitEntries' );
$form['limitEntriesCount'] = absint( rgar( $values, 'limitEntriesCount' ) );
$form['limitEntriesPeriod'] = rgar( $values, 'limitEntriesPeriod' ) ? GFCommon::whitelist( $values['limitEntriesPeriod'], array( '', 'day', 'week', 'month', 'year' ) ) : '';
$form['limitEntriesMessage'] = rgar( $values, 'limitEntriesMessage' );
// Require Login
$form['requireLogin'] = (bool) rgar( $values, 'requireLogin' );
$form['requireLoginMessage'] = rgar( $values, 'requireLoginMessage' );
// Scheduling
$form['scheduleForm'] = rgar( $values, 'scheduleForm' );
$form['scheduleStart'] = rgars( $values, 'scheduleStart/date' );
$form['scheduleStartHour'] = rgars( $values, 'scheduleStart/hour' );
$form['scheduleStartMinute'] = rgars( $values, 'scheduleStart/minute' );
$form['scheduleStartAmpm'] = rgars( $values, 'scheduleStart/ampm' );
$form['scheduleEnd'] = rgars( $values, 'scheduleEnd/date' );
$form['scheduleEndHour'] = rgars( $values, 'scheduleEnd/hour' );
$form['scheduleEndMinute'] = rgars( $values, 'scheduleEnd/minute' );
$form['scheduleEndAmpm'] = rgars( $values, 'scheduleEnd/ampm' );
$form['schedulePendingMessage'] = rgar( $values, 'schedulePendingMessage' );
$form['scheduleMessage'] = rgar( $values, 'scheduleMessage' );
// Form Options
$form['enableHoneypot'] = (bool) rgar( $values, 'enableHoneypot' );
$form['enableAnimation'] = (bool) rgar( $values, 'enableAnimation' );
$form['markupVersion'] = rgar( $values, 'markupVersion' ) ? 1 : 2;
// Enable/Disable Save & Continue.
if ( $form['save']['enabled'] ) {
$form = GFFormSettings::activate_save( $form );
} else {
$form = GFFormSettings::deactivate_save( $form );
}
/**
* Filters the updated form settings before being saved.
*
* @since 1.7
*
* @param array $form The form settings.
*/
$form = apply_filters( 'gform_pre_form_settings_save', $form );
// Save form.
GFFormDetail::save_form_info( $form_id, addslashes( json_encode( $form ) ) );
},
'before_fields' => function() use ( &$form ) {
?>
is_save_postback() ) {
self::get_settings_renderer()->process_postback();
}
}
/**
* Gets the current or default values of settings fields.
*
* Loop through all of the current settings and add in default values to pre-populate the settings fields.
*
* @since 2.5
*
* @param $form
*
* @return array
*/
private static function get_initial_values( $form ) {
$initial_values = array();
if ( empty( $form ) ) {
return $initial_values;
}
// Get all of the current values.
foreach ( $form as $key => $value ) {
if ( is_array( $value ) ) {
foreach ( $value as $sub_key => $sub_value ) {
if ( is_array( $sub_value ) ) {
foreach ( $sub_value as $third_key => $third_value ) {
$initial_values[ $key . ucfirst( $sub_key ) . ucfirst( $third_key ) ] = $third_value;
}
} else {
$initial_values[ $key . ucfirst( $sub_key ) ] = $sub_value;
}
}
} else {
$initial_values[ $key ] = $value;
}
}
// Start and end times are formatted differently than other fields.
$initial_values['scheduleStart'] = array(
'date' => rgar( $form, 'scheduleStart' ),
'hour' => rgar( $form, 'scheduleStartHour' ),
'minute' => rgar( $form, 'scheduleStartMinute' ),
'ampm' => rgar( $form, 'scheduleStartAmpm' ),
);
$initial_values['scheduleEnd'] = array(
'date' => rgar( $form, 'scheduleEnd' ),
'hour' => rgar( $form, 'scheduleEndHour' ),
'minute' => rgar( $form, 'scheduleEndMinute' ),
'ampm' => rgar( $form, 'scheduleEndAmpm' ),
);
// Conditional logic fields need different keys.
$initial_values['form_button_conditional_logic'] = isset( $form['button']['conditionalLogic'] ) && ! empty( $form['button']['conditionalLogic'] );
$initial_values['form_button_conditional_logic_object'] = rgars( $form, 'button/conditionalLogic' );
/**
* Filter the initial values that will be populated into the form settings.
*
* @since 2.5
*
* @param array $initial_values An associative array of setting names and their initial values.
* @param array $form The current form.
*/
return apply_filters( 'gform_form_settings_initial_values', $initial_values, $form );
}
/**
* Gets the current instance of Settings handling settings rendering.
*
* @since 2.5
*
* @return false|Gravity_Forms\Gravity_Forms\Settings\Settings
*/
private static function get_settings_renderer() {
return self::$_settings_renderer;
}
/**
* Sets the current instance of Settings handling settings rendering.
*
* @since 2.5
*
* @param Gravity_Forms\Gravity_Forms\Settings\Settings $renderer Settings renderer.
*
* @return bool|WP_Error
*/
private static function set_settings_renderer( $renderer ) {
// Ensure renderer is an instance of Settings
if ( ! is_a( $renderer, 'Gravity_Forms\Gravity_Forms\Settings\Settings' ) ) {
return new WP_Error( 'Renderer must be an instance of Gravity_Forms\Gravity_Forms\Settings\Settings.' );
}
self::$_settings_renderer = $renderer;
return true;
}
// # NOTIFICATIONS -------------------------------------------------------------------------------------------------
/**
* Runs the notification page.
*
* @since Unknown
* @access public
*
* @used-by GFFormSettings::form_settings_page()
* @uses GFNotification::notification_page()
*
* @return void
*/
public static function notification_page() {
require_once( 'notification.php' );
// Page header loaded in below function because admin messages were not yet available to the header to display.
GFNotification::notification_page();
}
/**
* Renders the Personal Data page.
*
* @since 2.4
*/
public static function personal_data_page() {
self::page_header( __( 'Personal Data', 'gravityforms' ) );
require_once( 'includes/class-personal-data.php' );
$form_id = absint( rgget( 'id' ) );
GF_Personal_Data::form_settings( $form_id );
self::page_footer();
}
/**
* Displays the form settings page header.
*
* @since Unknown
* @access public
*
* @used-by GFFormSettings::confirmations_edit_page()
* @used-by GFFormSettings::confirmations_list_page()
* @used-by GFFormSettings::form_settings_ui()
* @used-by GFNotification::notification_edit_page()
* @used-by GFNotification::notification_list_page()
* @used-by GFAddOn::form_settings_page()
* @uses SCRIPT_DEBUG
* @uses GFFormsModel::get_form_meta()
* @uses GFFormSettings::get_tabs()
* @uses GFCommon::form_page_title()
* @uses GFCommon::display_dismissible_message()
* @uses GFCommon::display_admin_message()
* @uses GFForms::top_toolbar()
* @uses GFCommon::get_browser_class()
*
* @param string $title The title to display as the page header. Defaults to empty string.
*
* @return void
*/
public static function page_header( $title = '' ) {
// Print admin styles.
wp_print_styles( array( 'jquery-ui-styles', 'gform_admin', 'gform_settings', 'wp-pointer' ) );
$form = GFFormsModel::get_form_meta( rgget( 'id' ) );
$current_tab = rgempty( 'subview', $_GET ) ? 'settings' : rgget( 'subview' );
$setting_tabs = GFFormSettings::get_tabs( $form['id'] );
// Kind of boring having to pass the title, optionally get it from the settings tab
if ( ! $title ) {
foreach ( $setting_tabs as $tab ) {
if ( $tab['name'] == $current_tab ) {
$title = $tab['label'];
}
}
}
?>