update plugins
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Calculation extends GF_Field {
|
||||
|
||||
public $type = 'calculation';
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'disable_quantity_setting',
|
||||
'rules_setting',
|
||||
'duplicate_setting',
|
||||
'calculation_setting',
|
||||
'conditional_logic_field_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$quantity_id = $this->id . '.3';
|
||||
$quantity = rgget( $quantity_id, $value );
|
||||
|
||||
if ( $this->isRequired && rgblank( $quantity ) && ! $this->disableQuantity ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty($this->errorMessage) ? esc_html__( 'This field is required.', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( ! empty( $quantity ) && ( ! is_numeric( $quantity ) || intval( $quantity ) != floatval( $quantity ) || intval( $quantity ) < 0 ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Please enter a valid quantity', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field inputs.
|
||||
*
|
||||
* @since unknown
|
||||
* @since 2.5 Add accessibility enhancements.
|
||||
*
|
||||
* @param array $form The form object.
|
||||
* @param string $value The field value.
|
||||
* @param array $entry The entry object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_legacy_markup = GFCommon::is_legacy_markup_enabled( $form );
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$product_name = ! is_array( $value ) || empty( $value[ $this->id . '.1' ] ) ? esc_attr( $this->label ) : esc_attr( $value[ $this->id . '.1' ] );
|
||||
$price = ! is_array( $value ) || empty( $value[ $this->id . '.2' ] ) ? $this->basePrice : esc_attr( $value[ $this->id . '.2' ] );
|
||||
$quantity = is_array( $value ) ? esc_attr( $value[ $this->id . '.3' ] ) : '';
|
||||
|
||||
if ( empty( $price ) ) {
|
||||
$price = 0;
|
||||
}
|
||||
|
||||
$has_quantity = sizeof( GFCommon::get_product_fields_by_type( $form, array( 'quantity' ), $this->id ) ) > 0;
|
||||
if ( $has_quantity ) {
|
||||
$this->disableQuantity = true;
|
||||
}
|
||||
|
||||
$currency = $is_entry_detail && ! empty( $entry ) ? $entry['currency'] : '';
|
||||
|
||||
$quantity_field = '';
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$product_quantity_sub_label = $this->get_product_quantity_label( $form_id );
|
||||
|
||||
if ( $is_entry_detail || $is_form_editor ) {
|
||||
$style = $this->disableQuantity ? "style='display:none;'" : '';
|
||||
$quantity_field = " <span class='ginput_quantity_label gform-field-label gform-field-label--type-sub-large' {$style}>{$product_quantity_sub_label}</span> <input type='number' name='input_{$id}.3' value='{$quantity}' id='ginput_quantity_{$form_id}_{$this->id}' class='ginput_quantity' size='10' min='0' {$disabled_text} />";
|
||||
} elseif ( ! $this->disableQuantity ) {
|
||||
$tabindex = $this->get_tabindex();
|
||||
$describedby_extra_id = array();
|
||||
if ( ! $is_legacy_markup ) {
|
||||
$describedby_extra_id = array( "ginput_product_price_{$this->formId}_{$this->id}" );
|
||||
}
|
||||
$quantity_aria_describedby = $this->get_aria_describedby( $describedby_extra_id );
|
||||
$quantity_field .= " <span class='ginput_quantity_label gform-field-label' aria-hidden='true'>" . $product_quantity_sub_label . "</span> <input type='number' name='input_{$id}.3' value='{$quantity}' id='input_{$form_id}_{$this->id}_1' class='ginput_quantity' size='10' min='0' {$tabindex} {$disabled_text} {$quantity_aria_describedby} />";
|
||||
} else {
|
||||
if ( ! is_numeric( $quantity ) ) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
if ( ! $has_quantity ) {
|
||||
$quantity_field .= "<input type='hidden' name='input_{$id}.3' value='{$quantity}' class='ginput_quantity_{$form_id}_{$this->id} gform_hidden' />";
|
||||
}
|
||||
}
|
||||
|
||||
$wrapper_open = $is_legacy_markup ? '' : "<div id='ginput_product_price_{$form_id}_{$this->id}' class='ginput_product_price_wrapper'>";
|
||||
$wrapper_close = $is_legacy_markup ? '' : '</div>';
|
||||
|
||||
return "<div class='ginput_container ginput_container_product_calculation'>
|
||||
<input type='hidden' name='input_{$id}.1' value='{$product_name}' class='gform_hidden' />
|
||||
$wrapper_open
|
||||
<span class='gform-field-label gform-field-label--type-sub-large ginput_product_price_label'>" . gf_apply_filters( array( 'gform_product_price', $form_id, $this->id ), esc_html__( 'Price', 'gravityforms' ), $form_id ) . ":</span>
|
||||
<span class='gform-field-label gform-field-label--type-sub-large ginput_product_price' id='{$field_id}'>" . esc_html( GFCommon::to_money( $price, $currency ) ) . "</span>
|
||||
$wrapper_close
|
||||
<input type='hidden' name='input_{$id}.2' id='ginput_base_price_{$form_id}_{$this->id}' class='gform_hidden' value='" . esc_attr( $price ) . "'/>
|
||||
{$quantity_field}
|
||||
</div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the field label.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param bool $force_frontend_label Should the frontend label be displayed in the admin even if an admin label is configured.
|
||||
* @param string $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_label( $force_frontend_label, $value ) {
|
||||
$field_label = parent::get_field_label( $force_frontend_label, $value );
|
||||
|
||||
// Checking the defined product name.
|
||||
if ( ! rgempty( $this->id . '.1', $value ) ) {
|
||||
$field_label = rgar( $value, $this->id . '.1' );
|
||||
}
|
||||
|
||||
if ( $this->disableQuantity || ! $this->get_context_property( 'rendering_form' ) ) {
|
||||
$label = esc_html( $field_label );
|
||||
} else {
|
||||
$product_quantity_sub_label = $this->get_product_quantity_label( $this->formId );
|
||||
$label = '<span class="gfield_label_product gform-field-label">' . esc_html( $field_label ) . '</span>' . ' <span class="screen-reader-text">' . $product_quantity_sub_label . '</span>';
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
if ( is_array( $value ) && ! empty( $value ) ) {
|
||||
$product_name = trim( $value[ $this->id . '.1' ] );
|
||||
$price = trim( $value[ $this->id . '.2' ] );
|
||||
$quantity = trim( $value[ $this->id . '.3' ] );
|
||||
|
||||
$product = $product_name . ', ' . esc_html__( 'Qty: ', 'gravityforms' ) . $quantity . ', ' . esc_html__( 'Price: ', 'gravityforms' ) . $price;
|
||||
|
||||
return $product;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
// ignore submitted value and recalculate price in backend
|
||||
list( $prefix, $field_id, $input_id ) = rgexplode( '_', $input_name, 3 );
|
||||
if ( $input_id == 2 ) {
|
||||
$currency = new RGCurrency( GFCommon::get_currency() );
|
||||
$lead = empty( $lead ) ? RGFormsModel::get_lead( $lead_id ) : $lead;
|
||||
$value = $currency->to_money( GFCommon::calculate( $this, $form, $lead ) );
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$this->enableCalculation = (bool) $this->enableCalculation;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Calculation() );
|
||||
@@ -0,0 +1,682 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_CAPTCHA extends GF_Field {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'captcha';
|
||||
|
||||
|
||||
/**
|
||||
* The reCAPTCHA API response.
|
||||
*
|
||||
* @var \stdClass
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* The reCAPTCHA site key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $site_key;
|
||||
|
||||
/**
|
||||
* The reCAPTCHA secret key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $secret_key;
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'CAPTCHA', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Adds a captcha field to your form to help protect your website from spam and bot abuse.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--recaptcha';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'captcha_type_setting',
|
||||
'captcha_badge_setting',
|
||||
'captcha_size_setting',
|
||||
'captcha_fg_setting',
|
||||
'captcha_bg_setting',
|
||||
'captcha_language_setting',
|
||||
'captcha_theme_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the warning message to be displayed in the form editor sidebar.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_sidebar_messages() {
|
||||
if ( $this->captchaType === 'math' || $this->captchaType === 'simple_captcha' || ( ! empty( $this->get_site_key() ) && ! empty( $this->get_secret_key() ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Translators: 1. Opening <a> tag with link to the Forms > Settings > reCAPTCHA page. 2. closing <a> tag.
|
||||
return sprintf( __( 'To use reCAPTCHA v2 you must configure the site and secret keys on the %1$sreCAPTCHA Settings%2$s page.', 'gravityforms' ), "<a href='?page=gf_settings&subview=recaptcha' target='_blank'>", '</a>' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the reCAPTCHA field.
|
||||
*
|
||||
* This method always gets called on the last page of a form, as well as on the page where the field is assigned.
|
||||
*
|
||||
* @since Unknown
|
||||
*
|
||||
* @param array|string $value The field value.
|
||||
* @param array $form The form data.
|
||||
*/
|
||||
public function validate( $value, $form ) {
|
||||
switch ( $this->captchaType ) {
|
||||
case 'simple_captcha' :
|
||||
if ( class_exists( 'ReallySimpleCaptcha' ) ) {
|
||||
$prefix = $_POST[ "input_captcha_prefix_{$this->id}" ];
|
||||
$captcha_obj = $this->get_simple_captcha();
|
||||
|
||||
if ( ! $captcha_obj->check( $prefix, str_replace( ' ', '', $value ) ) ) {
|
||||
$this->set_failed_validation( esc_html__( "The CAPTCHA wasn't entered correctly. Go back and try it again.", 'gravityforms' ) );
|
||||
}
|
||||
|
||||
//removes old files in captcha folder (older than 1 hour);
|
||||
$captcha_obj->cleanup();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'math' :
|
||||
$prefixes = explode( ',', $_POST[ "input_captcha_prefix_{$this->id}" ] );
|
||||
$captcha_obj = $this->get_simple_captcha();
|
||||
|
||||
//finding first number
|
||||
for ( $first = 0; $first < 10; $first ++ ) {
|
||||
if ( $captcha_obj->check( $prefixes[0], $first ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//finding second number
|
||||
for ( $second = 0; $second < 10; $second ++ ) {
|
||||
if ( $captcha_obj->check( $prefixes[2], $second ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if it is a +, perform the sum
|
||||
if ( $captcha_obj->check( $prefixes[1], '+' ) ) {
|
||||
$result = $first + $second;
|
||||
} else {
|
||||
$result = $first - $second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( intval( $result ) != intval( $value ) ) {
|
||||
$this->set_failed_validation( esc_html__( "The CAPTCHA wasn't entered correctly. Go back and try it again.", 'gravityforms' ) );
|
||||
}
|
||||
|
||||
//removes old files in captcha folder (older than 1 hour);
|
||||
$captcha_obj->cleanup();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->validate_recaptcha( $form );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the reCAPTCHA response.
|
||||
*
|
||||
* In our application flow, we create a decoded string out of the reCAPTCHA service response if the reCAPTCHA field
|
||||
* is added to the form on a page other than the last page. We therefore first attempt to validate the decoded response,
|
||||
* falling back to validating the reCAPTCHA with a request to Google.
|
||||
*
|
||||
* @see GF_Field_CAPTCHA::verify_decoded_response()
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param array $form The form data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validate_recaptcha( $form ) {
|
||||
$response = $this->get_posted_recaptcha_response();
|
||||
|
||||
if ( ! ( $this->verify_decoded_response( $form, $response ) || $this->verify_recaptcha_response( $response ) ) ) {
|
||||
$this->set_failed_validation( __( 'The reCAPTCHA was invalid. Go back and try it again.', 'gravityforms' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the decoded response meets the requirements for submitting the form.
|
||||
*
|
||||
* Returns false if the decoded response doesn't exist or the reCAPTCHA field is on the last page, as we'll want
|
||||
* regular validation at that point instead.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param string $response The encoded response to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function verify_decoded_response( $form, $response ) {
|
||||
$decoded_response = $this->get_decoded_recaptcha_response( $response );
|
||||
|
||||
// No decoded object.
|
||||
if ( ! is_object( $decoded_response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not a time that we need to verify the decoded object.
|
||||
if ( ! GFFormDisplay::is_last_page( $form ) || $this->is_on_last_page( $form ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
$decoded_response->success === true
|
||||
&& ! empty( $decoded_response->token )
|
||||
&& gmdate( time() ) <= strtotime( '+1 day', strtotime( $decoded_response->challenge_ts ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set validation failed on reCAPTCHA field.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param string $message The message to set if one does not already exist.
|
||||
*/
|
||||
private function set_failed_validation( $message ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? $message : $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the saved site key.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_site_key() {
|
||||
if ( ! $this->site_key ) {
|
||||
$this->site_key = get_option( 'rg_gforms_captcha_public_key', '' );
|
||||
}
|
||||
|
||||
return $this->site_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the saved secret key.
|
||||
*
|
||||
* @since 2.4.25
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_secret_key() {
|
||||
if ( ! $this->secret_key ) {
|
||||
$this->secret_key = get_option( 'rg_gforms_captcha_private_key', '' );
|
||||
}
|
||||
|
||||
return $this->secret_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the reCAPTCHA response input.
|
||||
*
|
||||
* When user clicks on the "I'm not a robot" box, the response token is populated into a hidden field by Google.
|
||||
* If the current form is a multi-page form and the reCAPTCHA field is on a page other than the last page, this
|
||||
* value will return an openssl encoded string with the Google reCAPTCHA validation data and some supplemental
|
||||
* validation data instead.
|
||||
*
|
||||
* @see GF_Field_CAPTCHA::get_encoded_recaptcha_response()
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_posted_recaptcha_response() {
|
||||
return sanitize_text_field( rgpost( 'g-recaptcha-response' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the reCAPTCHA token provided by Google.
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param string $response The token to verify.
|
||||
* @param null $secret_key The secret key for reCAPTCHA verification.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function verify_recaptcha_response( $response, $secret_key = null ) {
|
||||
|
||||
$verify_url = 'https://www.google.com/recaptcha/api/siteverify';
|
||||
|
||||
if ( $secret_key == null ) {
|
||||
$secret_key = $this->get_secret_key();
|
||||
}
|
||||
|
||||
// pass secret key and token for verification of whether the response was valid
|
||||
$response = wp_remote_post( $verify_url, array(
|
||||
'method' => 'POST',
|
||||
'body' => array(
|
||||
'secret' => $secret_key,
|
||||
'response' => $response
|
||||
),
|
||||
) );
|
||||
|
||||
if ( ! is_wp_error( $response ) ) {
|
||||
$this->response = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
return $this->response->success == true;
|
||||
} else {
|
||||
GFCommon::log_debug( __METHOD__ . '(): Validating the reCAPTCHA response has failed due to the following: ' . $response->get_error_message() );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
switch ( $this->captchaType ) {
|
||||
case 'simple_captcha' :
|
||||
$size = empty($this->simpleCaptchaSize) ? 'medium' : esc_attr( $this->simpleCaptchaSize );
|
||||
$captcha = $this->get_captcha();
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$dimensions = $is_entry_detail || $is_form_editor ? '' : "width='" . esc_attr( rgar( $captcha, 'width' ) ) . "' height='" . esc_attr( rgar( $captcha, 'height' ) ) . "'";
|
||||
|
||||
return "<div class='gfield_captcha_container'><img class='gfield_captcha' src='" . esc_url( rgar( $captcha, 'url' ) ) . "' alt='' {$dimensions} /><div class='gfield_captcha_input_container simple_captcha_{$size}'><input type='text' autocomplete='off' name='input_{$id}' id='{$field_id}' {$tabindex}/><input type='hidden' name='input_captcha_prefix_{$id}' value='" . esc_attr( rgar( $captcha, 'prefix' ) ) . "' /></div></div>";
|
||||
break;
|
||||
|
||||
case 'math' :
|
||||
$size = empty( $this->simpleCaptchaSize ) ? 'medium' : esc_attr( $this->simpleCaptchaSize );
|
||||
$captcha_1 = $this->get_math_captcha( 1 );
|
||||
$captcha_2 = $this->get_math_captcha( 2 );
|
||||
$captcha_3 = $this->get_math_captcha( 3 );
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$dimensions = $is_entry_detail || $is_form_editor ? '' : "width='" . esc_attr( rgar( $captcha_1, 'width' ) ) . "' height='" . esc_attr( rgar( $captcha_1, 'height' ) ) . "'";
|
||||
$prefix_value = rgar( $captcha_1, 'prefix' ) . ',' . rgar( $captcha_2, 'prefix' ) . ',' . rgar( $captcha_3, 'prefix' );
|
||||
|
||||
return "<div class='gfield_captcha_container'><img class='gfield_captcha' src='" . esc_url( rgar( $captcha_1, 'url' ) ) . "' alt='' {$dimensions} /><img class='gfield_captcha' src='" . esc_url( rgar( $captcha_2, 'url' ) ) . "' alt='' {$dimensions} /><img class='gfield_captcha' src='" . esc_url( rgar( $captcha_3, 'url' ) ) . "' alt='' {$dimensions} /><div class='gfield_captcha_input_container math_{$size}'><input type='text' autocomplete='off' name='input_{$id}' id='{$field_id}' {$tabindex}/><input type='hidden' name='input_captcha_prefix_{$id}' value='" . esc_attr( $prefix_value ) . "' /></div></div>";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
$this->site_key = $this->get_site_key();
|
||||
$this->secret_key = $this->get_secret_key();
|
||||
$theme = in_array( $this->captchaTheme, array( 'blackglass', 'dark' ) ) ? 'dark' : 'light';
|
||||
$type = get_option( 'rg_gforms_captcha_type' );
|
||||
if ( $is_entry_detail || $is_form_editor ){
|
||||
|
||||
//for admin, show a thumbnail depending on chosen theme
|
||||
if ( empty( $this->site_key ) || empty( $this->secret_key ) ) {
|
||||
|
||||
return "<div class='ginput_container'><div class='captcha_message'>" . __( 'To use the reCAPTCHA field you must do the following:', 'gravityforms' ) . "</div><div class='captcha_message'>1 - <a href='https://www.google.com/recaptcha/admin' target='_blank'>" . sprintf( __( 'Sign up%s for an API key pair for your site.', 'gravityforms' ), '</a>' ) . "</div><div class='captcha_message'>2 - " . sprintf( __( 'Enter your reCAPTCHA site and secret keys in the %sreCAPTCHA Settings%s.', 'gravityforms' ), "<a href='?page=gf_settings&subview=recaptcha' target='_blank'>", '</a>' ) . '</div></div>';
|
||||
}
|
||||
|
||||
$type_suffix = $type == 'invisible' ? 'invisible_' : '';
|
||||
$alt = esc_attr__( 'An example of reCAPTCHA', 'gravityforms' );
|
||||
|
||||
return "<div class='ginput_container'><img class='gfield_captcha' src='" . GFCommon::get_base_url() . "/images/captcha_{$type_suffix}{$theme}.jpg' alt='{$alt}' /></div>";
|
||||
}
|
||||
|
||||
if ( empty( $this->site_key ) || empty( $this->secret_key ) ) {
|
||||
GFCommon::log_error( __METHOD__ . sprintf( '(): reCAPTCHA secret keys not saved in the reCAPTCHA Settings (%s). The reCAPTCHA field will always fail validation during form submission.', admin_url( 'admin.php' ) . '?page=gf_settings&subview=recaptcha' ) );
|
||||
}
|
||||
|
||||
$stoken = '';
|
||||
|
||||
if ( ! empty( $this->secret_key ) && ! empty( $secure_token ) && $this->use_stoken() ) {
|
||||
// The secure token is a deprecated feature of the reCAPTCHA API.
|
||||
// https://developers.google.com/recaptcha/docs/secure_token
|
||||
$secure_token = self::create_recaptcha_secure_token( $this->secret_key );
|
||||
$stoken = sprintf( 'data-stoken=\'%s\'', esc_attr( $secure_token ) );
|
||||
}
|
||||
|
||||
$size = '';
|
||||
$badge = '';
|
||||
|
||||
if ( $type == 'invisible' ) {
|
||||
$size = "data-size='invisible'";
|
||||
$badge = $this->captchaBadge ? $this->captchaBadge : 'bottomright';
|
||||
$tabindex = -1;
|
||||
} else {
|
||||
$tabindex = GFCommon::$tab_index > 0 ? GFCommon::$tab_index++ : 0;
|
||||
}
|
||||
|
||||
$output = "<div id='" . esc_attr( $field_id ) ."' class='ginput_container ginput_recaptcha' data-sitekey='" . esc_attr( $this->site_key ) . "' {$stoken} data-theme='" . esc_attr( $theme ) . "' data-tabindex='{$tabindex}' {$size} data-badge='{$badge}'></div>";
|
||||
|
||||
$recaptcha_response = $this->get_posted_recaptcha_response();
|
||||
|
||||
if ( ! $this->requires_encoding( $form, $recaptcha_response ) ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<input
|
||||
type="hidden"
|
||||
name="g-recaptcha-response"
|
||||
value="<?php esc_attr_e( $this->get_encoded_recaptcha_response( $form, $recaptcha_response) ); ?>"
|
||||
/>
|
||||
<?php
|
||||
return $output .= ob_get_clean();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the reCAPTCHA response with details from Google.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param string $response The posted response data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_encoded_recaptcha_response( $form, $response ) {
|
||||
if ( ! $this->response ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->response->token = $response;
|
||||
|
||||
return GFCommon::openssl_encrypt( base64_encode( json_encode( $this->response ) ), $this->secret_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode and return the value of g-recaptcha-response field.
|
||||
*
|
||||
* The first time this method is called, the $response parameter will be the result of the reCAPTCHA callback,
|
||||
* and decryption will fail. On subsequent requests, it should contain an encoded string of the reCAPTCHA response
|
||||
* and the original token used to make the request.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param string $response An openssl encoded string, or the reCAPTCHA token on the very first call.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_decoded_recaptcha_response( $response ) {
|
||||
$decoded_response = GFCommon::openssl_decrypt( $response, $this->get_secret_key() );
|
||||
|
||||
if ( ! $decoded_response ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return json_decode( base64_decode( $decoded_response ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the reCAPTCHA response should be saved and encoded for validation on the final form page.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param string $recaptcha_response The reCAPTCHA response.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function requires_encoding( $form, $recaptcha_response ) {
|
||||
return $recaptcha_response && ! $this->failed_validation && GFFormDisplay::get_current_page( rgar( $form, 'id' ) ) != $this->pageNumber && ! $this->is_on_last_page( $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this CAPTCHA field is on the last page of the given form.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_on_last_page( $form ) {
|
||||
$pages = GFAPI::get_fields_by_type( $form, array( 'page' ) );
|
||||
|
||||
return count( $pages ) + 1 === (int) $this->pageNumber;
|
||||
}
|
||||
|
||||
public function get_captcha() {
|
||||
if ( ! class_exists( 'ReallySimpleCaptcha' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha = $this->get_simple_captcha();
|
||||
|
||||
//If captcha folder does not exist and can't be created, return an empty captcha
|
||||
if ( ! wp_mkdir_p( $captcha->tmp_dir ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha->char_length = 5;
|
||||
switch ( $this->simpleCaptchaSize ) {
|
||||
case 'small' :
|
||||
$captcha->img_size = array( 100, 28 );
|
||||
$captcha->font_size = 18;
|
||||
$captcha->base = array( 8, 20 );
|
||||
$captcha->font_char_width = 17;
|
||||
|
||||
break;
|
||||
|
||||
case 'large' :
|
||||
$captcha->img_size = array( 200, 56 );
|
||||
$captcha->font_size = 32;
|
||||
$captcha->base = array( 18, 42 );
|
||||
$captcha->font_char_width = 35;
|
||||
break;
|
||||
|
||||
default :
|
||||
$captcha->img_size = array( 150, 42 );
|
||||
$captcha->font_size = 26;
|
||||
$captcha->base = array( 15, 32 );
|
||||
$captcha->font_char_width = 25;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->simpleCaptchaFontColor ) ) {
|
||||
$captcha->fg = $this->hex2rgb( $this->simpleCaptchaFontColor );
|
||||
}
|
||||
if ( ! empty( $this->simpleCaptchaBackgroundColor ) ) {
|
||||
$captcha->bg = $this->hex2rgb( $this->simpleCaptchaBackgroundColor );
|
||||
}
|
||||
|
||||
$word = $captcha->generate_random_word();
|
||||
$prefix = mt_rand();
|
||||
$filename = $captcha->generate_image( $prefix, $word );
|
||||
$url = RGFormsModel::get_upload_url( 'captcha' ) . '/' . $filename;
|
||||
$path = $captcha->tmp_dir . $filename;
|
||||
|
||||
if ( GFCommon::is_ssl() && strpos( $url, 'http:' ) !== false ) {
|
||||
$url = str_replace( 'http:', 'https:', $url );
|
||||
}
|
||||
|
||||
return array( 'path' => $path, 'url' => $url, 'height' => $captcha->img_size[1], 'width' => $captcha->img_size[0], 'prefix' => $prefix );
|
||||
}
|
||||
|
||||
public function get_simple_captcha() {
|
||||
$captcha = new ReallySimpleCaptcha();
|
||||
$captcha->tmp_dir = RGFormsModel::get_upload_path( 'captcha' ) . '/';
|
||||
|
||||
return $captcha;
|
||||
}
|
||||
|
||||
public function get_math_captcha( $pos ) {
|
||||
if ( ! class_exists( 'ReallySimpleCaptcha' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha = $this->get_simple_captcha();
|
||||
|
||||
//If captcha folder does not exist and can't be created, return an empty captcha
|
||||
if ( ! wp_mkdir_p( $captcha->tmp_dir ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha->char_length = 1;
|
||||
if ( $pos == 1 || $pos == 3 ) {
|
||||
$captcha->chars = '0123456789';
|
||||
} else {
|
||||
$captcha->chars = '+';
|
||||
}
|
||||
|
||||
switch ( $this->simpleCaptchaSize ) {
|
||||
case 'small' :
|
||||
$captcha->img_size = array( 23, 28 );
|
||||
$captcha->font_size = 18;
|
||||
$captcha->base = array( 6, 20 );
|
||||
$captcha->font_char_width = 17;
|
||||
|
||||
break;
|
||||
|
||||
case 'large' :
|
||||
$captcha->img_size = array( 36, 56 );
|
||||
$captcha->font_size = 32;
|
||||
$captcha->base = array( 10, 42 );
|
||||
$captcha->font_char_width = 35;
|
||||
break;
|
||||
|
||||
default :
|
||||
$captcha->img_size = array( 30, 42 );
|
||||
$captcha->font_size = 26;
|
||||
$captcha->base = array( 9, 32 );
|
||||
$captcha->font_char_width = 25;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->simpleCaptchaFontColor ) ) {
|
||||
$captcha->fg = $this->hex2rgb( $this->simpleCaptchaFontColor );
|
||||
}
|
||||
if ( ! empty( $this->simpleCaptchaBackgroundColor ) ) {
|
||||
$captcha->bg = $this->hex2rgb( $this->simpleCaptchaBackgroundColor );
|
||||
}
|
||||
|
||||
$word = $captcha->generate_random_word();
|
||||
$prefix = mt_rand();
|
||||
$filename = $captcha->generate_image( $prefix, $word );
|
||||
$url = RGFormsModel::get_upload_url( 'captcha' ) . '/' . $filename;
|
||||
$path = $captcha->tmp_dir . $filename;
|
||||
|
||||
if ( GFCommon::is_ssl() && strpos( $url, 'http:' ) !== false ) {
|
||||
$url = str_replace( 'http:', 'https:', $url );
|
||||
}
|
||||
|
||||
return array( 'path' => $path, 'url' => $url, 'height' => $captcha->img_size[1], 'width' => $captcha->img_size[0], 'prefix' => $prefix );
|
||||
}
|
||||
|
||||
private function hex2rgb( $color ) {
|
||||
if ( $color[0] == '#' ) {
|
||||
$color = substr( $color, 1 );
|
||||
}
|
||||
|
||||
if ( strlen( $color ) == 6 ) {
|
||||
list( $r, $g, $b ) = array(
|
||||
$color[0] . $color[1],
|
||||
$color[2] . $color[3],
|
||||
$color[4] . $color[5],
|
||||
);
|
||||
} elseif ( strlen( $color ) == 3 ) {
|
||||
list( $r, $g, $b ) = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$r = hexdec( $r );
|
||||
$g = hexdec( $g );
|
||||
$b = hexdec( $b );
|
||||
|
||||
return array( $r, $g, $b );
|
||||
}
|
||||
|
||||
public function create_recaptcha_secure_token( $secret_key ) {
|
||||
|
||||
// If required cypher is not available, skip
|
||||
if ( ! defined( 'MCRYPT_RIJNDAEL_128' ) ) {
|
||||
GFCommon::log_error( __METHOD__ . sprintf( '(): Legacy MCRYPT_RIJNDAEL_128 cypher not available on system. Generate new reCAPTCHA v2 keys (https://www.google.com/recaptcha/admin/create) and update your Gravity Forms reCAPTCHA Settings (%s) to resolve.', admin_url( 'admin.php' ) . '?page=gf_settings&subview=recaptcha' ) );
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$secret_key = substr( hash( 'sha1', $secret_key, true ), 0, 16 );
|
||||
$session_id = uniqid( 'recaptcha' );
|
||||
$ts_ms = round( ( microtime( true ) - 1 ) * 1000 );
|
||||
|
||||
//create json string
|
||||
$params = array( 'session_id' => $session_id, 'ts_ms' => $ts_ms );
|
||||
$plaintext = json_encode( $params );
|
||||
GFCommon::log_debug( 'recaptcha token parameters: ' . $plaintext );
|
||||
|
||||
//pad json string
|
||||
$pad = 16 - ( strlen( $plaintext ) % 16 );
|
||||
$padded = $plaintext . str_repeat( chr( $pad ), $pad );
|
||||
|
||||
//encrypt as 128
|
||||
$encrypted = GFCommon::openssl_encrypt( $padded, $secret_key, MCRYPT_RIJNDAEL_128 );
|
||||
|
||||
$token = str_replace( array( '+', '/', '=' ), array( '-', '_', '' ), $encrypted );
|
||||
GFCommon::log_debug( ' token being used is: ' . $token );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function use_stoken() {
|
||||
// 'gform_recaptcha_keys_status' will be set to true if new keys have been entered
|
||||
return ! get_option( 'gform_recaptcha_keys_status', false );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_CAPTCHA() );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,596 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* The Consent Field keeps track of exactly what the user consented to. The consent value ("1"), checkbox label and the Form revision ID
|
||||
* are all stored in the entry meta table in separate input values when consent is given.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* Class GF_Field_Consent
|
||||
*/
|
||||
class GF_Field_Consent extends GF_Field {
|
||||
|
||||
/**
|
||||
* Declare the field type.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'consent';
|
||||
|
||||
/**
|
||||
* Checked indicator URL.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $checked_indicator_url = '';
|
||||
|
||||
/**
|
||||
* Checked indicator image markup.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $checked_indicator_markup = '';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
/**
|
||||
* GF_Field_Consent constructor.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $data Data needed when initiate the class.
|
||||
*/
|
||||
public function __construct( $data = array() ) {
|
||||
parent::__construct( $data );
|
||||
|
||||
/**
|
||||
* Filters the consent checked indicator (image) URL.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $url Image URL.
|
||||
*/
|
||||
$this->checked_indicator_url = apply_filters( 'gform_consent_checked_indicator', GFCommon::get_base_url() . '/images/tick.png' );
|
||||
|
||||
/**
|
||||
* Filters the consent checked indicator (image) element.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $tag Image tag.
|
||||
*/
|
||||
$this->checked_indicator_markup = apply_filters( 'gform_consent_checked_indicator_markup', '<img src="' . esc_url( $this->checked_indicator_url ) . '" />' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field title.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Consent', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Offers a “yes/no” consent checkbox and a detailed description of what is being consented to.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--consent';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field button properties for the form editor. The array contains two elements:
|
||||
* 'group' => 'standard_fields' // or 'advanced_fields', 'post_fields', 'pricing_fields'
|
||||
* 'text' => 'Button text'
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_form_editor_button() {
|
||||
return array(
|
||||
'group' => 'advanced_fields',
|
||||
'text' => $this->get_form_editor_field_title(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class names of the settings which should be available on the field in the form editor.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'checkbox_label_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if this field type can be used when configuring conditional logic rules.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field inner markup.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
* @param null|array $entry Null or the Entry Object currently being edited.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_input( $form, $value = array(), $entry = null ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_form_editor || $is_entry_detail;
|
||||
|
||||
$html_input_type = 'checkbox';
|
||||
|
||||
$id = (int) $this->id;
|
||||
$tabindex = $this->get_tabindex();
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
|
||||
$target_input_id = parent::get_first_input_id( $form );
|
||||
$for_attribute = empty( $target_input_id ) ? '' : "for='{$target_input_id}'";
|
||||
$label_class_attribute = 'class="gform-field-label gform-field-label--type-inline gfield_consent_label"';
|
||||
$required_div = ( $this->labelPlacement === 'hidden_label' && $this->isRequired ) ? $this->get_required_indicator() : '';
|
||||
|
||||
if ( $is_admin && ! GFCommon::is_entry_detail_edit() ) {
|
||||
$checkbox_label = ! is_array( $value ) || empty( $value[ $id . '.2' ] ) ? $this->checkboxLabel : $value[ $id . '.2' ];
|
||||
$revision_id = ! is_array( $value ) || empty( $value[ $id . '.3' ] ) ? GFFormsModel::get_latest_form_revisions_id( $form['id'] ) : $value[ $id . '.3' ];
|
||||
$value = ! is_array( $value ) || empty( $value[ $id . '.1' ] ) ? '0' : esc_attr( $value[ $id . '.1' ] );
|
||||
} else {
|
||||
$checkbox_label = trim( $this->checkboxLabel );
|
||||
$revision_id = GFFormsModel::get_latest_form_revisions_id( $form['id'] );
|
||||
// We compare if the description text from different revisions has been changed.
|
||||
$current_description = $this->get_field_description_from_revision( $revision_id );
|
||||
$submitted_description = $this->get_field_description_from_revision( $value[ $id . '.3' ] );
|
||||
|
||||
$value = ! is_array( $value ) || empty( $value[ $id . '.1' ] ) || ( $checkbox_label !== $value[ $id . '.2' ] ) || ( $current_description !== $submitted_description ) ? '0' : esc_attr( $value[ $id . '.1' ] );
|
||||
}
|
||||
$checked = $is_form_editor ? '' : checked( '1', $value, false );
|
||||
|
||||
$description = $is_entry_detail ? $this->get_field_description_from_revision( $revision_id ) : $this->description;
|
||||
$extra_describedby_ids = empty( $description ) ? array() : array( "gfield_consent_description_{$form['id']}_{$this->id}" );
|
||||
$aria_describedby = $this->get_aria_describedby( $extra_describedby_ids );
|
||||
|
||||
$input = "<input name='input_{$id}.1' id='{$target_input_id}' type='{$html_input_type}' value='1' {$tabindex} {$aria_describedby} {$required_attribute} {$invalid_attribute} {$disabled_text} {$checked} /> <label {$label_class_attribute} {$for_attribute} >{$checkbox_label}{$required_div}</label>";
|
||||
$input .= "<input type='hidden' name='input_{$id}.2' value='" . esc_attr( $checkbox_label ) . "' class='gform_hidden' />";
|
||||
$input .= "<input type='hidden' name='input_{$id}.3' value='" . esc_attr( $revision_id ) . "' class='gform_hidden' />";
|
||||
|
||||
if ( $is_entry_detail ) {
|
||||
$input .= $this->get_description( $this->get_field_description_from_revision( $revision_id ), '' );
|
||||
}
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_consent'>%s</div>", $input );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input ID to be assigned to the field label for attribute.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_first_input_id( $form ) {
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the markup for the field description.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $description The field description.
|
||||
* @param string $css_class The css class to be assigned to the description container.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description( $description, $css_class ) {
|
||||
if ( ! empty( $description ) ) {
|
||||
$id = "gfield_consent_description_{$this->formId}_{$this->id}";
|
||||
|
||||
$css_class .= ' gfield_consent_description';
|
||||
|
||||
return "<div class='$css_class' id='$id'>" . nl2br( $description ) . '</div>';
|
||||
}
|
||||
|
||||
return parent::get_description( $description, $css_class );
|
||||
}
|
||||
|
||||
/**
|
||||
* If a field has a description, the aria-describedby attribute for the input field is returned.
|
||||
* This method is specific to the consent field since the consent description has a different ID pattern.
|
||||
*
|
||||
* @since 2.6.8
|
||||
*
|
||||
* @param array|string $extra_ids Any extra ids that should be added to the describedby attribute.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_aria_describedby( $extra_ids = array() ) {
|
||||
|
||||
$describedby_ids = is_array( $extra_ids ) ? $extra_ids : explode( ' ', $extra_ids );
|
||||
|
||||
if ( $this->failed_validation ) {
|
||||
$describedby_ids[] = "validation_message_{$this->formId}_{$this->id}";
|
||||
}
|
||||
|
||||
if ( empty( $describedby_ids ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return 'aria-describedby="' . implode( ' ', $describedby_ids ) . '"';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when determining if the field has failed required validation.
|
||||
*
|
||||
* The consent field has three inputs; only the checkbox is required.
|
||||
*
|
||||
* @since 2.7.5
|
||||
*
|
||||
* @param int $form_id The ID of the form currently being processed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_value_submission_empty( $form_id ) {
|
||||
return rgblank( rgpost( 'input_' . $this->id . '_1' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize and format the value before it is saved to the Entry Object.
|
||||
* We also add the value of inputs .2 and .3 here since they are not displayed in the form.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $value The value to be saved.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $input_name The input name used when accessing the $_POST.
|
||||
* @param int $lead_id The ID of the Entry currently being processed.
|
||||
* @param array $lead The Entry Object currently being processed.
|
||||
*
|
||||
* @return array|string The safe value.
|
||||
*/
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
list( $input, $field_id, $input_id ) = rgexplode( '_', $input_name, 3 );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ( ! empty( $value ) ) ? '1' : '';
|
||||
break;
|
||||
case '2':
|
||||
$value = ( $lead[ $field_id . '.1' ] === '1' ) ? $value : '';
|
||||
break;
|
||||
case '3':
|
||||
$value = ( $lead[ $field_id . '.1' ] === '1' ) ? $value : '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the values of consent field inputs in merge tags.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string|array $value The field value. Depending on the location the merge tag is being used the following functions may have already been applied to the value: esc_html, nl2br, and urlencode.
|
||||
* @param string $input_id The field or input ID from the merge tag currently being processed.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $modifier The merge tag modifier. e.g. value.
|
||||
* @param string|array $raw_value The raw field value from before any formatting was applied to $value.
|
||||
* @param bool $url_encode Indicates if the urlencode function may have been applied to the $value.
|
||||
* @param bool $esc_html Indicates if the esc_html function may have been applied to the $value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param bool $nl2br Indicates if the nl2br function may have been applied to the $value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
list( $field_id, $input_id ) = explode( '.', $input_id );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ! rgblank( $value ) ? $this->checked_indicator_markup : '';
|
||||
break;
|
||||
case '3':
|
||||
$value = ! rgblank( $value ) ? $this->get_field_description_from_revision( $value ) : '';
|
||||
if ( $value !== '' && $nl2br ) {
|
||||
$value = nl2br( $value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for display on the entries list page.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param string $field_id The field or input ID currently being processed.
|
||||
* @param array $columns The properties for the columns being displayed on the entry list page.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
list( $field_id, $input_id ) = explode( '.', $field_id );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ! rgblank( $value ) ? $this->checked_indicator_markup : '';
|
||||
$value .= ! rgblank( $value ) ? ' ' . trim( $entry[ $this->id . '.2' ] ) : '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for display on the entry detail page and for the {all_fields} merge tag.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param string $currency The entry currency code.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param string $media The location where the value will be displayed. Possible values: screen or email.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
$return = '';
|
||||
|
||||
if ( is_array( $value ) && ! empty( $value ) ) {
|
||||
$consent = trim( $value[ $this->id . '.1' ] );
|
||||
$text = trim( $value[ $this->id . '.2' ] );
|
||||
$revision_id = absint( trim( $value[ $this->id . '.3' ] ) );
|
||||
|
||||
if ( ! rgblank( $consent ) ) {
|
||||
$return = $this->checked_indicator_markup;
|
||||
$return .= ' ' . wp_kses_post( $text );
|
||||
|
||||
if ( $media === 'screen' ) {
|
||||
// checking revisions.
|
||||
$description = $this->get_field_description_from_revision( $revision_id );
|
||||
|
||||
if ( ! empty( $description ) ) {
|
||||
$return .= '<br /><div class="gfield_consent_description">' . nl2br( $description ) . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value before it is used in entry exports and by framework add-ons using GFAddOn::get_field_value().
|
||||
*
|
||||
* For CSV export return a string or array.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $entry The entry currently being processed.
|
||||
* @param string $input_id The field or input ID.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param bool|false $is_csv Is the value going to be used in the .csv entries export.
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
|
||||
if ( empty( $input_id ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$value = parent::get_value_export( $entry, $input_id, $use_text, $is_csv );
|
||||
|
||||
list( $field_id, $input_id ) = rgexplode( '.', $input_id, 2 );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ! rgblank( $value ) ? esc_html__( 'Checked', 'gravityforms' ) : esc_html__( 'Not Checked', 'gravityforms' );
|
||||
break;
|
||||
case '3':
|
||||
$value = ! rgblank( $value ) ? $this->get_field_description_from_revision( $value ) : '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces settings into expected values while saving the form object.
|
||||
*
|
||||
* No escaping should be done at this stage to prevent double escaping on output.
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$this->checkboxLabel = $this->maybe_wp_kses( $this->checkboxLabel );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter settings for the current field.
|
||||
*
|
||||
* If overriding to add custom settings call the parent method first to get the default settings.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_settings() {
|
||||
$filter_settings = array(
|
||||
'key' => $this->id . '.1',
|
||||
'text' => GFFormsModel::get_label( $this ),
|
||||
'preventMultiple' => false,
|
||||
'operators' => $this->get_filter_operators(),
|
||||
);
|
||||
|
||||
$values = $this->get_filter_values();
|
||||
if ( ! empty( $values ) ) {
|
||||
$filter_settings['values'] = $values;
|
||||
}
|
||||
|
||||
return $filter_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = array( 'is', 'isnot' );
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filters values setting for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_values() {
|
||||
$choices = array(
|
||||
array(
|
||||
'value' => '1',
|
||||
'text' => esc_html__( 'Checked', 'gravityforms' ),
|
||||
),
|
||||
);
|
||||
|
||||
return $choices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get consent description from the form revision.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param int $revision_id Revision ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_description_from_revision( $revision_id ) {
|
||||
global $wpdb;
|
||||
$revisions_table_name = GFFormsModel::get_form_revisions_table_name();
|
||||
$display_meta = $wpdb->get_var( $wpdb->prepare( "SELECT display_meta FROM $revisions_table_name WHERE form_id=%d AND id=%d", $this->formId, $revision_id ) );
|
||||
$value = '';
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
|
||||
if ( ! empty( $display_meta ) ) {
|
||||
$display_meta_array = json_decode( $display_meta, true );
|
||||
foreach ( $display_meta_array['fields'] as $field ) {
|
||||
if ( $field['id'] === $this->id ) {
|
||||
$value = $field['description'];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$value = ( ! empty( $this->description ) ) ? $this->description : '';
|
||||
}
|
||||
|
||||
if ( $is_entry_detail ) {
|
||||
$value = $this->maybe_wp_kses( $value );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Consent() );
|
||||
@@ -0,0 +1,626 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_CreditCard extends GF_Field {
|
||||
|
||||
public $type = 'creditcard';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Credit Card', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to enter credit card information.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--credit-card';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'force_ssl_field_setting',
|
||||
'credit_card_style_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'sub_labels_setting',
|
||||
'sub_label_placement_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'rules_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'credit_card_setting',
|
||||
'input_placeholders_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array(); // this button is conditionally added in the form detail page
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the IDs of required inputs.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_required_inputs_ids() {
|
||||
return array( '1', '2_month', '2_year', '3' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array that contains aria-describedby attribute for each input.
|
||||
*
|
||||
* Depending on each input's validation state, aria-describedby takes the value of the validation message container ID, the description only or nothing.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $required_inputs_ids IDs of required field inputs.
|
||||
* @param array|string $values Inputs values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_inputs_describedby_attributes( $required_inputs_ids, $values ) {
|
||||
|
||||
$describedby_attributes = array();
|
||||
$warning_container_id = ! GFCommon::is_ssl() && ! ( $this->is_form_editor() || $this->is_entry_detail() ) ? "field_{$this->formId}_{$this->id}_creditcard_warning_message" : '';
|
||||
|
||||
foreach ( $this->inputs as $input ) {
|
||||
$input_id = str_replace( $this->id . '.', '', $input['id'] );
|
||||
$input_value = GFForms::get( $input['id'], $values );
|
||||
if ( ! empty( $_POST[ 'is_submit_' . $this->formId ] ) && $this->isRequired && in_array( $input_id, $required_inputs_ids ) && empty( $input_value ) ) {
|
||||
$describedby_attributes[ $input_id ] = "aria-describedby='validation_message_{$this->formId}_{$this->id} {$warning_container_id}'";
|
||||
} else {
|
||||
$describedby_attributes[ $input_id ] = empty( $warning_container_id ) ? '' : "aria-describedby='{$warning_container_id}'";
|
||||
}
|
||||
}
|
||||
|
||||
return $describedby_attributes;
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$card_number = rgpost( 'input_' . $this->id . '_1' );
|
||||
$expiration_date = rgpost( 'input_' . $this->id . '_2' );
|
||||
$security_code = rgpost( 'input_' . $this->id . '_3' );
|
||||
|
||||
if ( $this->isRequired && ( empty( $card_number ) || empty( $security_code ) || empty( $expiration_date[0] ) || empty( $expiration_date[1] ) ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'Please enter your credit card information.', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( ! empty( $card_number ) ) {
|
||||
$card_type = GFCommon::get_card_type( $card_number );
|
||||
|
||||
if ( empty( $security_code ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( "Please enter your card's security code.", 'gravityforms' );
|
||||
} elseif ( ! $card_type ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Invalid credit card number.', 'gravityforms' );
|
||||
} elseif ( ! $this->is_card_supported( $card_type['slug'] ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = $card_type['name'] . ' ' . esc_html__( 'is not supported. Please enter one of the supported credit cards.', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function is_card_supported( $card_slug ) {
|
||||
$supported_cards = $this->creditCards;
|
||||
$default_cards = array( 'amex', 'discover', 'mastercard', 'visa' );
|
||||
|
||||
if ( ! empty( $supported_cards ) && in_array( $card_slug, $supported_cards ) ) {
|
||||
return true;
|
||||
} elseif ( empty( $supported_cards ) && in_array( $card_slug, $default_cards ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
|
||||
|
||||
if ( $get_from_post_global_var ) {
|
||||
$value[ $this->id . '.1' ] = $this->get_input_value_submission( 'input_' . $this->id . '_1', rgar( $this->inputs[0], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.2' ] = $this->get_input_value_submission( 'input_' . $this->id . '_2', rgar( $this->inputs[1], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.3' ] = $this->get_input_value_submission( 'input_' . $this->id . '_3', rgar( $this->inputs[3], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.4' ] = $this->get_input_value_submission( 'input_' . $this->id . '_4', rgar( $this->inputs[4], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.5' ] = $this->get_input_value_submission( 'input_' . $this->id . '_5', rgar( $this->inputs[5], 'name' ), $field_values, true );
|
||||
} else {
|
||||
$value = $this->get_input_value_submission( 'input_' . $this->id, $this->inputName, $field_values, $get_from_post_global_var );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an insecure page warning below the field content.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string|array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
* @param bool $force_frontend_label Should the frontend label be displayed in the admin even if an admin label is configured.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_content( $value, $force_frontend_label, $form ) {
|
||||
|
||||
$is_form_editor = GFCommon::is_form_editor();
|
||||
$is_entry_detail = GFCommon::is_entry_detail();
|
||||
$is_admin = $is_form_editor || $is_entry_detail;
|
||||
|
||||
// Get existing field content.
|
||||
$field_content = parent::get_field_content( $value, $force_frontend_label, $form );
|
||||
|
||||
// If SSL is not used, display warning message.
|
||||
if ( ! GFCommon::is_ssl() && ! $is_admin ) {
|
||||
$field_content = "<div class='gfield_description gfield_validation_message gfield_creditcard_warning_message' id='field_{$form['id']}_{$this->id}_creditcard_warning_message'><span>" . esc_html__( 'This page is unsecured. Do not enter a real credit card number! Use this field only for testing purposes. ', 'gravityforms' ) . '</span></div>' . $field_content;
|
||||
}
|
||||
|
||||
return $field_content;
|
||||
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$form_id = $form['id'];
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
$form_id = ( $is_entry_detail || $is_form_editor ) && empty( $form_id ) ? rgget( 'id' ) : $form_id;
|
||||
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
|
||||
|
||||
$form_sub_label_placement = rgar( $form, 'subLabelPlacement' );
|
||||
$field_sub_label_placement = $this->subLabelPlacement;
|
||||
$is_sub_label_above = $field_sub_label_placement == 'above' || ( empty( $field_sub_label_placement ) && $form_sub_label_placement == 'above' );
|
||||
$sub_label_class = $field_sub_label_placement == 'hidden_label' ? "hidden_sub_label screen-reader-text" : '';
|
||||
|
||||
$card_number = '';
|
||||
$card_name = '';
|
||||
$expiration_month = '';
|
||||
$expiration_year = '';
|
||||
$security_code = '';
|
||||
$autocomplete = "autocomplete='off'";
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$card_number = esc_attr( rgget( $this->id . '.1', $value ) );
|
||||
$card_name = esc_attr( rgget( $this->id . '.5', $value ) );
|
||||
$expiration_date = rgget( $this->id . '.2', $value );
|
||||
if ( ! is_array( $expiration_date ) && ! empty( $expiration_date ) ) {
|
||||
$expiration_date = explode( '/', $expiration_date );
|
||||
}
|
||||
|
||||
if ( is_array( $expiration_date ) && count( $expiration_date ) == 2 ) {
|
||||
$expiration_month = $expiration_date[0];
|
||||
$expiration_year = $expiration_date[1];
|
||||
}
|
||||
|
||||
$security_code = esc_attr( rgget( $this->id . '.3', $value ) );
|
||||
}
|
||||
|
||||
$action = ! ( $is_entry_detail || $is_form_editor ) ? "gformMatchCard(\"{$field_id}_1\");" : '';
|
||||
|
||||
$onchange = "onchange='{$action}'";
|
||||
$onkeyup = "onkeyup='{$action}'";
|
||||
|
||||
$card_icons = '';
|
||||
$cards = GFCommon::get_card_types();
|
||||
$enabled_card_names = array();
|
||||
|
||||
foreach ( $cards as $card ) {
|
||||
|
||||
$style = '';
|
||||
if ( $this->is_card_supported( $card['slug'] ) ) {
|
||||
$print_card = true;
|
||||
$enabled_card_names[] = rgar( $card, 'name' );
|
||||
} elseif ( $is_form_editor || $is_entry_detail ) {
|
||||
$print_card = true;
|
||||
$style = "style='display:none;'";
|
||||
} else {
|
||||
$print_card = false;
|
||||
}
|
||||
|
||||
if ( $print_card ) {
|
||||
$card_icons .= "<div class='gform_card_icon gform_card_icon_{$card['slug']}' {$style}>{$card['name']}</div>";
|
||||
}
|
||||
}
|
||||
|
||||
$payment_methods = apply_filters( 'gform_payment_methods', array(), $this, $form_id );
|
||||
$payment_options = '';
|
||||
if ( is_array( $payment_methods ) ) {
|
||||
foreach ( $payment_methods as $payment_method ) {
|
||||
$checked = rgpost( 'gform_payment_method' ) == $payment_method['key'] ? "checked='checked'" : '';
|
||||
$payment_options .= "<div class='gform_payment_option gform_payment_{$payment_method['key']}'><input type='radio' name='gform_payment_method' value='{$payment_method['key']}' id='gform_payment_method_{$payment_method['key']}' onclick='gformToggleCreditCard();' onkeypress='gformToggleCreditCard();' {$checked}/> {$payment_method['label']}</div>";
|
||||
}
|
||||
}
|
||||
$checked = rgpost( 'gform_payment_method' ) == 'creditcard' || rgempty( 'gform_payment_method' ) ? "checked='checked'" : '';
|
||||
$card_radio_button = empty( $payment_options ) ? '' : "<input type='radio' name='gform_payment_method' id='gform_payment_method_creditcard' value='creditcard' onclick='gformToggleCreditCard();' onkeypress='gformToggleCreditCard();' {$checked}/>";
|
||||
$card_describer = sprintf(
|
||||
"<span class='screen-reader-text' id='field_%d_%d_supported_creditcards'>%s %s</span>",
|
||||
$form_id,
|
||||
$this->id,
|
||||
esc_html__( 'Supported Credit Cards:', 'gravityforms' ),
|
||||
implode( ', ', $enabled_card_names )
|
||||
);
|
||||
$card_icons = "{$payment_options}<div class='gform_card_icon_container'>{$card_radio_button}{$card_icons}{$card_describer}</div>";
|
||||
|
||||
// Aria attributes.
|
||||
$number_aria_attributes = $this->get_aria_attributes( $value, '1' );
|
||||
$expiration_month_aria_attributes = $this->get_aria_attributes( $value, '2_month' );
|
||||
$expiration_year_aria_attributes = $this->get_aria_attributes( $value, '2_year' );
|
||||
$security_aria_attributes = $this->get_aria_attributes( $value, '3' );
|
||||
$name_aria_attributes = $this->get_aria_attributes( $value, '5' );
|
||||
|
||||
//card number fields
|
||||
$tabindex = $this->get_tabindex();
|
||||
$card_number_field_input = GFFormsModel::get_input( $this, $this->id . '.1' );
|
||||
$validation_helper = ! is_admin() ? "pattern='[0-9]*' title='" . esc_attr__( 'Only digits are allowed', 'gravityforms' ) . "'" : '';
|
||||
$card_number_label = rgar( $card_number_field_input, 'customLabel' ) != '' ? $card_number_field_input['customLabel'] : esc_html__( 'Card Number', 'gravityforms' );
|
||||
$card_number_label = gf_apply_filters( array( 'gform_card_number', $form_id ), $card_number_label, $form_id );
|
||||
|
||||
$card_number_placeholder = $this->get_input_placeholder_attribute( $card_number_field_input );
|
||||
if ( $is_sub_label_above ) {
|
||||
$card_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_1_container' >
|
||||
{$card_icons}
|
||||
<label for='{$field_id}_1' id='{$field_id}_1_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_number_label}</label>
|
||||
<input type='text' name='input_{$id}.1' id='{$field_id}_1' value='{$card_number}' {$tabindex} {$disabled_text} {$onchange} {$onkeyup} {$autocomplete} {$validation_helper} {$card_number_placeholder} {$number_aria_attributes}/>
|
||||
</span>";
|
||||
} else {
|
||||
$card_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_1_container' >
|
||||
{$card_icons}
|
||||
<input type='text' name='input_{$id}.1' id='{$field_id}_1' value='{$card_number}' {$tabindex} {$disabled_text} {$onchange} {$onkeyup} {$autocomplete} {$validation_helper} {$card_number_placeholder} {$number_aria_attributes}/>
|
||||
<label for='{$field_id}_1' id='{$field_id}_1_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_number_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
// Expiration Date Inputs
|
||||
$expiration_wrapper_tag = $this->get_field_container_tag( $form ) === 'fieldset' ? 'fieldset' : 'span';
|
||||
$expiration_label_tag = $expiration_wrapper_tag === 'fieldset' ? 'legend' : 'label';
|
||||
$expiration_label_for = $expiration_label_tag === 'label' ? " for='{$field_id}_2_month'" : '';
|
||||
$expiration_month_input = GFFormsModel::get_input( $this, $this->id . '.2_month' );
|
||||
|
||||
$expiration_label = rgar( $expiration_month_input, 'customLabel' ) != '' ? esc_html( $expiration_month_input['customLabel'] ) : esc_html__( 'Expiration Date', 'gravityforms' );
|
||||
$expiration_label = gf_apply_filters( array( 'gform_card_expiration', $form_id ), $expiration_label, $form_id );
|
||||
|
||||
// Expiration Date: Month
|
||||
$expiration_month_label = $expiration_wrapper_tag === 'fieldset' ? "<label for='{$field_id}_2_month' class='gform-field-label gform-field-label--type-sub screen-reader-text'>" . esc_html__( 'Month', 'gravityforms' ) . "</label>" : '';
|
||||
$expiration_month_tab_index = $this->get_tabindex();
|
||||
$expiration_month_placeholder = $this->get_input_placeholder_value( $expiration_month_input );
|
||||
$expiration_months = $this->get_expiration_months( $expiration_month, $expiration_month_placeholder );
|
||||
|
||||
// Expiration Date: Year
|
||||
$expiration_year_input = GFFormsModel::get_input( $this, $this->id . '.2_year' );
|
||||
$expiration_year_tab_index = $this->get_tabindex();
|
||||
$expiration_year_placeholder = $this->get_input_placeholder_value( $expiration_year_input );
|
||||
$expiration_years = $this->get_expiration_years( $expiration_year, $expiration_year_placeholder );
|
||||
|
||||
if ( $expiration_wrapper_tag === 'fieldset' ) {
|
||||
$expiration_year_label_for = $is_form_editor ? '' : $field_id . '_2_year';
|
||||
$expiration_year_label = "<label for='{$expiration_year_label_for}' class='gform-field-label gform-field-label--type-sub screen-reader-text'>" . esc_html__( 'Year', 'gravityforms' ) . "</label>";
|
||||
} else {
|
||||
$expiration_year_label = '';
|
||||
}
|
||||
|
||||
// legend tag should be the first child of fieldset, so we are putting out this markup for fieldset
|
||||
// even if the sub-label is below or hidden.
|
||||
if ( $expiration_wrapper_tag === 'fieldset' || $is_sub_label_above ) {
|
||||
$expiration_field = "<span class='ginput_full{$class_suffix} ginput_cardextras gform-grid-col gform-grid-row' id='{$field_id}_2_container'>
|
||||
<{$expiration_wrapper_tag} class='ginput_cardinfo_left{$class_suffix} gform-grid-col' id='{$field_id}_2_cardinfo_left'>
|
||||
<{$expiration_label_tag}{$expiration_label_for} class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$expiration_label}</{$expiration_label_tag}>
|
||||
<span class='ginput_card_expiration_container ginput_card_field gform-grid-row'>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_month_container gform-grid-col'>" : "" ) . "
|
||||
{$expiration_month_label}
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_month' {$expiration_month_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_month' {$expiration_month_aria_attributes}>
|
||||
{$expiration_months}
|
||||
</select>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_year_container gform-grid-col'>" : "" ) . "
|
||||
{$expiration_year_label}
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_year' {$expiration_year_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_year' {$expiration_year_aria_attributes}>
|
||||
{$expiration_years}
|
||||
</select>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
</span>
|
||||
</{$expiration_wrapper_tag}>";
|
||||
|
||||
} else {
|
||||
$expiration_field = "<span class='ginput_full{$class_suffix} ginput_cardextras gform-grid-col gform-grid-row' id='{$field_id}_2_container'>
|
||||
<{$expiration_wrapper_tag} class='ginput_cardinfo_left{$class_suffix}' id='{$field_id}_2_cardinfo_left'>
|
||||
<span class='ginput_card_expiration_container ginput_card_field'>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_month_container'>" : "" ) . "
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_month' {$expiration_month_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_month' {$expiration_month_aria_attributes}>
|
||||
{$expiration_months}
|
||||
</select>
|
||||
{$expiration_month_label}
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_year_container'>" : "" ) . "
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_year' {$expiration_year_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_year' {$expiration_year_aria_attributes}>
|
||||
{$expiration_years}
|
||||
</select>
|
||||
{$expiration_year_label}
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
</span>
|
||||
<{$expiration_label_tag}{$expiration_label_for} class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$expiration_label}</{$expiration_label_tag}>
|
||||
</{$expiration_wrapper_tag}>";
|
||||
}
|
||||
//security code field
|
||||
$tabindex = $this->get_tabindex();
|
||||
$security_code_field_input = GFFormsModel::get_input( $this, $this->id . '.3' );
|
||||
$security_code_label = rgar( $security_code_field_input, 'customLabel' ) != '' ? $security_code_field_input['customLabel'] : esc_html__( 'Security Code', 'gravityforms' );
|
||||
$security_code_label = gf_apply_filters( array( 'gform_card_security_code', $form_id ), $security_code_label, $form_id );
|
||||
$validation_helper = "pattern='[0-9]*' title='" . esc_attr__( 'Only digits are allowed', 'gravityforms' ) . "'";
|
||||
$security_code_placeholder = $this->get_input_placeholder_attribute( $security_code_field_input );
|
||||
if ( $is_sub_label_above ) {
|
||||
$security_field = "<span class='ginput_cardinfo_right{$class_suffix} gform-grid-col' id='{$field_id}_2_cardinfo_right'>
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>$security_code_label</label>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' {$tabindex} {$disabled_text} class='ginput_card_security_code' value='{$security_code}' {$autocomplete} {$validation_helper} {$security_code_placeholder} {$security_aria_attributes}/>
|
||||
<span class='ginput_card_security_code_icon'> </span>
|
||||
</span>
|
||||
</span>";
|
||||
} else {
|
||||
$security_field = "<span class='ginput_cardinfo_right{$class_suffix} gform-grid-col' id='{$field_id}_2_cardinfo_right'>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' {$tabindex} {$disabled_text} class='ginput_card_security_code' value='{$security_code}' {$autocomplete} {$validation_helper} {$security_code_placeholder} {$security_aria_attributes}/>
|
||||
<span class='ginput_card_security_code_icon'> </span>
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>$security_code_label</label>
|
||||
</span>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$card_name_field_input = GFFormsModel::get_input( $this, $this->id . '.5' );
|
||||
$card_name_label = rgar( $card_name_field_input, 'customLabel' ) != '' ? $card_name_field_input['customLabel'] : esc_html__( 'Cardholder Name', 'gravityforms' );
|
||||
$card_name_label = gf_apply_filters( array( 'gform_card_name', $form_id ), $card_name_label, $form_id );
|
||||
|
||||
$card_name_placeholder = $this->get_input_placeholder_attribute( $card_name_field_input );
|
||||
if ( $is_sub_label_above ) {
|
||||
$card_name_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_5_container'>
|
||||
<label for='{$field_id}_5' id='{$field_id}_5_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_name_label}</label>
|
||||
<input type='text' name='input_{$id}.5' id='{$field_id}_5' value='{$card_name}' {$tabindex} {$disabled_text} {$card_name_placeholder} {$name_aria_attributes}/>
|
||||
</span>";
|
||||
} else {
|
||||
$card_name_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_5_container'>
|
||||
<input type='text' name='input_{$id}.5' id='{$field_id}_5' value='{$card_name}' {$tabindex} {$disabled_text} {$card_name_placeholder} {$name_aria_attributes}/>
|
||||
<label for='{$field_id}_5' id='{$field_id}_5_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_name_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
return "<div class='ginput_complex{$class_suffix} ginput_container ginput_container_creditcard gform-grid-row' id='{$field_id}'>" . $card_field . $expiration_field . $security_field . $card_name_field . ' </div>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options for the Expiration Date Month drop down.
|
||||
*
|
||||
* @since Unknown
|
||||
* @since 2.5 Added $included_placeholder parameter.
|
||||
*
|
||||
* @param string $selected_month The currently selected month.
|
||||
* @param string $placeholder Placeholder text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_expiration_months( $selected_month, $placeholder ) {
|
||||
|
||||
$str = '';
|
||||
|
||||
if ( empty( $placeholder ) ) {
|
||||
$placeholder = esc_html__( 'Month', 'gravityforms' );
|
||||
}
|
||||
|
||||
$str .= "<option value=''>{$placeholder}</option>";
|
||||
|
||||
for ( $i = 1; $i < 13; $i ++ ) {
|
||||
$selected = intval( $selected_month ) == $i ? "selected='selected'" : '';
|
||||
$month = str_pad( $i, 2, '0', STR_PAD_LEFT );
|
||||
$str .= "<option value='{$i}' {$selected}>{$month}</option>";
|
||||
}
|
||||
|
||||
return $str;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options for the Expiration Date Year drop down.
|
||||
*
|
||||
* @since Unknown
|
||||
* @since 2.5 Added $included_placeholder parameter.
|
||||
*
|
||||
* @param string $selected_year The currently selected year.
|
||||
* @param string $placeholder Placeholder text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_expiration_years( $selected_year, $placeholder ) {
|
||||
|
||||
$str = '';
|
||||
|
||||
if ( empty( $placeholder ) ) {
|
||||
$placeholder = esc_html__( 'Year', 'gravityforms' );
|
||||
}
|
||||
|
||||
$str .= "<option value=''>{$placeholder}</option>";
|
||||
|
||||
$year = intval( date( 'Y' ) );
|
||||
|
||||
for ( $i = $year; $i < ( $year + 20 ); $i ++ ) {
|
||||
$selected = intval( $selected_year ) == $i ? "selected='selected'" : '';
|
||||
$str .= "<option value='{$i}' {$selected}>{$i}</option>";
|
||||
}
|
||||
|
||||
return $str;
|
||||
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$card_number = trim( rgget( $this->id . '.1', $value ) );
|
||||
$card_type = trim( rgget( $this->id . '.4', $value ) );
|
||||
$separator = $format == 'html' ? '<br/>' : "\n";
|
||||
|
||||
return empty( $card_number ) ? '' : $card_type . $separator . $card_number;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_form_inline_script_on_page_render( $form ) {
|
||||
|
||||
$field_id = "input_{$form['id']}_{$this->id}";
|
||||
|
||||
if ( $this->forceSSL && ! GFCommon::is_ssl() && ! GFCommon::is_preview() ) {
|
||||
$script = "document.location.href='" . esc_js( RGFormsModel::get_current_page_url( true ) ) . "';";
|
||||
} else {
|
||||
$script = "jQuery(document).ready(function(){ { gformMatchCard(\"{$field_id}_1\"); } } );";
|
||||
}
|
||||
|
||||
$card_rules = $this->get_credit_card_rules();
|
||||
$script = "if(!window['gf_cc_rules']){window['gf_cc_rules'] = new Array(); } window['gf_cc_rules'] = " . GFCommon::json_encode( $card_rules ) . "; $script";
|
||||
|
||||
return $script;
|
||||
}
|
||||
|
||||
public function get_credit_card_rules() {
|
||||
|
||||
$cards = GFCommon::get_card_types();
|
||||
//$supported_cards = //TODO: Only include enabled cards
|
||||
$rules = array();
|
||||
|
||||
foreach ( $cards as $card ) {
|
||||
$prefixes = explode( ',', $card['prefixes'] );
|
||||
foreach ( $prefixes as $prefix ) {
|
||||
$rules[ $card['slug'] ][] = $prefix;
|
||||
}
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function get_entry_inputs() {
|
||||
$inputs = array();
|
||||
// only store month and card number input values
|
||||
foreach ( $this->inputs as $input ) {
|
||||
if ( in_array( $input['id'], array( $this->id . '.1', $this->id . '.4' ) ) ) {
|
||||
$inputs[] = $input;
|
||||
}
|
||||
}
|
||||
|
||||
return $inputs;
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
|
||||
//saving last 4 digits of credit card
|
||||
list( $input_token, $field_id_token, $input_id ) = rgexplode( '_', $input_name, 3 );
|
||||
if ( $input_id == '1' ) {
|
||||
$value = str_replace( ' ', '', $value );
|
||||
$card_number_length = strlen( $value );
|
||||
$value = substr( $value, - 4, 4 );
|
||||
$value = str_pad( $value, $card_number_length, 'X', STR_PAD_LEFT );
|
||||
} elseif ( $input_id == '4' ) {
|
||||
|
||||
$value = rgpost( "input_{$field_id_token}_4" );
|
||||
|
||||
if ( ! $value ) {
|
||||
$card_number = rgpost( "input_{$field_id_token}_1" );
|
||||
$card_type = GFCommon::get_card_type( $card_number );
|
||||
$value = $card_type ? $card_type['name'] : '';
|
||||
}
|
||||
} else {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
return $this->sanitize_entry_value( $value, $form['id'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades inputs, if needed.
|
||||
*
|
||||
* @since 2.1.2.7
|
||||
* @access public
|
||||
* @see GF_Field::post_convert_field()
|
||||
*
|
||||
* @uses GF_Field::post_convert_field()
|
||||
* @uses GF_Field_CreditCard::maybe_upgrade_inputs()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function post_convert_field() {
|
||||
parent::post_convert_field();
|
||||
$this->maybe_upgrade_inputs();
|
||||
}
|
||||
|
||||
/**
|
||||
* GF1.8 and earlier used 5 inputs (1 input for the expiration date); GF1.9 changed to 6 inputs (the expiration month and year now separate); upgrade those fields still using the older configuration.
|
||||
*/
|
||||
public function maybe_upgrade_inputs() {
|
||||
$inputs = $this->inputs;
|
||||
$exp_input = $inputs[1];
|
||||
$exp_id = $this->id . '.2';
|
||||
|
||||
if ( count( $inputs ) == 5 && $exp_input['id'] == $exp_id ) {
|
||||
$new_inputs = array(
|
||||
array(
|
||||
'id' => $exp_id . '_month',
|
||||
'label' => esc_html__( 'Expiration Month', 'gravityforms' ),
|
||||
'defaultLabel' => $exp_input['label']
|
||||
),
|
||||
array(
|
||||
'id' => $exp_id . '_year',
|
||||
'label' => esc_html__( 'Expiration Year', 'gravityforms' ),
|
||||
)
|
||||
);
|
||||
|
||||
array_splice( $inputs, 1, 1, $new_inputs );
|
||||
$this->inputs = $inputs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_CreditCard() );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.6
|
||||
*
|
||||
* Class GF_Field_Donationç
|
||||
*/
|
||||
class GF_Field_Donation extends GF_Field {
|
||||
|
||||
public $type = 'donation';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'donation_field_type_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'label_placement_setting',
|
||||
'rules_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$price = GFCommon::to_number( $value );
|
||||
if ( ! rgblank( $value ) && ( $price === false || $price < 0 ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'Please enter a valid amount.', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = absint( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$value = esc_attr( $value );
|
||||
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
return "<div class='ginput_container ginput_container_donation'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='text' value='{$value}' class='{$class} ginput_donation_amount' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
</div>";
|
||||
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
return GFCommon::to_money( $value, $currency );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Donation() );
|
||||
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Email extends GF_Field {
|
||||
|
||||
public $type = 'email';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Email', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to enter a valid email address.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--mail';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'email_confirm_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'autocomplete_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_entry_inputs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) || ! $this->emailConfirmEnabled ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this field expects an array during submission.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_value_submission_array() {
|
||||
return (bool) $this->emailConfirmEnabled ;
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$email = is_array( $value ) ? rgar( $value, 0 ) : $value; // Form objects created in 1.8 will supply a string as the value.
|
||||
$is_blank = rgblank( $value ) || ( is_array( $value ) && rgempty( array_filter( $value ) ) );
|
||||
|
||||
if ( ! $is_blank && ! GFCommon::is_valid_email( $email ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'The email address entered is invalid, please check the formatting (e.g. email@domain.com).', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( $this->emailConfirmEnabled && ! empty( $email ) ) {
|
||||
$confirm = is_array( $value ) ? rgar( $value, 1 ) : $this->get_input_value_submission( 'input_' . $this->id . '_2' );
|
||||
if ( $confirm != $email ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Your emails do not match.', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$value = array_values( $value );
|
||||
}
|
||||
|
||||
$form_id = absint( $form['id'] );
|
||||
$id = absint( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
$form_id = ( $is_entry_detail || $is_form_editor ) && empty( $form_id ) ? rgget( 'id' ) : $form_id;
|
||||
|
||||
$size = $this->size;
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
|
||||
$class = $this->emailConfirmEnabled ? '' : $size . $class_suffix; //Size only applies when confirmation is disabled
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$form_sub_label_placement = rgar( $form, 'subLabelPlacement' );
|
||||
$field_sub_label_placement = $this->subLabelPlacement;
|
||||
$is_sub_label_above = $field_sub_label_placement == 'above' || ( empty( $field_sub_label_placement ) && $form_sub_label_placement == 'above' );
|
||||
$sub_label_class = $field_sub_label_placement == 'hidden_label' ? "hidden_sub_label screen-reader-text" : '';
|
||||
|
||||
$html_input_type = 'email';
|
||||
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
$enter_email_field_input = GFFormsModel::get_input( $this, $this->id . '' );
|
||||
$confirm_field_input = GFFormsModel::get_input( $this, $this->id . '.2' );
|
||||
|
||||
$enter_email_label = rgar( $enter_email_field_input, 'customLabel' ) != '' ? $enter_email_field_input['customLabel'] : esc_html__( 'Enter Email', 'gravityforms' );
|
||||
$enter_email_label = gf_apply_filters( array( 'gform_email', $form_id ), $enter_email_label, $form_id );
|
||||
$confirm_email_label = rgar( $confirm_field_input, 'customLabel' ) != '' ? $confirm_field_input['customLabel'] : esc_html__( 'Confirm Email', 'gravityforms' );
|
||||
$confirm_email_label = gf_apply_filters( array( 'gform_email_confirm', $form_id ), $confirm_email_label, $form_id );
|
||||
|
||||
$single_placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$enter_email_placeholder_attribute = $this->get_input_placeholder_attribute( $enter_email_field_input );
|
||||
$confirm_email_placeholder_attribute = $this->get_input_placeholder_attribute( $confirm_field_input );
|
||||
|
||||
$single_autocomplete_attribute = $this->get_field_autocomplete_attribute();
|
||||
$enter_email_autocomplete_attribute = $this->get_input_autocomplete_attribute( $enter_email_field_input );
|
||||
$confirm_email_autocomplete_attribute = $this->get_input_autocomplete_attribute( $confirm_field_input );
|
||||
|
||||
if ( $is_form_editor ) {
|
||||
$single_style = $this->emailConfirmEnabled ? "style='display:none;'" : '';
|
||||
$confirm_style = $this->emailConfirmEnabled ? '' : "style='display:none;'";
|
||||
|
||||
if ( $is_sub_label_above ) {
|
||||
return "<div class='ginput_container ginput_container_email ginput_single_email' {$single_style}>
|
||||
<input name='input_{$id}' type='{$html_input_type}' class='" . esc_attr( $class ) . "' disabled='disabled' {$single_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$single_autocomplete_attribute} />
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>
|
||||
<div class='ginput_complex ginput_container ginput_container_email ginput_confirm_email gform-grid-row' {$confirm_style} id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$enter_email_label}</label>
|
||||
<input class='{$class}' type='text' name='input_{$id}' id='{$field_id}' disabled='disabled' {$enter_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$enter_email_autocomplete_attribute} />
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_right gform-grid-col gform-grid-col--size-auto'>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_email_label}</label>
|
||||
<input class='{$class}' type='text' name='input_{$id}_2' id='{$field_id}_2' disabled='disabled' {$confirm_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$confirm_email_autocomplete_attribute} />
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>";
|
||||
} else {
|
||||
return "<div class='ginput_container ginput_container_email ginput_single_email' {$single_style}>
|
||||
<input name='input_{$id}' type='{$html_input_type}' class='" . esc_attr( $class ) . "' disabled='disabled' {$single_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$single_autocomplete_attribute} />
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>
|
||||
<div class='ginput_complex ginput_container ginput_container_email ginput_confirm_email gform-grid-row' {$confirm_style} id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<input class='{$class}' type='text' name='input_{$id}' id='{$field_id}' disabled='disabled' {$enter_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$enter_email_autocomplete_attribute} />
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$enter_email_label}</label>
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_right gform-grid-col gform-grid-col--size-auto'>
|
||||
<input class='{$class}' type='text' name='input_{$id}_2' id='{$field_id}_2' disabled='disabled' {$confirm_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$confirm_email_autocomplete_attribute} />
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_email_label}</label>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>";
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( $this->emailConfirmEnabled && ! $is_entry_detail ) {
|
||||
$first_tabindex = $this->get_tabindex();
|
||||
$last_tabindex = $this->get_tabindex();
|
||||
$email_value = is_array( $value ) ? rgar( $value, 0 ) : $value;
|
||||
$email_value = esc_attr( $email_value );
|
||||
$confirmation_value = is_array( $value ) ? rgar( $value, 1 ) : rgpost( 'input_' . $this->id . '_2' );
|
||||
$confirmation_value = esc_attr( $confirmation_value );
|
||||
$confirmation_disabled = $is_entry_detail ? "disabled='disabled'" : $disabled_text;
|
||||
if ( $is_sub_label_above ) {
|
||||
return "<div class='ginput_complex ginput_container ginput_container_email gform-grid-row' id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>" . $enter_email_label . "</label>
|
||||
<input class='{$class}' type='{$html_input_type}' name='input_{$id}' id='{$field_id}' value='{$email_value}' {$first_tabindex} {$disabled_text} {$enter_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$enter_email_autocomplete_attribute}/>
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_right gform-grid-col gform-grid-col--size-auto'>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_email_label}</label>
|
||||
<input class='{$class}' type='{$html_input_type}' name='input_{$id}_2' id='{$field_id}_2' value='{$confirmation_value}' {$last_tabindex} {$confirmation_disabled} {$confirm_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$confirm_email_autocomplete_attribute}/>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>";
|
||||
} else {
|
||||
return "<div class='ginput_complex ginput_container ginput_container_email gform-grid-row' id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<input class='{$class}' type='{$html_input_type}' name='input_{$id}' id='{$field_id}' value='{$email_value}' {$first_tabindex} {$disabled_text} {$enter_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$enter_email_autocomplete_attribute}/>
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$enter_email_label}</label>
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_right gform-grid-col gform-grid-col--size-auto'>
|
||||
<input class='{$class}' type='{$html_input_type}' name='input_{$id}_2' id='{$field_id}_2' value='{$confirmation_value}' {$last_tabindex} {$confirmation_disabled} {$confirm_email_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$confirm_email_autocomplete_attribute}/>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_email_label}</label>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>";
|
||||
}
|
||||
} else {
|
||||
$tabindex = $this->get_tabindex();
|
||||
$value = esc_attr( $value );
|
||||
$class = esc_attr( $class );
|
||||
|
||||
return "<div class='ginput_container ginput_container_email'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='{$html_input_type}' value='$value' class='{$class}' {$tabindex} {$disabled_text} {$single_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$single_autocomplete_attribute}/>
|
||||
</div>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
if ( GFCommon::is_valid_email( $value ) && $format == 'html' ) {
|
||||
return sprintf( "<a href='mailto:%s'>%s</a>", esc_attr( $value ), esc_html( $value ) );
|
||||
}
|
||||
|
||||
return esc_html( $value );
|
||||
}
|
||||
|
||||
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
|
||||
|
||||
if ( $this->emailConfirmEnabled && ! $this->is_entry_detail() && is_array( $this->inputs ) ) {
|
||||
$value[0] = $this->get_input_value_submission( 'input_' . $this->id, $this->inputName, $field_values, $get_from_post_global_var );
|
||||
$value[1] = $this->get_input_value_submission( 'input_' . $this->id . '_2', $this->inputName, $field_values, $get_from_post_global_var );
|
||||
} else {
|
||||
$value = $this->get_input_value_submission( 'input_' . $this->id, $this->inputName, $field_values, $get_from_post_global_var );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value is empty, get the default value.
|
||||
*
|
||||
* @since 2.6.5
|
||||
*
|
||||
* @param array|string $value The field's value.
|
||||
*
|
||||
* @return array|string The default value, if there is one.
|
||||
*/
|
||||
public function get_value_default_if_empty( $value ) {
|
||||
|
||||
if ( is_array( $this->inputs ) && is_array( $value ) ) {
|
||||
// get_value_default() uses the input IDs as the array keys, while $value is an array that uses automatic index, so we need to reindex the defaults.
|
||||
$defaults = $this->get_value_default();
|
||||
$defaults = is_array( $defaults ) ? array_values( $defaults ) : $defaults;
|
||||
foreach( $value as $index => &$input_value ) {
|
||||
if ( rgblank( $input_value ) ) {
|
||||
$input_value = rgar( $defaults, $index );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! GFCommon::is_empty_array( $value ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $this->get_value_default();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the "for" attribute in the field label when the confirmation input is enabled.
|
||||
* Inputs are only allowed one label (a11y) and the inputs already have labels.
|
||||
*
|
||||
* @since 2.4
|
||||
* @access public
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_first_input_id( $form ) {
|
||||
return $this->emailConfirmEnabled ? '' : parent::get_first_input_id( $form );
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Email() );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Hidden extends GF_Field {
|
||||
|
||||
public $type = 'hidden';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Hidden', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Stores information that should not be visible to the user but can be processed and saved with the user submission.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--hidden';
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported(){
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'prepopulate_field_setting',
|
||||
'label_setting',
|
||||
'default_value_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$field_type = $is_entry_detail || $is_form_editor ? 'text' : 'hidden';
|
||||
$class_attribute = $is_entry_detail || $is_form_editor ? '' : "class='gform_hidden'";
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
|
||||
$input = sprintf( "<input name='input_%d' id='%s' type='$field_type' {$class_attribute} {$required_attribute} {$invalid_attribute} value='%s' %s/>", $id, $field_id, esc_attr( $value ), $disabled_text );
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_text'>%s</div>", $input );
|
||||
}
|
||||
|
||||
public function get_field_content( $value, $force_frontend_label, $form ) {
|
||||
$form_id = $form['id'];
|
||||
$admin_buttons = $this->get_admin_buttons();
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_entry_detail || $is_form_editor;
|
||||
$field_label = $this->get_field_label( $force_frontend_label, $value );
|
||||
$field_id = $is_admin || $form_id == 0 ? "input_{$this->id}" : 'input_' . $form_id . "_{$this->id}";
|
||||
$field_content = ! $is_admin ? '{FIELD}' : $field_content = sprintf( "%s<label class='gfield_label gform-field-label' for='%s'>%s</label>{FIELD}", $admin_buttons, $field_id, esc_html( $field_label ) );
|
||||
|
||||
return $field_content;
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Hidden() );
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_HiddenProduct extends GF_Field {
|
||||
|
||||
public $type = 'hiddenproduct';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--hidden';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'base_price_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$quantity_id = $this->id . '.3';
|
||||
$quantity = rgget( $quantity_id, $value );
|
||||
|
||||
if ( $this->isRequired && rgblank( $quantity ) && ! $this->disableQuantity ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty($this->errorMessage) ? esc_html__( 'This field is required.', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( ! empty( $quantity ) && ( ! is_numeric( $quantity ) || intval( $quantity ) != floatval( $quantity ) || intval( $quantity ) < 0 ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Please enter a valid quantity', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value_default() {
|
||||
$value = array();
|
||||
if ( is_array( $this->inputs ) ) {
|
||||
foreach ( $this->inputs as $index => $input ) {
|
||||
$input_value = $this->is_form_editor() ? rgar( $input, 'defaultValue' ) : GFCommon::replace_variables_prepopulate( rgar( $input, 'defaultValue' ) );
|
||||
if ( rgblank( $input_value ) && $input['id'] == "{$this->id}.2" ) {
|
||||
$input_value = $this->basePrice;
|
||||
}
|
||||
$value[ strval( $input['id'] ) ] = $input_value;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
|
||||
$product_name = ! is_array( $value ) || empty( $value[ $this->id . '.1' ] ) ? esc_attr( $this->label ) : esc_attr( $value[ $this->id . '.1' ] );
|
||||
$price = ! is_array( $value ) || empty( $value[ $this->id . '.2' ] ) ? $this->basePrice : esc_attr( $value[ $this->id . '.2' ] );
|
||||
$quantity = is_array( $value ) ? esc_attr( $value[ $this->id . '.3' ] ) : '';
|
||||
|
||||
if ( rgblank( $quantity ) ) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
if ( empty( $price ) ) {
|
||||
$price = 0;
|
||||
}
|
||||
|
||||
$price = esc_attr( $price );
|
||||
|
||||
$has_quantity_field = sizeof( GFCommon::get_product_fields_by_type( $form, array( 'quantity' ), $this->id ) ) > 0;
|
||||
if ( $has_quantity_field ) {
|
||||
$this->disableQuantity = true;
|
||||
}
|
||||
|
||||
$quantity_field = $has_quantity_field ? '' : "<input type='hidden' name='input_{$id}.3' value='" . esc_attr( $quantity ) . "' id='ginput_quantity_{$form_id}_{$this->id}' class='gform_hidden' />";
|
||||
$product_name_field = "<input type='hidden' name='input_{$id}.1' value='{$product_name}' class='gform_hidden' />";
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$field_type = $is_entry_detail || $is_form_editor ? 'text' : 'hidden';
|
||||
|
||||
return $quantity_field . $product_name_field . "<input name='input_{$id}.2' id='ginput_base_price_{$form_id}_{$this->id}' type='{$field_type}' value='{$price}' class='gform_hidden ginput_amount' {$disabled_text}/>";
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
if ( is_array( $value ) && ! empty( $value ) ) {
|
||||
$product_name = trim( $value[ $this->id . '.1' ] );
|
||||
$price = trim( $value[ $this->id . '.2' ] );
|
||||
$quantity = trim( $value[ $this->id . '.3' ] );
|
||||
|
||||
$product_details = $product_name;
|
||||
|
||||
if ( ! rgblank( $quantity ) ) {
|
||||
$product_details .= ', ' . esc_html__( 'Qty: ', 'gravityforms' ) . $quantity;
|
||||
}
|
||||
|
||||
if ( ! rgblank( $price ) ) {
|
||||
$product_details .= ', ' . esc_html__( 'Price: ', 'gravityforms' ) . GFCommon::format_number( $price, 'currency', $currency );
|
||||
}
|
||||
|
||||
return $product_details;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
|
||||
$price_number = GFCommon::to_number( $this->basePrice );
|
||||
$this->basePrice = GFCommon::to_money( $price_number );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_HiddenProduct() );
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_HTML extends GF_Field {
|
||||
|
||||
public $type = 'html';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'HTML', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Places a block of free form HTML anywhere in your form.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--html-code';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'content_setting',
|
||||
'disable_margins_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'label_setting',
|
||||
'css_class_setting',
|
||||
'visibility_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$content = $is_entry_detail || $is_form_editor ? "<div class='gf-html-container'><span class='gf_blockheader'>
|
||||
<i class='fa fa-code fa-lg'></i> " . esc_html__( 'HTML Content', 'gravityforms' ) .
|
||||
'</span><span>' . esc_html__( 'This is a content placeholder. HTML content is not displayed in the form admin. Preview this form to view the content.', 'gravityforms' ) . '</span></div>'
|
||||
: $this->content;
|
||||
$content = GFCommon::replace_variables_prepopulate( $content ); // adding support for merge tags
|
||||
|
||||
// adding support for shortcodes
|
||||
$content = $this->do_shortcode( $content );
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function get_field_content( $value, $force_frontend_label, $form ) {
|
||||
$form_id = $form['id'];
|
||||
$admin_buttons = $this->get_admin_buttons();
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_entry_detail || $is_form_editor;
|
||||
$field_label = $this->get_field_label( $force_frontend_label, $value );
|
||||
$field_id = $is_admin || $form_id == 0 ? "input_{$this->id}" : 'input_' . $form_id . "_{$this->id}";
|
||||
$admin_hidden_markup = ( $this->visibility == 'hidden' ) ? $this->get_hidden_admin_markup() : '';
|
||||
$field_content = ! $is_admin ? '{FIELD}' : $field_content = sprintf( "%s%s<label class='gfield_label gform-field-label' for='%s'>%s</label>{FIELD}", $admin_buttons, $admin_hidden_markup, $field_id, esc_html( $field_label ) );
|
||||
|
||||
return $field_content;
|
||||
}
|
||||
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$this->content = GFCommon::maybe_wp_kses( $this->content );
|
||||
}
|
||||
|
||||
public function do_shortcode( $content ){
|
||||
|
||||
if( isset($GLOBALS['wp_embed']) ) {
|
||||
// adds support for the [embed] shortcode
|
||||
$content = $GLOBALS['wp_embed']->run_shortcode( $content );
|
||||
}
|
||||
// executes all other shortcodes
|
||||
$content = do_shortcode( $content );
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_HTML() );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
|
||||
// If the GF_Field class isn't available, bail.
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Field_MultiSelect
|
||||
*
|
||||
* Allows the creation of multiselect fields.
|
||||
*
|
||||
* @since Unknown
|
||||
*
|
||||
* @uses GF_Field
|
||||
*/
|
||||
class GF_Field_MultiSelect extends GF_Field {
|
||||
|
||||
public $type = 'multiselect';
|
||||
|
||||
/**
|
||||
* Returns the field title.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @return string The field title. Escaped.
|
||||
*/
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Multi Select', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to select multiple options available in the multi select box.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--multi-select';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class names of the settings which should be available on the field in the form editor.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @return array Settings available within the field editor.
|
||||
*/
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'enable_enhanced_ui_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'choices_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates this field type can be used when configuring conditional logic rules.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this field expects an array during submission.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_value_submission_array() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field inner markup.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GF_Field_MultiSelect::is_entry_detail()
|
||||
* @uses GF_Field_MultiSelect::is_form_editor()
|
||||
* @uses GF_Field_MultiSelect::get_conditional_logic_event()
|
||||
* @uses GF_Field_MultiSelect::get_tabindex()
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string|array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
* @param null|array $entry Null or the Entry Object currently being edited.
|
||||
*
|
||||
* @return string The field input HTML markup.
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
$css_class = trim( $class . ' gfield_select' );
|
||||
$tabindex = $this->get_tabindex();
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$describedby_attribute = $this->get_aria_describedby();
|
||||
|
||||
|
||||
/**
|
||||
* Allow the placeholder used by the enhanced ui to be overridden
|
||||
*
|
||||
* @since 1.9.14 Third parameter containing the field ID was added.
|
||||
* @since Unknown
|
||||
*
|
||||
* @param string $placeholder The placeholder text.
|
||||
* @param integer $form_id The ID of the current form.
|
||||
*/
|
||||
$placeholder = gf_apply_filters( array(
|
||||
'gform_multiselect_placeholder',
|
||||
$form_id,
|
||||
$this->id
|
||||
), __( 'Click to select...', 'gravityforms' ), $form_id, $this );
|
||||
$placeholder = $this->enableEnhancedUI ? "data-placeholder='" . esc_attr( $placeholder ) . "'" : '';
|
||||
|
||||
$size = $this->multiSelectSize;
|
||||
if ( empty( $size ) ) {
|
||||
$size = 7;
|
||||
}
|
||||
$size = esc_attr( $size );
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_multiselect'><select multiple='multiple' {$placeholder} size='{$size}' name='input_%d[]' id='%s' class='%s' $tabindex %s %s %s %s>%s</select></div>", $id, esc_attr( $field_id ), $css_class, $disabled_text, $invalid_attribute, $required_attribute, $describedby_attribute, $this->get_choices( $value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for retrieving the markup for the choices.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::get_select_choices()
|
||||
*
|
||||
* @param string|array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
*
|
||||
* @return string Returns the choices available within the multi-select field.
|
||||
*/
|
||||
public function get_choices( $value ) {
|
||||
|
||||
$value = $this->to_array( $value );
|
||||
|
||||
return GFCommon::get_select_choices( $this, $value, false );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for display on the entries list page.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param string $field_id The field or input ID currently being processed.
|
||||
* @param array $columns The properties for the columns being displayed on the entry list page.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string $value The value of the field. Escaped.
|
||||
*/
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
// Add space after comma-delimited values.
|
||||
$value = implode( ', ', $this->to_array( $value ) );
|
||||
return esc_html( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for display on the entry detail page and for the {all_fields} merge tag.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::selection_display()
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param string $currency The entry currency code.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param string $media The location where the value will be displayed. Possible values: screen or email.
|
||||
*
|
||||
* @return string The list items, stored within an unordered list.
|
||||
*/
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
|
||||
if ( empty( $value ) || ( $format == 'text' && $this->storageType !== 'json' ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$items = $this->to_array( $value );
|
||||
|
||||
foreach ( $items as &$item ) {
|
||||
$item = esc_html( GFCommon::selection_display( $item, $this, $currency, $use_text ) );
|
||||
}
|
||||
|
||||
if ( $format === 'text' ) {
|
||||
return GFCommon::implode_non_blank( ', ', $items );
|
||||
}
|
||||
|
||||
return "<ul class='bulleted'><li>" . GFCommon::implode_non_blank( '</li><li>', $items ) . '</li></ul>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the value before it is saved to the Entry Object.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GF_Field_MultiSelect::sanitize_entry_value()
|
||||
*
|
||||
* @param array|string $value The value to be saved.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $input_name The input name used when accessing the $_POST.
|
||||
* @param int $lead_id The ID of the Entry currently being processed.
|
||||
* @param array $lead The Entry Object currently being processed.
|
||||
*
|
||||
* @return string $value The field value. Comma separated if an array.
|
||||
*/
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
foreach ( $value as &$v ) {
|
||||
$v = $this->sanitize_entry_value( $v, $form['id'] );
|
||||
}
|
||||
} else {
|
||||
$value = $this->sanitize_entry_value( $value, $form['id'] );
|
||||
}
|
||||
|
||||
return empty( $value ) ? '' : $this->to_string( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for when the field/input merge tag is processed.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::format_post_category()
|
||||
* @uses GFCommon::format_variable_value()
|
||||
* @uses GFCommon::selection_display()
|
||||
* @uses GFCommon::implode_non_blank()
|
||||
*
|
||||
* @param string|array $value The field value. Depending on the location the merge tag is being used the following functions may have already been applied to the value: esc_html, nl2br, and urlencode.
|
||||
* @param string $input_id The field or input ID from the merge tag currently being processed.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $modifier The merge tag modifier. e.g. value
|
||||
* @param string|array $raw_value The raw field value from before any formatting was applied to $value.
|
||||
* @param bool $url_encode Indicates if the urlencode function may have been applied to the $value.
|
||||
* @param bool $esc_html Indicates if the esc_html function may have been applied to the $value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param bool $nl2br Indicates if the nl2br function may have been applied to the $value.
|
||||
*
|
||||
* @return string $return The merge tag value.
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
$items = $this->to_array( $raw_value );
|
||||
|
||||
$modifiers = $this->get_modifiers();
|
||||
|
||||
if ( $this->type == 'post_category' ) {
|
||||
if ( is_array( $items ) ) {
|
||||
$use_id = in_array( 'id', $modifiers );
|
||||
|
||||
foreach ( $items as &$item ) {
|
||||
$cat = GFCommon::format_post_category( $item, $use_id );
|
||||
$item = GFCommon::format_variable_value( $cat, $url_encode, $esc_html, $format );
|
||||
}
|
||||
}
|
||||
} elseif ( ! in_array( 'value', $modifiers ) ) {
|
||||
|
||||
foreach ( $items as &$item ) {
|
||||
$item = GFCommon::selection_display( $item, $this, rgar( $entry, 'currency' ), true );
|
||||
$item = GFCommon::format_variable_value( $item, $url_encode, $esc_html, $format );
|
||||
}
|
||||
}
|
||||
|
||||
$return = GFCommon::implode_non_blank( ', ', $items );
|
||||
|
||||
if ( $format == 'html' || $esc_html ) {
|
||||
$return = esc_html( $return );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value before it is used in entry exports and by framework add-ons using GFAddOn::get_field_value().
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::selection_display()
|
||||
* @uses GFCommon::implode_non_blank()
|
||||
*
|
||||
* @param array $entry The entry currently being processed.
|
||||
* @param string $input_id The field or input ID.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param bool|false $is_csv Is the value going to be used in the .csv entries export?
|
||||
*
|
||||
* @return string $value The value of a field from an export file.
|
||||
*/
|
||||
public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
|
||||
if ( empty( $input_id ) ) {
|
||||
$input_id = $this->id;
|
||||
}
|
||||
|
||||
$value = rgar( $entry, $input_id );
|
||||
|
||||
if ( ! empty( $value ) && ! $is_csv ) {
|
||||
$items = $this->to_array( $value );
|
||||
|
||||
foreach ( $items as &$item ) {
|
||||
$item = GFCommon::selection_display( $item, $this, rgar( $entry, 'currency' ), $use_text );
|
||||
}
|
||||
$value = GFCommon::implode_non_blank( ', ', $items );
|
||||
|
||||
} elseif ( $this->storageType === 'json' ) {
|
||||
|
||||
$items = json_decode( $value );
|
||||
$value = GFCommon::implode_non_blank( ', ', $items );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array to a string.
|
||||
*
|
||||
* @since 2.2.3.7 Changed access to public.
|
||||
* @since 2.2
|
||||
* @access public
|
||||
*
|
||||
* @uses \GF_Field_MultiSelect::$storageType
|
||||
*
|
||||
* @param array $value The array to convert to a string.
|
||||
*
|
||||
* @return string The converted string.
|
||||
*/
|
||||
public function to_string( $value ) {
|
||||
if ( $this->storageType === 'json' ) {
|
||||
return json_encode( $value );
|
||||
} else {
|
||||
return is_array( $value ) ? implode( ',', $value ) : $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to an array.
|
||||
*
|
||||
* @since 2.2.3.7 Changed access to public.
|
||||
* @since 2.2
|
||||
* @access public
|
||||
*
|
||||
* @uses \GF_Field_MultiSelect::$storageType
|
||||
*
|
||||
* @param string $value A comma-separated or JSON string to convert.
|
||||
*
|
||||
* @return array The converted array.
|
||||
*/
|
||||
public function to_array( $value ) {
|
||||
if ( empty( $value ) ) {
|
||||
return array();
|
||||
} elseif ( is_array( $value ) ) {
|
||||
return $value;
|
||||
} elseif ( $this->storageType !== 'json' || $value[0] !== '[' ) {
|
||||
return array_map( 'trim', explode( ',', $value ) );
|
||||
} else {
|
||||
$json = json_decode( $value, true );
|
||||
|
||||
return $json == null ? array() : $json;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces settings into expected values while saving the form object.
|
||||
*
|
||||
* No escaping should be done at this stage to prevent double escaping on output.
|
||||
*
|
||||
* Currently called only for forms created after version 1.9.6.10.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$this->enableEnhancedUI = (bool) $this->enableEnhancedUI;
|
||||
|
||||
$this->storageType = empty( $this->storageType ) || $this->storageType === 'json' ? $this->storageType : 'json';
|
||||
|
||||
if ( $this->type === 'post_category' ) {
|
||||
$this->displayAllCategories = (bool) $this->displayAllCategories;
|
||||
}
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
return array( 'contains' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Register the new field type.
|
||||
GF_Fields::register( new GF_Field_MultiSelect() );
|
||||
@@ -0,0 +1,738 @@
|
||||
<?php /** @noinspection PhpCSValidationInspection */
|
||||
|
||||
// If Gravity Forms isn't loaded, bail.
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Field_Name
|
||||
*
|
||||
* Handles the behavior of the Name field.
|
||||
*
|
||||
* @since Unknown
|
||||
*/
|
||||
class GF_Field_Name extends GF_Field {
|
||||
|
||||
/**
|
||||
* Sets the field type.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @var string The type of field.
|
||||
*/
|
||||
public $type = 'name';
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the field title of the Name field.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFCommon::get_field_type_title()
|
||||
* @used-by GF_Field::get_form_editor_button()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Name', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to enter their name in the format you have specified.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--name-2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines if conditional logic is supported by the Name field.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDetail::inline_scripts()
|
||||
* @used-by GFFormSettings::output_field_scripts()
|
||||
*
|
||||
* @return bool true
|
||||
*/
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the IDs of required inputs.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_required_inputs_ids() {
|
||||
return array( '3', '6' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates Name field inputs.
|
||||
*
|
||||
* @since 1.9
|
||||
* @since 2.6.5 Updated to use set_required_error().
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDisplay::validate()
|
||||
* @uses GF_Field_Name::$isRequired
|
||||
* @uses GF_Field_Name::$nameFormat
|
||||
* @uses GF_Field_Name::get_input_property
|
||||
* @uses GF_Field_Name::$failed_validation
|
||||
* @uses GF_Field_Name::$validation_message
|
||||
* @uses GF_Field_Name::$errorMessage
|
||||
*
|
||||
* @param array|string $value The value of the field to validate. Not used here.
|
||||
* @param array $form The Form Object. Not used here.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function validate( $value, $form ) {
|
||||
if ( $this->isRequired && $this->nameFormat != 'simple' ) {
|
||||
$this->set_required_error( $value, true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the field settings available for the Name field in the form editor.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDetail::inline_scripts()
|
||||
*
|
||||
* @return array The field settings available.
|
||||
*/
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'label_placement_setting',
|
||||
'sub_label_placement_setting',
|
||||
'default_input_values_setting',
|
||||
'input_placeholders_setting',
|
||||
'name_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'autocomplete_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTML markup for the field input.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFCommon::get_field_input()
|
||||
* @uses GF_Field::is_entry_detail()
|
||||
* @uses GF_Field::is_form_editor()
|
||||
* @uses GF_Field_Name::$size
|
||||
* @uses GF_Field_Name::$id
|
||||
* @uses GF_Field_Name::$subLabelPlacement
|
||||
* @uses GF_Field_Name::$isRequired
|
||||
* @uses GF_Field_Name::$failed_validation
|
||||
* @uses GFForms::get()
|
||||
* @uses GFFormsModel::get_input()
|
||||
* @uses GFCommon::get_input_placeholder_attribute()
|
||||
* @uses GFCommon::get_tabindex()
|
||||
* @uses GFCommon::get_field_placeholder_attribute()
|
||||
* @uses GF_Field_Name::get_css_class()
|
||||
*
|
||||
* @param array $form The Form Object.
|
||||
* @param string $value The value of the field. Defaults to empty string.
|
||||
* @param array|null $entry The Entry Object. Defaults to null.
|
||||
*
|
||||
* @return string The HTML markup for the field input.
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_entry_detail || $is_form_editor;
|
||||
|
||||
$form_id = $form['id'];
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
$form_id = ( $is_entry_detail || $is_form_editor ) && empty( $form_id ) ? rgget( 'id' ) : $form_id;
|
||||
|
||||
$size = $this->size;
|
||||
$class_suffix = rgget('view') == 'entry' ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
|
||||
$form_sub_label_placement = rgar( $form, 'subLabelPlacement' );
|
||||
$field_sub_label_placement = $this->subLabelPlacement;
|
||||
$is_sub_label_above = $field_sub_label_placement == 'above' || ( empty( $field_sub_label_placement ) && $form_sub_label_placement == 'above' );
|
||||
$sub_label_class = $field_sub_label_placement == 'hidden_label' ? "hidden_sub_label screen-reader-text" : '';
|
||||
|
||||
$prefix = '';
|
||||
$first = '';
|
||||
$middle = '';
|
||||
$last = '';
|
||||
$suffix = '';
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$prefix = esc_attr( GFForms::get( $this->id . '.2', $value ) );
|
||||
$first = esc_attr( GFForms::get( $this->id . '.3', $value ) );
|
||||
$middle = esc_attr( GFForms::get( $this->id . '.4', $value ) );
|
||||
$last = esc_attr( GFForms::get( $this->id . '.6', $value ) );
|
||||
$suffix = esc_attr( GFForms::get( $this->id . '.8', $value ) );
|
||||
}
|
||||
|
||||
$prefix_input = GFFormsModel::get_input( $this, $this->id . '.2' );
|
||||
$first_input = GFFormsModel::get_input( $this, $this->id . '.3' );
|
||||
$middle_input = GFFormsModel::get_input( $this, $this->id . '.4' );
|
||||
$last_input = GFFormsModel::get_input( $this, $this->id . '.6' );
|
||||
$suffix_input = GFFormsModel::get_input( $this, $this->id . '.8' );
|
||||
|
||||
$first_placeholder_attribute = GFCommon::get_input_placeholder_attribute( $first_input );
|
||||
$middle_placeholder_attribute = GFCommon::get_input_placeholder_attribute( $middle_input );
|
||||
$last_placeholder_attribute = GFCommon::get_input_placeholder_attribute( $last_input );
|
||||
$suffix_placeholder_attribute = GFCommon::get_input_placeholder_attribute( $suffix_input );
|
||||
|
||||
// ARIA labels.
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$describedby_attribute = $this->get_aria_describedby();
|
||||
$input_aria_describedby = '';
|
||||
|
||||
|
||||
if ( $this->nameFormat != 'simple' ) {
|
||||
// specific aria attributes for each individual input.
|
||||
$first_aria_attributes = $this->get_aria_attributes( $value, '3');
|
||||
$middle_aria_attributes = $this->get_aria_attributes( $value, '4');
|
||||
$last_aria_attributes = $this->get_aria_attributes( $value, '6');
|
||||
$suffix_aria_attributes = $this->get_aria_attributes( $value, '8');
|
||||
}
|
||||
|
||||
$prefix_autocomplete = $this->enableAutocomplete ? $this->get_input_autocomplete_attribute( $prefix_input ) : '';
|
||||
$first_autocomplete = $this->enableAutocomplete ? $this->get_input_autocomplete_attribute( $first_input ) : '';
|
||||
$middle_autocomplete = $this->enableAutocomplete ? $this->get_input_autocomplete_attribute( $middle_input ) : '';
|
||||
$last_autocomplete = $this->enableAutocomplete ? $this->get_input_autocomplete_attribute( $last_input ) : '';
|
||||
$suffix_autocomplete = $this->enableAutocomplete ? $this->get_input_autocomplete_attribute( $suffix_input ) : '';
|
||||
|
||||
switch ( $this->nameFormat ) {
|
||||
|
||||
case 'advanced' :
|
||||
case 'extended' :
|
||||
$prefix_tabindex = GFCommon::get_tabindex();
|
||||
$first_tabindex = GFCommon::get_tabindex();
|
||||
$middle_tabindex = GFCommon::get_tabindex();
|
||||
$last_tabindex = GFCommon::get_tabindex();
|
||||
$suffix_tabindex = GFCommon::get_tabindex();
|
||||
|
||||
$prefix_sub_label = rgar( $prefix_input, 'customLabel' ) != '' ? $prefix_input['customLabel'] : gf_apply_filters( array( 'gform_name_prefix', $form_id ), esc_html__( 'Prefix', 'gravityforms' ), $form_id );
|
||||
$first_name_sub_label = rgar( $first_input, 'customLabel' ) != '' ? $first_input['customLabel'] : gf_apply_filters( array( 'gform_name_first', $form_id ), esc_html__( 'First', 'gravityforms' ), $form_id );
|
||||
$middle_name_sub_label = rgar( $middle_input, 'customLabel' ) != '' ? $middle_input['customLabel'] : gf_apply_filters( array( 'gform_name_middle', $form_id ), esc_html__( 'Middle', 'gravityforms' ), $form_id );
|
||||
$last_name_sub_label = rgar( $last_input, 'customLabel' ) != '' ? $last_input['customLabel'] : gf_apply_filters( array( 'gform_name_last', $form_id ), esc_html__( 'Last', 'gravityforms' ), $form_id );
|
||||
$suffix_sub_label = rgar( $suffix_input, 'customLabel' ) != '' ? $suffix_input['customLabel'] : gf_apply_filters( array( 'gform_name_suffix', $form_id ), esc_html__( 'Suffix', 'gravityforms' ), $form_id );
|
||||
|
||||
$prefix_markup = '';
|
||||
$first_markup = '';
|
||||
$middle_markup = '';
|
||||
$last_markup = '';
|
||||
$suffix_markup = '';
|
||||
|
||||
if ( $is_sub_label_above ) {
|
||||
|
||||
$style = ( $is_admin && rgar( $prefix_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $prefix_input, 'isHidden' ) ) {
|
||||
$prefix_select_class = isset( $prefix_input['choices'] ) && is_array( $prefix_input['choices'] ) ? 'name_prefix_select' : '';
|
||||
$prefix_markup = self::get_name_prefix_field( $prefix_input, $id, $field_id, $prefix, $disabled_text, $prefix_tabindex );
|
||||
$prefix_markup = "<span id='{$field_id}_2_container' class='name_prefix {$prefix_select_class} gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$prefix_sub_label}</label>
|
||||
{$prefix_markup}
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && rgar( $first_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $first_input, 'isHidden' ) ) {
|
||||
$first_markup = "<span id='{$field_id}_3_container' class='name_first gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$first_name_sub_label}</label>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' value='{$first}' {$first_tabindex} {$disabled_text} {$first_aria_attributes} {$first_placeholder_attribute} {$first_autocomplete} {$this->maybe_add_aria_describedby( $first_input, $field_id, $this['formId'] )}/>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && ( ! isset( $middle_input['isHidden'] ) || rgar( $middle_input, 'isHidden' ) ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ( isset( $middle_input['isHidden'] ) && $middle_input['isHidden'] == false ) ) {
|
||||
$middle_markup = "<span id='{$field_id}_4_container' class='name_middle gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<label for='{$field_id}_4' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$middle_name_sub_label}</label>
|
||||
<input type='text' name='input_{$id}.4' id='{$field_id}_4' value='{$middle}' {$middle_tabindex} {$disabled_text} {$middle_aria_attributes} {$middle_placeholder_attribute} {$middle_autocomplete} {$this->maybe_add_aria_describedby( $middle_input, $field_id, $this['formId'] )}/>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && rgar( $last_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $last_input, 'isHidden' ) ) {
|
||||
$last_markup = "<span id='{$field_id}_6_container' class='name_last gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<label for='{$field_id}_6' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$last_name_sub_label}</label>
|
||||
<input type='text' name='input_{$id}.6' id='{$field_id}_6' value='{$last}' {$last_tabindex} {$disabled_text} {$last_aria_attributes} {$last_placeholder_attribute} {$last_autocomplete} {$this->maybe_add_aria_describedby( $last_input, $field_id, $this['formId'] )}/>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && rgar( $suffix_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $suffix_input, 'isHidden' ) ) {
|
||||
$suffix_select_class = isset( $suffix_input['choices'] ) && is_array( $suffix_input['choices'] ) ? 'name_suffix_select' : '';
|
||||
$suffix_markup = "<span id='{$field_id}_8_container' class='name_suffix {$suffix_select_class} gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<label for='{$field_id}_8' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$suffix_sub_label}</label>
|
||||
<input type='text' name='input_{$id}.8' id='{$field_id}_8' value='{$suffix}' {$suffix_tabindex} {$disabled_text} {$suffix_aria_attributes} {$suffix_placeholder_attribute} {$suffix_autocomplete} {$this->maybe_add_aria_describedby( $suffix_input, $field_id, $this['formId'] )}/>
|
||||
</span>";
|
||||
}
|
||||
} else {
|
||||
$style = ( $is_admin && rgar( $prefix_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $prefix_input, 'isHidden' ) ) {
|
||||
$prefix_select_class = isset( $prefix_input['choices'] ) && is_array( $prefix_input['choices'] ) ? 'name_prefix_select' : '';
|
||||
$prefix_markup = self::get_name_prefix_field( $prefix_input, $id, $field_id, $prefix, $disabled_text, $prefix_tabindex );
|
||||
$prefix_markup = "<span id='{$field_id}_2_container' class='name_prefix {$prefix_select_class} gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
{$prefix_markup}
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$prefix_sub_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && rgar( $first_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $first_input, 'isHidden' ) ) {
|
||||
$first_markup = "<span id='{$field_id}_3_container' class='name_first gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' value='{$first}' {$first_tabindex} {$disabled_text} {$first_aria_attributes} {$first_placeholder_attribute} {$first_autocomplete} {$this->maybe_add_aria_describedby( $first_input, $field_id, $this['formId'] )}/>
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$first_name_sub_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && ( ! isset( $middle_input['isHidden'] ) || rgar( $middle_input, 'isHidden' ) ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ( isset( $middle_input['isHidden'] ) && $middle_input['isHidden'] == false ) ) {
|
||||
$middle_markup = "<span id='{$field_id}_4_container' class='name_middle gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<input type='text' name='input_{$id}.4' id='{$field_id}_4' value='{$middle}' {$middle_tabindex} {$disabled_text} {$middle_aria_attributes} {$middle_placeholder_attribute} {$middle_autocomplete} {$this->maybe_add_aria_describedby( $middle_input, $field_id, $this['formId'] )}/>
|
||||
<label for='{$field_id}_4' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$middle_name_sub_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && rgar( $last_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $last_input, 'isHidden' ) ) {
|
||||
$last_markup = "<span id='{$field_id}_6_container' class='name_last gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<input type='text' name='input_{$id}.6' id='{$field_id}_6' value='{$last}' {$last_tabindex} {$disabled_text} {$last_aria_attributes} {$last_placeholder_attribute} {$last_autocomplete} {$this->maybe_add_aria_describedby( $last_input, $field_id, $this['formId'] )}/>
|
||||
<label for='{$field_id}_6' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$last_name_sub_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$style = ( $is_admin && rgar( $suffix_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $suffix_input, 'isHidden' ) ) {
|
||||
$suffix_select_class = isset( $suffix_input['choices'] ) && is_array( $suffix_input['choices'] ) ? 'name_suffix_select' : '';
|
||||
$suffix_markup = "<span id='{$field_id}_8_container' class='name_suffix {$suffix_select_class} gform-grid-col gform-grid-col--size-auto' {$style}>
|
||||
<input type='text' name='input_{$id}.8' id='{$field_id}_8' value='{$suffix}' {$suffix_tabindex} {$disabled_text} {$suffix_aria_attributes} {$suffix_placeholder_attribute} {$suffix_autocomplete} {$this->maybe_add_aria_describedby( $suffix_input, $field_id, $this['formId'] )}/>
|
||||
<label for='{$field_id}_8' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$suffix_sub_label}</label>
|
||||
</span>";
|
||||
}
|
||||
}
|
||||
$css_class = $this->get_css_class();
|
||||
|
||||
|
||||
return "<div class='ginput_complex{$class_suffix} ginput_container ginput_container--name {$css_class} gform-grid-row' id='{$field_id}'>
|
||||
{$prefix_markup}
|
||||
{$first_markup}
|
||||
{$middle_markup}
|
||||
{$last_markup}
|
||||
{$suffix_markup}
|
||||
</div>";
|
||||
case 'simple' :
|
||||
$value = esc_attr( $value );
|
||||
$class = esc_attr( $class );
|
||||
$tabindex = GFCommon::get_tabindex();
|
||||
$placeholder_attribute = GFCommon::get_field_placeholder_attribute( $this );
|
||||
|
||||
return "<div class='ginput_container ginput_container_name'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='text' value='{$value}' class='{$class}' {$tabindex} {$disabled_text} {$required_attribute} {$invalid_attribute} {$describedby_attribute} {$placeholder_attribute} />
|
||||
</div>";
|
||||
default :
|
||||
$first_tabindex = GFCommon::get_tabindex();
|
||||
$last_tabindex = GFCommon::get_tabindex();
|
||||
$first_name_sub_label = rgar( $first_input, 'customLabel' ) != '' ? $first_input['customLabel'] : gf_apply_filters( array( 'gform_name_first', $form_id ), esc_html__( 'First', 'gravityforms' ), $form_id );
|
||||
$last_name_sub_label = rgar( $last_input, 'customLabel' ) != '' ? $last_input['customLabel'] : gf_apply_filters( array( 'gform_name_last', $form_id ), esc_html__( 'Last', 'gravityforms' ), $form_id );
|
||||
if ( $is_sub_label_above ) {
|
||||
$first_markup = '';
|
||||
$style = ( $is_admin && rgar( $first_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $first_input, 'isHidden' ) ) {
|
||||
$first_markup = "<span id='{$field_id}_3_container' class='name_first gform-grid-col' {$style}>
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$first_name_sub_label}</label>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' value='{$first}' {$first_tabindex} {$disabled_text} {$first_aria_attributes} {$first_placeholder_attribute} />
|
||||
</span>";
|
||||
}
|
||||
|
||||
$last_markup = '';
|
||||
$style = ( $is_admin && rgar( $last_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $last_input, 'isHidden' ) ) {
|
||||
$last_markup = "<span id='{$field_id}_6_container' class='name_last gform-grid-col' {$style}>
|
||||
<label for='{$field_id}_6' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>" . $last_name_sub_label . "</label>
|
||||
<input type='text' name='input_{$id}.6' id='{$field_id}_6' value='{$last}' {$last_tabindex} {$disabled_text} {$last_aria_attributes} {$last_placeholder_attribute} />
|
||||
</span>";
|
||||
}
|
||||
} else {
|
||||
$first_markup = '';
|
||||
$style = ( $is_admin && rgar( $first_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $first_input, 'isHidden' ) ) {
|
||||
$first_markup = "<span id='{$field_id}_3_container' class='name_first gform-grid-col' {$style}>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' value='{$first}' {$first_tabindex} {$disabled_text} {$first_aria_attributes} {$first_placeholder_attribute} />
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$first_name_sub_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$last_markup = '';
|
||||
$style = ( $is_admin && rgar( $last_input, 'isHidden' ) ) ? "style='display:none;'" : '';
|
||||
if ( $is_admin || ! rgar( $last_input, 'isHidden' ) ) {
|
||||
$last_markup = "<span id='{$field_id}_6_container' class='name_last gform-grid-col' {$style}>
|
||||
<input type='text' name='input_{$id}.6' id='{$field_id}_6' value='{$last}' {$last_tabindex} {$disabled_text} {$last_aria_attributes} {$last_placeholder_attribute} />
|
||||
<label for='{$field_id}_6' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$last_name_sub_label}</label>
|
||||
</span>";
|
||||
}
|
||||
}
|
||||
|
||||
$css_class = $this->get_css_class();
|
||||
|
||||
return "<div class='ginput_complex{$class_suffix} ginput_container ginput_container--name {$css_class} gform-grid-row' id='{$field_id}'>
|
||||
{$first_markup}
|
||||
{$last_markup}
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CSS class to be used by the field input.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GF_Field_Name::get_field_input()
|
||||
* @uses GFFormsModel::get_input()
|
||||
*
|
||||
* @return string The CSS class to use for the field.
|
||||
*/
|
||||
public function get_css_class() {
|
||||
|
||||
$prefix_input = GFFormsModel::get_input( $this, $this->id . '.2' );
|
||||
$first_input = GFFormsModel::get_input( $this, $this->id . '.3' );
|
||||
$middle_input = GFFormsModel::get_input( $this, $this->id . '.4' );
|
||||
$last_input = GFFormsModel::get_input( $this, $this->id . '.6' );
|
||||
$suffix_input = GFFormsModel::get_input( $this, $this->id . '.8' );
|
||||
|
||||
$css_class = '';
|
||||
$visible_input_count = 0;
|
||||
|
||||
if ( $prefix_input && ! rgar( $prefix_input, 'isHidden' ) ) {
|
||||
$visible_input_count++;
|
||||
$css_class .= 'has_prefix ';
|
||||
} else {
|
||||
$css_class .= 'no_prefix ';
|
||||
}
|
||||
|
||||
if ( $first_input && ! rgar( $first_input, 'isHidden' ) ) {
|
||||
$visible_input_count++;
|
||||
$css_class .= 'has_first_name ';
|
||||
} else {
|
||||
$css_class .= 'no_first_name ';
|
||||
}
|
||||
|
||||
if ( $middle_input && ! rgar( $middle_input, 'isHidden' ) ) {
|
||||
$visible_input_count++;
|
||||
$css_class .= 'has_middle_name ';
|
||||
} else {
|
||||
$css_class .= 'no_middle_name ';
|
||||
}
|
||||
|
||||
if ( $last_input && ! rgar( $last_input, 'isHidden' ) ) {
|
||||
$visible_input_count++;
|
||||
$css_class .= 'has_last_name ';
|
||||
} else {
|
||||
$css_class .= 'no_last_name ';
|
||||
}
|
||||
|
||||
if ( $suffix_input && ! rgar( $suffix_input, 'isHidden' ) ) {
|
||||
$visible_input_count++;
|
||||
$css_class .= 'has_suffix ';
|
||||
} else {
|
||||
$css_class .= 'no_suffix ';
|
||||
}
|
||||
|
||||
$css_class .= "gf_name_has_{$visible_input_count} ginput_container_name ";
|
||||
|
||||
return trim( $css_class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the field markup to be used for the name prefix.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GF_Field_Name::get_field_input()
|
||||
* @uses GFCommon::get_input_placeholder_value()
|
||||
* @uses GFCommon::get_input_placeholder_attribute()
|
||||
*
|
||||
* @param array $input The input item choices.
|
||||
* @param int $id The ID of the name field.
|
||||
* @param int $field_id The field ID of the name field.
|
||||
* @param string $value The value to be used in the prefix field item.
|
||||
* @param string $disabled_text The text to be used if the prefix field item is disabled.
|
||||
* @param int $tabindex The tab index of the prefix field item.
|
||||
*
|
||||
* @return string The field HTML markup.
|
||||
*/
|
||||
public function get_name_prefix_field( $input, $id, $field_id, $value, $disabled_text, $tabindex ) {
|
||||
|
||||
$autocomplete = $this->enableAutocomplete ? $this->get_input_autocomplete_attribute( $input ) : '';
|
||||
$aria_attributes = $this->get_aria_attributes( array( $input['id'] => $value ), '2' );
|
||||
$describedby_attribute = $this->get_aria_describedby();
|
||||
|
||||
if ( isset( $input['choices'] ) && is_array( $input['choices'] ) ) {
|
||||
$placeholder_value = GFCommon::get_input_placeholder_value( $input );
|
||||
$options = "<option value=''>{$placeholder_value}</option>";
|
||||
$value_enabled = rgar( $input, 'enableChoiceValue' );
|
||||
foreach ( $input['choices'] as $choice ) {
|
||||
$choice_value = $value_enabled ? $choice['value'] : $choice['text'];
|
||||
$is_selected_by_default = rgar( $choice, 'isSelected' );
|
||||
$is_this_choice_selected = empty( $value ) ? $is_selected_by_default : strtolower( $choice_value ) == strtolower( $value );
|
||||
$selected = $is_this_choice_selected ? "selected='selected'" : '';
|
||||
$options .= "<option value='{$choice_value}' {$selected}>{$choice['text']}</option>";
|
||||
}
|
||||
|
||||
$markup = "<select name='input_{$id}.2' id='{$field_id}_2' {$tabindex} {$disabled_text} {$autocomplete} {$aria_attributes} {$this->maybe_add_aria_describedby( $input, $field_id, $this['formId'] )}>
|
||||
{$options}
|
||||
</select>";
|
||||
|
||||
} else {
|
||||
$placeholder_attribute = GFCommon::get_input_placeholder_attribute( $input );
|
||||
|
||||
$markup = "<input type='text' name='input_{$id}.2' id='{$field_id}_2' value='{$value}' {$tabindex} {$disabled_text} {$placeholder_attribute} {$autocomplete} {$this->maybe_add_aria_describedby( $input, $field_id, $this['formId'] )}/>";
|
||||
}
|
||||
|
||||
return $markup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field value to be displayed on the entry detail page.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFCommon::get_lead_field_display()
|
||||
* @uses GF_Field_Name::$id
|
||||
*
|
||||
* @param array|string $value The value of the field input.
|
||||
* @param string $currency Not used.
|
||||
* @param bool $use_text Not used.
|
||||
* @param string $format The format to output the value. Defaults to 'html'.
|
||||
* @param string $media Not used.
|
||||
*
|
||||
* @return array|string The value to be displayed on the entry detail page.
|
||||
*/
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$prefix = trim( rgget( $this->id . '.2', $value ) );
|
||||
$first = trim( rgget( $this->id . '.3', $value ) );
|
||||
$middle = trim( rgget( $this->id . '.4', $value ) );
|
||||
$last = trim( rgget( $this->id . '.6', $value ) );
|
||||
$suffix = trim( rgget( $this->id . '.8', $value ) );
|
||||
|
||||
$name = $prefix;
|
||||
$name .= ! empty( $name ) && ! empty( $first ) ? " $first" : $first;
|
||||
$name .= ! empty( $name ) && ! empty( $middle ) ? " $middle" : $middle;
|
||||
$name .= ! empty( $name ) && ! empty( $last ) ? " $last" : $last;
|
||||
$name .= ! empty( $name ) && ! empty( $suffix ) ? " $suffix" : $suffix;
|
||||
|
||||
$return = $name;
|
||||
} else {
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
if ( $format === 'html' ) {
|
||||
$return = esc_html( $return );
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the field settings choices.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDetail::add_field()
|
||||
* @used-by GFFormsModel::sanitize_settings()
|
||||
* @uses GF_Field::sanitize_settings()
|
||||
* @uses GF_Field::sanitize_settings_choices()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
if ( is_array( $this->inputs ) ) {
|
||||
foreach ( $this->inputs as &$input ) {
|
||||
if ( isset ( $input['choices'] ) && is_array( $input['choices'] ) ) {
|
||||
$input['choices'] = $this->sanitize_settings_choices( $input['choices'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field value to be used when exporting.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFExport::start_export()
|
||||
* @used-by GFAddOn::get_field_value()
|
||||
* @used-by GFAddOn::get_full_name()
|
||||
*
|
||||
* @param array $entry The Entry Object.
|
||||
* @param string $input_id The input ID to format. Defaults to empty string. If not set, uses t
|
||||
* @param bool $use_text Not used.
|
||||
* @param bool $is_csv Not used.
|
||||
*
|
||||
* @return string The field value.
|
||||
*/
|
||||
public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
|
||||
if ( empty( $input_id ) ) {
|
||||
$input_id = $this->id;
|
||||
}
|
||||
|
||||
if ( absint( $input_id ) == $input_id ) {
|
||||
// If field is simple (one input), simply return full content.
|
||||
$name = rgar( $entry, $input_id );
|
||||
if ( ! empty( $name ) ) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
// Complex field (multiple inputs). Join all pieces and create name.
|
||||
$prefix = trim( rgar( $entry, $input_id . '.2' ) );
|
||||
$first = trim( rgar( $entry, $input_id . '.3' ) );
|
||||
$middle = trim( rgar( $entry, $input_id . '.4' ) );
|
||||
$last = trim( rgar( $entry, $input_id . '.6' ) );
|
||||
$suffix = trim( rgar( $entry, $input_id . '.8' ) );
|
||||
|
||||
$name = $prefix;
|
||||
$name .= ! empty( $name ) && ! empty( $first ) ? ' ' . $first : $first;
|
||||
$name .= ! empty( $name ) && ! empty( $middle ) ? ' ' . $middle : $middle;
|
||||
$name .= ! empty( $name ) && ! empty( $last ) ? ' ' . $last : $last;
|
||||
$name .= ! empty( $name ) && ! empty( $suffix ) ? ' ' . $suffix : $suffix;
|
||||
|
||||
return $name;
|
||||
} else {
|
||||
|
||||
return rgar( $entry, $input_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the "for" attribute in the field label. Inputs are only allowed one label (a11y) and the inputs already have labels.
|
||||
*
|
||||
* @since 2.4
|
||||
* @access public
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_first_input_id( $form ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the sub-filters for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_sub_filters() {
|
||||
$sub_filters = array();
|
||||
|
||||
if ( $this->nameFormat == 'simple' ) {
|
||||
return $sub_filters;
|
||||
}
|
||||
|
||||
$inputs = $this->inputs;
|
||||
|
||||
foreach ( (array) $inputs as $input ) {
|
||||
if ( rgar( $input, 'isHidden' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sub_filters[] = array(
|
||||
'key' => rgar( $input, 'id' ),
|
||||
'text' => rgar( $input, 'customLabel', rgar( $input, 'label' ) ),
|
||||
'preventMultiple' => false,
|
||||
'operators' => $this->get_filter_operators(),
|
||||
);
|
||||
}
|
||||
|
||||
return $sub_filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
}
|
||||
|
||||
// Registers the Name field with the field framework.
|
||||
GF_Fields::register( new GF_Field_Name() );
|
||||
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Number extends GF_Field {
|
||||
|
||||
public $type = 'number';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Number', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to enter a number.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--numbers-alt';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'number_format_setting',
|
||||
'range_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'calculation_setting',
|
||||
'autocomplete_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
|
||||
|
||||
$value = $this->get_input_value_submission( 'input_' . $this->id, $this->inputName, $field_values, $get_from_post_global_var );
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$value = array_map( 'trim', $value );
|
||||
foreach ( $value as &$v ) {
|
||||
$v = trim( $v );
|
||||
$v = $this->clean_value( $v );
|
||||
}
|
||||
} else {
|
||||
if ( is_string( $value ) ) {
|
||||
$value = trim( $value );
|
||||
$value = $this->clean_value( $value );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the POST value is in the correct number format.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return bool|float|string
|
||||
*/
|
||||
public function clean_value( $value ) {
|
||||
|
||||
if ( $this->numberFormat == 'currency' ) {
|
||||
$currency = new RGCurrency( GFCommon::get_currency() );
|
||||
$value = $currency->to_number( $value );
|
||||
} elseif ( $this->numberFormat == 'decimal_comma' ) {
|
||||
$value = GFCommon::clean_number( $value, 'decimal_comma' );
|
||||
} elseif ( $this->numberFormat == 'decimal_dot' ) {
|
||||
$value = GFCommon::clean_number( $value, 'decimal_dot' );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
|
||||
// The POST value has already been converted from currency or decimal_comma to decimal_dot and then cleaned in get_field_value().
|
||||
$value = GFCommon::maybe_add_leading_zero( $value );
|
||||
|
||||
// Raw value will be tested against the is_numeric() function to make sure it is in the right format.
|
||||
// If the POST value is an array then the field is inside a repeater so use $value.
|
||||
$raw_value = isset( $_POST[ 'input_' . $this->id ] ) && ! is_array( $_POST[ 'input_' . $this->id ] ) ? GFCommon::maybe_add_leading_zero( rgpost( 'input_' . $this->id ) ) : $value;
|
||||
|
||||
$has_raw_value = ! rgblank( trim( $raw_value ) );
|
||||
$requires_valid_number = $has_raw_value && ! $this->has_calculation();
|
||||
$is_valid_number = $this->validate_range( $value ) && GFCommon::is_numeric( $raw_value, $this->numberFormat );
|
||||
|
||||
if ( $requires_valid_number && ! $is_valid_number ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? $this->get_range_message() : $this->errorMessage;
|
||||
} elseif ( $this->type == 'quantity' && $has_raw_value ) {
|
||||
if ( intval( $value ) != $value ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'Please enter a valid quantity. Quantity cannot contain decimals.', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( ( ! is_numeric( $value ) || intval( $value ) != floatval( $value ) || intval( $value ) < 0 ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'Please enter a valid quantity', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the given value considered empty for this field.
|
||||
*
|
||||
* Adds a check to the parent method because a value of 0 returns a false positive.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_value_empty( $value ) {
|
||||
$empty = parent::is_value_empty( $value );
|
||||
|
||||
if ( $empty && ! rgblank( $value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the range of the number according to the field settings.
|
||||
*
|
||||
* @param string $value A decimal_dot formatted string
|
||||
*
|
||||
* @return true|false True on valid or false on invalid
|
||||
*/
|
||||
private function validate_range( $value ) {
|
||||
|
||||
if ( ! GFCommon::is_numeric( $value, 'decimal_dot' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$numeric_min = $this->numberFormat == 'decimal_comma' ? GFCommon::clean_number( $this->rangeMin, 'decimal_comma' ) : $this->rangeMin;
|
||||
$numeric_max = $this->numberFormat == 'decimal_comma' ? GFCommon::clean_number( $this->rangeMax, 'decimal_comma' ) : $this->rangeMax;
|
||||
|
||||
if ( ( is_numeric( $numeric_min ) && $value < $numeric_min ) ||
|
||||
( is_numeric( $numeric_max ) && $value > $numeric_max )
|
||||
) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_range_message() {
|
||||
$min = $this->rangeMin;
|
||||
$max = $this->rangeMax;
|
||||
|
||||
$numeric_min = $min;
|
||||
$numeric_max = $max;
|
||||
|
||||
if ( $this->numberFormat == 'decimal_comma' ) {
|
||||
$numeric_min = empty( $min ) ? '' : GFCommon::clean_number( $min, 'decimal_comma', '' );
|
||||
$numeric_max = empty( $max ) ? '' : GFCommon::clean_number( $max, 'decimal_comma', '' );
|
||||
}
|
||||
|
||||
$message = '';
|
||||
|
||||
if ( is_numeric( $numeric_min ) && is_numeric( $numeric_max ) ) {
|
||||
$message = sprintf( esc_html__( 'Please enter a number from %1$s to %2$s.', 'gravityforms' ), "<strong>$min</strong>", "<strong>$max</strong>" );
|
||||
} elseif ( is_numeric( $numeric_min ) ) {
|
||||
$message = sprintf( esc_html__( 'Please enter a number greater than or equal to %s.', 'gravityforms' ), "<strong>$min</strong>" );
|
||||
} elseif ( is_numeric( $numeric_max ) ) {
|
||||
$message = sprintf( esc_html__( 'Please enter a number less than or equal to %s.', 'gravityforms' ), "<strong>$max</strong>" );
|
||||
} elseif ( $this->failed_validation ) {
|
||||
$message = esc_html__( 'Please enter a valid number.', 'gravityforms' );
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$form_id = $form['id'];
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$size = $this->size;
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$instruction = '';
|
||||
$read_only = '';
|
||||
|
||||
if ( ! $is_entry_detail && ! $is_form_editor ) {
|
||||
|
||||
if ( $this->has_calculation() ) {
|
||||
|
||||
// calculation-enabled fields should be read only
|
||||
$read_only = 'readonly="readonly"';
|
||||
|
||||
} else {
|
||||
|
||||
$message = $this->get_range_message();
|
||||
$validation_class = $this->failed_validation ? 'validation_message' : '';
|
||||
|
||||
if ( ! $this->failed_validation && ! empty( $message ) && empty( $this->errorMessage ) ) {
|
||||
$instruction = "<div class='gfield_description instruction $validation_class' id='gfield_instruction_{$this->formId}_{$this->id}'>" . $message . '</div>';
|
||||
}
|
||||
}
|
||||
} elseif ( rgget( 'view' ) == 'entry' ) {
|
||||
$value = GFCommon::format_number( $value, $this->numberFormat, rgar( $entry, 'currency' ) );
|
||||
}
|
||||
|
||||
$html_input_type = ! $this->has_calculation() && ( $this->numberFormat != 'currency' && $this->numberFormat != 'decimal_comma' ) ? 'number' : 'text'; // chrome does not allow number fields to have commas, calculations and currency values display numbers with commas
|
||||
$step_attr = "step='any'";
|
||||
|
||||
$min = $this->rangeMin;
|
||||
$max = $this->rangeMax;
|
||||
|
||||
$min_attr = is_numeric( $min ) ? "min='{$min}'" : '';
|
||||
$max_attr = is_numeric( $max ) ? "max='{$max}'" : '';
|
||||
|
||||
$include_thousands_sep = apply_filters( 'gform_include_thousands_sep_pre_format_number', $html_input_type == 'text', $this );
|
||||
$value = GFCommon::format_number( $value, $this->numberFormat, rgar( $entry, 'currency' ), $include_thousands_sep );
|
||||
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
|
||||
$range_message = $this->get_range_message();
|
||||
$describedby_extra_id = empty( $range_message ) ? array() : array( "gfield_instruction_{$this->formId}_{$this->id}" );
|
||||
$aria_describedby = $this->get_aria_describedby( $describedby_extra_id );
|
||||
|
||||
$autocomplete_attribute = $this->enableAutocomplete ? $this->get_field_autocomplete_attribute() : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$input = sprintf( "<div class='ginput_container ginput_container_number'><input name='input_%d' id='%s' type='{$html_input_type}' {$step_attr} {$min_attr} {$max_attr} value='%s' class='%s' {$tabindex} {$read_only} %s %s %s %s %s %s/>%s</div>", $id, $field_id, esc_attr( $value ), esc_attr( $class ), $disabled_text, $placeholder_attribute, $required_attribute, $invalid_attribute, $aria_describedby, $autocomplete_attribute, $instruction );
|
||||
return $input;
|
||||
}
|
||||
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
$include_thousands_sep = apply_filters( 'gform_include_thousands_sep_pre_format_number', true, $this );
|
||||
|
||||
return GFCommon::format_number( $value, $this->numberFormat, rgar( $entry, 'currency' ), $include_thousands_sep );
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
$include_thousands_sep = apply_filters( 'gform_include_thousands_sep_pre_format_number', $use_text, $this );
|
||||
|
||||
return GFCommon::format_number( $value, $this->numberFormat, $currency, $include_thousands_sep );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets merge tag values.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::format_number()
|
||||
*
|
||||
* @param array|string $value The value of the input.
|
||||
* @param string $input_id The input ID to use.
|
||||
* @param array $entry The Entry Object.
|
||||
* @param array $form The Form Object
|
||||
* @param string $modifier The modifier passed.
|
||||
* @param array|string $raw_value The raw value of the input.
|
||||
* @param bool $url_encode If the result should be URL encoded.
|
||||
* @param bool $esc_html If the HTML should be escaped.
|
||||
* @param string $format The format that the value should be.
|
||||
* @param bool $nl2br If the nl2br function should be used.
|
||||
*
|
||||
* @return string The processed merge tag.
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
$include_thousands_sep = ! in_array( 'value', $this->get_modifiers() );
|
||||
|
||||
/**
|
||||
* Filters if the thousands separator should be used when displaying the a number field result.
|
||||
*
|
||||
* @since 1.9.5
|
||||
*
|
||||
* @param bool $include_thousands_sep If the modifier passed in the merge tag is not 'value', false. Otherwise, true.
|
||||
* @param GF_Field_Number $this An instance of this class.
|
||||
*/
|
||||
$include_thousands_sep = apply_filters( 'gform_include_thousands_sep_pre_format_number', $include_thousands_sep, $this );
|
||||
|
||||
$formatted_value = GFCommon::format_number( $value, $this->numberFormat, rgar( $entry, 'currency' ), $include_thousands_sep );
|
||||
|
||||
return $url_encode ? urlencode( $formatted_value ) : $formatted_value;
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
if ( $this->has_calculation() ) {
|
||||
if ( empty( $lead ) ) {
|
||||
$lead = GFFormsModel::get_lead( $lead_id );
|
||||
}
|
||||
|
||||
$value = GFCommon::calculate( $this, $form, $lead );
|
||||
|
||||
if ( $this->numberFormat !== 'currency' ) {
|
||||
$value = GFCommon::round_number( $value, $this->calculationRounding );
|
||||
}
|
||||
|
||||
// Return the value as a string when it is zero and a calc so that the "==" comparison done when checking if the field has changed isn't treated as false.
|
||||
if ( $value == 0 ) {
|
||||
$value = '0';
|
||||
}
|
||||
} else {
|
||||
$value = $this->clean_number( GFCommon::maybe_add_leading_zero( $value ) );
|
||||
}
|
||||
|
||||
return $this->sanitize_entry_value( $value, $form['id'] );
|
||||
}
|
||||
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$this->enableCalculation = (bool) $this->enableCalculation;
|
||||
|
||||
if ( ! in_array( $this->numberFormat, array( 'currency', 'decimal_comma', 'decimal_dot' ) ) ) {
|
||||
$this->numberFormat = GFCommon::is_currency_decimal_dot() ? 'decimal_dot' : 'decimal_comma';
|
||||
}
|
||||
|
||||
$this->rangeMin = $this->clean_number( $this->rangeMin );
|
||||
$this->rangeMax = $this->clean_number( $this->rangeMax );
|
||||
|
||||
if ( $this->numberFormat == 'decimal_comma' ) {
|
||||
$this->rangeMin = GFCommon::format_number( $this->rangeMin, 'decimal_comma' );
|
||||
$this->rangeMax = GFCommon::format_number( $this->rangeMax, 'decimal_comma' );
|
||||
}
|
||||
}
|
||||
|
||||
public function clean_number( $value ) {
|
||||
|
||||
if ( $this->numberFormat == 'currency' ) {
|
||||
return GFCommon::to_number( $value );
|
||||
} else {
|
||||
return GFCommon::clean_number( $value, $this->numberFormat );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Number() );
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Option extends GF_Field {
|
||||
|
||||
public $type = 'option';
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'product_field_setting',
|
||||
'option_field_type_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'label_placement_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Option', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to select options for products created by a product field.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--misc';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Option() );
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_Page extends GF_Field {
|
||||
|
||||
public $type = 'page';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Page', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows multi-page forms.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--page';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'next_button_setting',
|
||||
'previous_button_setting',
|
||||
'css_class_setting',
|
||||
'conditional_logic_page_setting',
|
||||
'conditional_logic_nextbutton_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_field_content( $value, $force_frontend_label, $form ) {
|
||||
$admin_buttons = $this->get_admin_buttons();
|
||||
$field_content = "{$admin_buttons} <label class='gfield_label'> </label><div class='gf-pagebreak-inline gf-pagebreak'>" . esc_html__( 'Page Break', 'gravityforms' ) . '</div>';
|
||||
return $field_content;
|
||||
}
|
||||
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
if ( $this->nextButton ) {
|
||||
if ( isset( $this->nextButton['imageUrl'] ) ) {
|
||||
$this->nextButton['imageUrl'] = wp_strip_all_tags( $this->nextButton['imageUrl'] );
|
||||
}
|
||||
$allowed_tags = wp_kses_allowed_html( 'post' );
|
||||
$this->nextButton['text'] = wp_kses( $this->nextButton['text'], $allowed_tags );
|
||||
$this->nextButton['type'] = wp_strip_all_tags( $this->nextButton['type'] );
|
||||
if ( isset( $this->nextButton['conditionalLogic'] ) && is_array( $this->nextButton['conditionalLogic'] ) ) {
|
||||
$this->nextButton['conditionalLogic'] = $this->sanitize_settings_conditional_logic( $this->nextButton['conditionalLogic'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Page() );
|
||||
@@ -0,0 +1,451 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_Password extends GF_Field {
|
||||
|
||||
public $type = 'password';
|
||||
|
||||
private static $passwords = array();
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Password', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows the user to enter a password and confirm it. The password will be masked with blobs or asterisks.', 'gravityforms' );
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'input_placeholders_setting',
|
||||
'sub_label_placement_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'password_strength_setting',
|
||||
'password_visibility_setting',
|
||||
'password_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--password';
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array(); // this button is conditionally added in the form detail page
|
||||
}
|
||||
|
||||
public function get_entry_inputs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) || ! $this->is_confirm_input_enabled() ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$password = rgpost( 'input_' . $this->id );
|
||||
$confirm = rgpost( 'input_' . $this->id . '_2' );
|
||||
if ( $this->is_confirm_input_enabled() && $password != $confirm ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Your passwords do not match.', 'gravityforms' );
|
||||
} elseif ( $this->passwordStrengthEnabled && ! empty( $this->minPasswordStrength ) && ! empty( $password ) ) {
|
||||
|
||||
$strength = rgpost('input_' . $this->id . '_strength' );
|
||||
|
||||
if ( empty( $strength ) ) {
|
||||
$strength = $this->get_password_strength( $password );
|
||||
}
|
||||
|
||||
$levels = array( 'short' => 1, 'bad' => 2, 'good' => 3, 'strong' => 4 );
|
||||
if ( rgar( $levels, $strength, 0 ) < $levels[ $this->minPasswordStrength ] ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? sprintf( esc_html__( 'Your password does not meet the required strength. %sHint: To make it stronger, use upper and lower case letters, numbers and symbols like ! " ? $ %% ^ & ).', 'gravityforms' ), '<br />' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the password score using PHP when not passed by JS.
|
||||
*
|
||||
* @since 2.4.11
|
||||
*
|
||||
* @see gravityforms.js gformPasswordStrength() JS code
|
||||
*
|
||||
* @param string $password The password that should be checked.
|
||||
*
|
||||
* @return string blank|short|bad|good|strong
|
||||
*/
|
||||
protected function get_password_strength( $password = '' ) {
|
||||
|
||||
$symbol_size = 0;
|
||||
$strlen = GFCommon::safe_strlen( $password );
|
||||
|
||||
if ( 0 >= $strlen ) {
|
||||
return 'blank';
|
||||
}
|
||||
|
||||
if ( $strlen < 4 ) {
|
||||
return 'short';
|
||||
}
|
||||
|
||||
if ( preg_match( '/[ 0 - 9 ] /', $password ) ) {
|
||||
$symbol_size += 10;
|
||||
}
|
||||
|
||||
if ( preg_match( '/[ a - z ] /', $password ) ) {
|
||||
$symbol_size += 26;
|
||||
}
|
||||
|
||||
if ( preg_match( '/[ A - Z ] /', $password ) ) {
|
||||
$symbol_size += 26;
|
||||
}
|
||||
|
||||
if ( preg_match( '/[^a - zA - Z0 - 9]/', $password ) ) {
|
||||
$symbol_size += 31;
|
||||
}
|
||||
|
||||
$natLog = log( pow( $symbol_size, $strlen ) );
|
||||
$score = $natLog / log( 2 );
|
||||
|
||||
if ( 40 > $score ) {
|
||||
return 'bad';
|
||||
}
|
||||
|
||||
if ( 56 > $score ) {
|
||||
return 'good';
|
||||
}
|
||||
|
||||
return 'strong';
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$value = array_values( $value );
|
||||
}
|
||||
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_entry_detail || $is_form_editor;
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $this->is_confirm_input_enabled() ? '' : $size . $class_suffix; // Size only applies when confirmation is disabled.
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$form_sub_label_placement = rgar( $form, 'subLabelPlacement' );
|
||||
$field_sub_label_placement = $this->subLabelPlacement;
|
||||
$is_sub_label_above = $field_sub_label_placement == 'above' || ( empty( $field_sub_label_placement ) && $form_sub_label_placement == 'above' );
|
||||
$sub_label_class = $field_sub_label_placement == 'hidden_label' ? "hidden_sub_label screen-reader-text" : '';
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$first_tabindex = $this->get_tabindex();
|
||||
$last_tabindex = $this->get_tabindex();
|
||||
|
||||
$strength_style = ! $this->passwordStrengthEnabled ? "style='display:none;'" : '';
|
||||
$strength_indicator_label = esc_html__( 'Strength indicator', 'gravityforms' );
|
||||
$strength = $this->passwordStrengthEnabled || $is_admin ? "<div id='{$field_id}_strength_indicator' class='gfield_password_strength' {$strength_style}>
|
||||
{$strength_indicator_label}
|
||||
</div>
|
||||
<input type='hidden' class='gform_hidden' id='{$field_id}_strength' name='input_{$id}_strength' />" : '';
|
||||
|
||||
$action = ! $is_admin ? "gformShowPasswordStrength(\"$field_id\");" : '';
|
||||
$onchange = $this->passwordStrengthEnabled ? "onchange='{$action}'" : '';
|
||||
$onkeyup = $this->passwordStrengthEnabled ? "onkeyup='{$action}'" : '';
|
||||
|
||||
$confirmation_value = rgpost( 'input_' . $id . '_2' );
|
||||
|
||||
$password_value = is_array( $value ) ? $value[0] : $value;
|
||||
$password_value = esc_attr( $password_value );
|
||||
$confirmation_value = esc_attr( $confirmation_value );
|
||||
|
||||
$enter_password_field_input = GFFormsModel::get_input( $this, $this->id . '' );
|
||||
$confirm_password_field_input = GFFormsModel::get_input( $this, $this->id . '.2' );
|
||||
|
||||
$enter_password_label = rgar( $enter_password_field_input, 'customLabel' ) != '' ? $enter_password_field_input['customLabel'] : esc_html__( 'Enter Password', 'gravityforms' );
|
||||
$enter_password_label = gf_apply_filters( array( 'gform_password', $form_id ), $enter_password_label, $form_id );
|
||||
|
||||
$confirm_password_label = rgar( $confirm_password_field_input, 'customLabel' ) != '' ? $confirm_password_field_input['customLabel'] : esc_html__( 'Confirm Password', 'gravityforms' );
|
||||
$confirm_password_label = gf_apply_filters( array( 'gform_password_confirm', $form_id ), $confirm_password_label, $form_id );
|
||||
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
|
||||
$enter_password_placeholder_attribute = GFCommon::get_input_placeholder_attribute( $enter_password_field_input );
|
||||
$confirm_password_placeholder_attribute = GFCommon::get_input_placeholder_attribute( $confirm_password_field_input );
|
||||
|
||||
$visibility_toggle_style = ! $this->passwordVisibilityEnabled ? " style='display:none;'" : '';
|
||||
$enter_password_toggle = $this->passwordVisibilityEnabled || $is_admin ? "<button type='button' class='gform_show_password gform-theme-button gform-theme-button--simple' onclick='javascript:gformToggleShowPassword(\"{$field_id}\");' aria-live='polite' aria-label='" . esc_attr__( 'Show Password', 'gravityforms' ) . "' data-label-show='" . esc_attr__( 'Show Password', 'gravityforms' ) . "' data-label-hide='" . esc_attr__( 'Hide Password', 'gravityforms' ) . "'{$visibility_toggle_style}><span class='dashicons dashicons-hidden' aria-hidden='true'></span></button>" : "";
|
||||
$confirm_password_toggle = $this->passwordVisibilityEnabled || $is_admin ? "<button type='button' class='gform_show_password gform-theme-button gform-theme-button--simple' onclick='javascript:gformToggleShowPassword(\"{$field_id}_2\");' aria-live='polite' aria-label='" . esc_attr__( 'Show Password', 'gravityforms' ) . "' data-label-show='" . esc_attr__( 'Show Password', 'gravityforms' ) . "' data-label-hide='" . esc_attr__( 'Hide Password', 'gravityforms' ) . "'{$visibility_toggle_style}><span class='dashicons dashicons-hidden' aria-hidden='true'></span></button>" : "";
|
||||
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
if ( $is_form_editor ) {
|
||||
$confirm_style = $this->is_confirm_input_enabled() ? '' : "style='display:none;'";
|
||||
|
||||
if ( $is_sub_label_above ) {
|
||||
return "<div class='ginput_complex$class_suffix ginput_container ginput_container_password gform-grid-row' id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_password ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}' {$confirm_style}>{$enter_password_label}</label>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}' id='{$field_id}' {$onkeyup} {$onchange} value='{$password_value}' {$first_tabindex} {$enter_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
{$enter_password_toggle}
|
||||
</span>
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_password ginput_right gform-grid-col gform-grid-col--size-auto' {$confirm_style}>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_password_label}</label>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}_2' id='{$field_id}_2' {$onkeyup} {$onchange} value='{$confirmation_value}' {$last_tabindex} {$confirm_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
{$confirm_password_toggle}
|
||||
</span>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>{$strength}";
|
||||
} else {
|
||||
return "<div class='ginput_complex$class_suffix ginput_container ginput_container_password gform-grid-row' id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_password ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}' id='{$field_id}' {$onkeyup} {$onchange} value='{$password_value}' {$first_tabindex} {$enter_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
{$enter_password_toggle}
|
||||
</span>
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}' {$confirm_style}>{$enter_password_label}</label>
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_password ginput_right gform-grid-col gform-grid-col--size-auto' {$confirm_style}>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}_2' id='{$field_id}_2' {$onkeyup} {$onchange} value='{$confirmation_value}' {$last_tabindex} {$confirm_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
{$confirm_password_toggle}
|
||||
</span>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_password_label}</label>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>{$strength}";
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->is_confirm_input_enabled() ) {
|
||||
|
||||
if ( $is_sub_label_above ) {
|
||||
return "<div class='ginput_complex$class_suffix ginput_container ginput_container_password gform-grid-row' id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_password ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$enter_password_label}</label>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}' id='{$field_id}' {$onkeyup} {$onchange} value='{$password_value}' {$first_tabindex} {$enter_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text} {$aria_describedby}/>
|
||||
{$enter_password_toggle}
|
||||
</span>
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_password ginput_right gform-grid-col gform-grid-col--size-auto'>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_password_label}</label>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}_2' id='{$field_id}_2' {$onkeyup} {$onchange} value='{$confirmation_value}' {$last_tabindex} {$confirm_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
{$confirm_password_toggle}
|
||||
</span>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>{$strength}";
|
||||
} else {
|
||||
return "<div class='ginput_complex$class_suffix ginput_container ginput_container_password gform-grid-row' id='{$field_id}_container'>
|
||||
<span id='{$field_id}_1_container' class='ginput_password ginput_left gform-grid-col gform-grid-col--size-auto'>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}' id='{$field_id}' {$onkeyup} {$onchange} value='{$password_value}' {$first_tabindex} {$enter_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text} {$aria_describedby}/>
|
||||
{$enter_password_toggle}
|
||||
</span>
|
||||
<label for='{$field_id}' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$enter_password_label}</label>
|
||||
</span>
|
||||
<span id='{$field_id}_2_container' class='ginput_password ginput_right gform-grid-col gform-grid-col--size-auto'>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}_2' id='{$field_id}_2' {$onkeyup} {$onchange} value='{$confirmation_value}' {$last_tabindex} {$confirm_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
{$confirm_password_toggle}
|
||||
</span>
|
||||
<label for='{$field_id}_2' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$confirm_password_label}</label>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>{$strength}";
|
||||
}
|
||||
|
||||
} else {
|
||||
$class = esc_attr( $class );
|
||||
|
||||
return "<div class='ginput_container ginput_container_password'>
|
||||
<span id='{$field_id}_1_container' class='ginput_password {$size}'>
|
||||
<span class='password_input_container'>
|
||||
<input type='password' name='input_{$id}' id='{$field_id}' {$onkeyup} {$onchange} value='{$password_value}' {$first_tabindex} {$enter_password_placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>
|
||||
{$enter_password_toggle}
|
||||
</span>
|
||||
</span>
|
||||
<div class='gf_clear gf_clear_complex'></div>
|
||||
</div>{$strength}";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function get_field_label_class(){
|
||||
return 'gfield_label gform-field-label gfield_label_before_complex';
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
|
||||
/**
|
||||
* A filter to allow the password to be encrypted (default set to false)
|
||||
*
|
||||
* @param bool Whether to encrypt the Password field with true or false
|
||||
* @param array $form The Current Form Object
|
||||
*/
|
||||
$encrypt_password = apply_filters( 'gform_encrypt_password', false, $this, $form );
|
||||
if ( $encrypt_password ) {
|
||||
$value = GFCommon::openssl_encrypt( $value );
|
||||
GFFormsModel::set_openssl_encrypted_fields( $lead_id, $this->id );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.4.16
|
||||
*
|
||||
* @param $entry
|
||||
* @param $form
|
||||
*/
|
||||
public static function delete_passwords( $entry, $form ) {
|
||||
$password_fields = GFAPI::get_fields_by_type( $form, array( 'password' ) );
|
||||
|
||||
$field_ids = array();
|
||||
|
||||
$encrypted_fields = GFFormsModel::get_openssl_encrypted_fields( $entry['id'] );
|
||||
|
||||
foreach ( $password_fields as $password_field ) {
|
||||
$field_ids[] = $password_field->id;
|
||||
GFAPI::update_entry_field( $entry['id'], $password_field->id, '' );
|
||||
|
||||
$key = array_search( $password_field->id, $encrypted_fields );
|
||||
if ( $key !== false ) {
|
||||
unset( $encrypted_fields[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $encrypted_fields ) ) {
|
||||
gform_delete_meta( $entry['id'], '_openssl_encrypted_fields' );
|
||||
} else {
|
||||
gform_update_meta( $entry['id'], '_openssl_encrypted_fields', $encrypted_fields );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the "for" attribute in the field label.
|
||||
* Inputs are only allowed one label (a11y) and the inputs already have labels.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_first_input_id( $form ) {
|
||||
|
||||
return $this->is_confirm_input_enabled() ? '' : parent::get_first_input_id( $form );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Confirm Password input is enabled.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_confirm_input_enabled() {
|
||||
|
||||
// Get Confirm Password input.
|
||||
$confirm_input = GFFormsModel::get_input( $this, $this->id . '.2' );
|
||||
|
||||
return isset( $confirm_input['isHidden'] ) ? ! $confirm_input['isHidden'] : true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Passwords are not saved to the database and won't be available in the runtime $entry object unless we stash and
|
||||
* rehydrate them into the $entry object after it has been retrieved from the database.
|
||||
*
|
||||
* @since 2.4.16
|
||||
*
|
||||
* @param $form
|
||||
*/
|
||||
public static function stash_passwords( $form ) {
|
||||
foreach( $form['fields'] as $field ) {
|
||||
/* @var GF_Field $field */
|
||||
if ( $field->get_input_type() == 'password' ) {
|
||||
self::$passwords[ $field->id ] = $field->get_value_submission( rgpost( 'gform_field_values' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrate the stashed passwords back into the runtime $entry object that has just been saved and retrieved from the
|
||||
* database.
|
||||
*
|
||||
* @since 2.4.16
|
||||
*
|
||||
* @param $entry
|
||||
*
|
||||
* @return array $entry
|
||||
*/
|
||||
public static function hydrate_passwords( $entry ) {
|
||||
foreach( self::$passwords as $field_id => $password ) {
|
||||
$entry[ $field_id ] = $password;
|
||||
}
|
||||
// Reset passwords so they are not available for the next submission in multi-submission requests (only possible via API).
|
||||
self::$passwords = array();
|
||||
return $entry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Password() );
|
||||
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
|
||||
// If Gravity Forms isn't loaded, bail.
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Field_Phone
|
||||
*
|
||||
* Handles the behavior of Phone fields.
|
||||
*
|
||||
* @since Unknown
|
||||
*/
|
||||
class GF_Field_Phone extends GF_Field {
|
||||
|
||||
/**
|
||||
* Defines the field type.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @var string The field type.
|
||||
*/
|
||||
public $type = 'phone';
|
||||
|
||||
/**
|
||||
* Defines the field title to be used in the form editor.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFCommon::get_field_type_title()
|
||||
*
|
||||
* @return string The field title. Translatable and escaped.
|
||||
*/
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Phone', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to enter a phone number.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--phone';
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the field settings available within the field editor.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @return array The field settings available for the field.
|
||||
*/
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'phone_format_setting',
|
||||
'css_class_setting',
|
||||
'autocomplete_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines if conditional logic is supported in this field type.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDetail::inline_scripts()
|
||||
* @used-by GFFormSettings::output_field_scripts()
|
||||
*
|
||||
* @return bool true
|
||||
*/
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates inputs for the Phone field.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDisplay::validate()
|
||||
* @uses GF_Field_Phone::get_phone_format()
|
||||
* @uses GF_Field_Phone::$validation_message
|
||||
* @uses GF_Field_Phone::$errorMessage
|
||||
*
|
||||
* @param array|string $value The field value to be validated.
|
||||
* @param array $form The Form Object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validate( $value, $form ) {
|
||||
$phone_format = $this->get_phone_format();
|
||||
|
||||
if ( rgar( $phone_format, 'regex' ) && $value !== '' && $value !== 0 && ! preg_match( $phone_format['regex'], $value ) ) {
|
||||
$this->failed_validation = true;
|
||||
if ( ! empty( $this->errorMessage ) ) {
|
||||
$this->validation_message = $this->errorMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field input.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFCommon::get_field_input()
|
||||
* @uses GF_Field::is_entry_detail()
|
||||
* @uses GF_Field::is_form_editor()
|
||||
* @uses GF_Field_Phone::$failed_validation
|
||||
* @uses GF_Field_Phone::get_phone_format()
|
||||
* @uses GF_Field::get_field_placeholder_attribute()
|
||||
* @uses GF_Field_Phone::$isRequired
|
||||
* @uses GF_Field::get_tabindex()
|
||||
*
|
||||
* @param array $form The Form Object.
|
||||
* @param string $value The value of the input. Defaults to empty string.
|
||||
* @param null|array $entry The Entry Object. Defaults to null.
|
||||
*
|
||||
* @return string The HTML markup for the field.
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$form_id = $form['id'];
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$size = $this->size;
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$instruction_div = '';
|
||||
if ( $this->failed_validation ) {
|
||||
$phone_format = $this->get_phone_format();
|
||||
if ( rgar( $phone_format, 'instruction' ) ) {
|
||||
$instruction_div = sprintf( "<div class='gfield_description instruction validation_message'>%s %s</div>", esc_html__( 'Phone format:', 'gravityforms' ), $phone_format['instruction'] );
|
||||
}
|
||||
}
|
||||
|
||||
$html_input_type = 'tel';
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
$autocomplete_attribute = $this->enableAutocomplete ? $this->get_field_autocomplete_attribute() : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_phone'><input name='input_%d' id='%s' type='{$html_input_type}' value='%s' class='%s' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$autocomplete_attribute} %s/>{$instruction_div}</div>", $id, $field_id, esc_attr( $value ), esc_attr( $class ), $disabled_text );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the submitted field.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormsModel::get_field_value()
|
||||
* @uses GF_Field::get_value_submission()
|
||||
* @uses GF_Field_Phone::sanitize_entry_value()
|
||||
*
|
||||
* @param array $field_values The dynamic population parameter names with their corresponding values to be populated.
|
||||
* @param bool $get_from_post_global_var Whether to get the value from the $_POST array as opposed to $field_values. Defaults to true.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
|
||||
|
||||
$value = parent::get_value_submission( $field_values, $get_from_post_global_var );
|
||||
$value = $this->sanitize_entry_value( $value, $this->formId );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the entry value.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GF_Field_Phone::get_value_save_entry()
|
||||
* @used-by GF_Field_Phone::get_value_submission()
|
||||
*
|
||||
* @param string $value The value to be sanitized.
|
||||
* @param int $form_id The form ID of the submitted item.
|
||||
*
|
||||
* @return string The sanitized value.
|
||||
*/
|
||||
public function sanitize_entry_value( $value, $form_id ) {
|
||||
$value = is_array( $value ) ? array_map( 'sanitize_text_field', $value ) : sanitize_text_field( $value );
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field value when an entry is being saved.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormsModel::prepare_value()
|
||||
* @uses GF_Field_Phone::sanitize_entry_value()
|
||||
* @uses GF_Field_Phone::$phoneFormat
|
||||
*
|
||||
* @param string $value The input value.
|
||||
* @param array $form The Form Object.
|
||||
* @param string $input_name The input name.
|
||||
* @param int $lead_id The Entry ID.
|
||||
* @param array $lead The Entry Object.
|
||||
*
|
||||
* @return string The field value.
|
||||
*/
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
$value = $this->sanitize_entry_value( $value, $form['id'] );
|
||||
|
||||
if ( $this->phoneFormat == 'standard' && preg_match( '/^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$/', $value, $matches ) ) {
|
||||
$value = sprintf( '(%s) %s-%s', $matches[1], $matches[2], $matches[3] );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs any inline scripts to be used when the page is rendered.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GF_Field::register_form_init_scripts()
|
||||
* @uses GF_Field_Phone::get_phone_format()
|
||||
*
|
||||
* @param array $form The Form Object.
|
||||
*
|
||||
* @return string The inline scripts.
|
||||
*/
|
||||
public function get_form_inline_script_on_page_render( $form ) {
|
||||
$script = '';
|
||||
$phone_format = $this->get_phone_format();
|
||||
|
||||
if ( rgar( $phone_format, 'mask' ) ) {
|
||||
$script = "jQuery('#input_{$form['id']}_{$this->id}').mask('{$phone_format['mask']}').bind('keypress', function(e){if(e.which == 13){jQuery(this).blur();} } );";
|
||||
}
|
||||
return $script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the field settings.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDetail::add_field()
|
||||
* @used-by GFFormsModel::sanitize_settings()
|
||||
* @uses GF_Field::sanitize_settings()
|
||||
* @uses GF_Field_Phone::get_phone_format()
|
||||
* @uses GF_Field_Phone::$phoneFormat
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
|
||||
if ( ! $this->get_phone_format() ) {
|
||||
$this->phoneFormat = 'standard';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of phone formats.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GF_Field_Phone::get_phone_format()
|
||||
*
|
||||
* @param null|int $form_id The ID of the current form or null to use the value from the current fields form_id property. Defaults to null.
|
||||
*
|
||||
* @return array The phone formats available.
|
||||
*/
|
||||
public function get_phone_formats( $form_id = null ) {
|
||||
|
||||
if ( empty( $form_id ) ) {
|
||||
$form_id = $this->formId;
|
||||
}
|
||||
$form_id = absint( $form_id );
|
||||
|
||||
$phone_formats = array(
|
||||
'standard' => array(
|
||||
'label' => '(###) ###-####',
|
||||
'mask' => '(999) 999-9999',
|
||||
'regex' => '/^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$/',
|
||||
'instruction' => '(###) ###-####',
|
||||
),
|
||||
'international' => array(
|
||||
'label' => __( 'International', 'gravityforms' ),
|
||||
'mask' => false,
|
||||
'regex' => false,
|
||||
'instruction' => false,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Allow custom phone formats to be defined.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $phone_formats The phone formats.
|
||||
* @param int $form_id The ID of the current form.
|
||||
*/
|
||||
return gf_apply_filters( array( 'gform_phone_formats', $form_id ), $phone_formats, $form_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the properties for the fields selected phone format.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GF_Field_Phone::get_field_input()
|
||||
* @used-by GF_Field_Phone::get_form_inline_script_on_page_render()
|
||||
* @used-by GF_Field_Phone::sanitize_settings()
|
||||
* @used-by GF_Field_Phone::validate()
|
||||
* @uses GF_Field_Phone::get_phone_formats()
|
||||
* @uses GF_Field_Phone::$phoneFormat
|
||||
*
|
||||
* @return array The phone format.
|
||||
*/
|
||||
public function get_phone_format() {
|
||||
$phone_formats = $this->get_phone_formats();
|
||||
|
||||
return rgar( $phone_formats, $this->phoneFormat );
|
||||
}
|
||||
}
|
||||
|
||||
// Register the phone field with the field framework.
|
||||
GF_Fields::register( new GF_Field_Phone() );
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_Post_Category extends GF_Field {
|
||||
|
||||
public $type = 'post_category';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Category', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows the user to select a category for the post they are creating.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--category';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'post_category_checkbox_setting',
|
||||
'post_category_initial_item_setting',
|
||||
'post_category_field_type_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'conditional_logic_field_setting',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Post_Category() );
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-field-textarea.php' );
|
||||
|
||||
class GF_Field_Post_Content extends GF_Field_Textarea {
|
||||
|
||||
public $type = 'post_content';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Body', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit the body content for a post.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--body';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'post_content_template_setting',
|
||||
'post_status_setting',
|
||||
'post_category_setting',
|
||||
'post_author_setting',
|
||||
'post_format_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'maxlen_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'default_value_textarea_setting',
|
||||
'placeholder_textarea_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'rich_text_editor_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the rich_editing option for the current user.
|
||||
*
|
||||
* @since 2.2.5.14
|
||||
*
|
||||
* @param string $value The value of the rich_editing option for the current user.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function filter_user_option_rich_editing( $value ) {
|
||||
return is_user_logged_in() ? $value : 'true';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Post_Content() );
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_Post_Custom_Field extends GF_Field {
|
||||
|
||||
public $type = 'post_custom_field';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Custom Field', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit data that is used as a custom field value for a post.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--post-custom-field';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'post_custom_field_type_setting',
|
||||
'post_custom_field_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$value = esc_attr( $value );
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
return "<div class='ginput_container ginput_container_post_custom_field'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='text' value='{$value}' class='{$class}' {$tabindex} {$placeholder_attribute} {$disabled_text} {$required_attribute} {$invalid_attribute} {$aria_describedby} />
|
||||
</div>";
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Post_Custom_Field() );
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_Post_Excerpt extends GF_Field {
|
||||
|
||||
public $type = 'post_excerpt';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Excerpt', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit data that is then used as the excerpt of a post.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--excerpt';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'post_status_setting',
|
||||
'post_category_setting',
|
||||
'post_author_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'maxlen_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'default_value_textarea_setting',
|
||||
'placeholder_textarea_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$value = esc_textarea( $value );
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
return "<div class='ginput_container ginput_container_post_excerpt'>
|
||||
<textarea name='input_{$id}' id='{$field_id}' class='textarea {$class}' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$disabled_text} rows='10' cols='50'>{$value}</textarea>
|
||||
</div>";
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for when the field/input merge tag is processed. Not called for the {all_fields} merge tag.
|
||||
*
|
||||
* Return a value that is safe for the context specified by $format.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GF_Field::get_allowable_tags()
|
||||
*
|
||||
* @param string|array $value The field value. Depending on the location the merge tag is being used the following functions may have already been applied to the value: esc_html, nl2br, and urlencode.
|
||||
* @param string $input_id The field or input ID from the merge tag currently being processed.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $modifier The merge tag modifier. e.g. value
|
||||
* @param string|array $raw_value The raw field value from before any formatting was applied to $value.
|
||||
* @param bool $url_encode Indicates if the urlencode function may have been applied to the $value.
|
||||
* @param bool $esc_html Indicates if the esc_html function may have been applied to the $value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param bool $nl2br Indicates if the nl2br function may have been applied to the $value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
|
||||
if ( $format === 'html' ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$allowable_tags = $this->get_allowable_tags( $form_id );
|
||||
|
||||
if ( $allowable_tags === false ) {
|
||||
// The value is unsafe so encode the value.
|
||||
$return = esc_html( $value );
|
||||
} else {
|
||||
// The value contains HTML but the value was sanitized before saving.
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
// If $nl2br is true nl2br() may have already been run in GFCommon::format_variable_value().
|
||||
if ( ! $nl2br ) {
|
||||
// Run nl2br() to preserve line breaks when auto-formatting is disabled on notifications/confirmations.
|
||||
$return = nl2br( $return );
|
||||
}
|
||||
} else {
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Post_Excerpt() );
|
||||
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Post_Image extends GF_Field_Fileupload {
|
||||
|
||||
public $type = 'post_image';
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Post Image', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to upload an image that is added to the Media Library and Gallery for the post that is created.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--post-image';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'sub_label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'post_image_setting',
|
||||
'rules_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'post_image_featured_image',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_entry_detail || $is_form_editor;
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$alt = esc_attr( rgget( $this->id . '.2', $value ) );
|
||||
$title = esc_attr( rgget( $this->id . '.1', $value ) );
|
||||
$caption = esc_attr( rgget( $this->id . '.4', $value ) );
|
||||
$description = esc_attr( rgget( $this->id . '.7', $value ) );
|
||||
|
||||
//hiding meta fields for admin
|
||||
$hidden_style = "style='display:none;'";
|
||||
$alt_style = ! $this->displayAlt && $is_admin ? $hidden_style : '';
|
||||
$title_style = ! $this->displayTitle && $is_admin ? $hidden_style : '';
|
||||
$caption_style = ! $this->displayCaption && $is_admin ? $hidden_style : '';
|
||||
$description_style = ! $this->displayDescription && $is_admin ? $hidden_style : '';
|
||||
$file_label_style = $is_admin && ! ( $this->displayAlt || $this->displayTitle || $this->displayCaption || $this->displayDescription ) ? $hidden_style : '';
|
||||
|
||||
$form_sub_label_placement = rgar( $form, 'subLabelPlacement' );
|
||||
$field_sub_label_placement = $this->subLabelPlacement;
|
||||
$is_sub_label_above = $field_sub_label_placement == 'above' || ( empty( $field_sub_label_placement ) && $form_sub_label_placement == 'above' );
|
||||
|
||||
// Prepare accepted extensions message.
|
||||
$allowed_extensions = join( ',', GFCommon::clean_extensions( explode( ',', strtolower( $this->allowedExtensions ) ) ) );
|
||||
$extensions_message_id = 'extensions_message_' . $form_id . '_' . $id;
|
||||
$extensions_message = sprintf(
|
||||
"<span id='%s' class='gfield_description gform_fileupload_rules'>%s</span>",
|
||||
$extensions_message_id,
|
||||
esc_attr( sprintf( __( 'Accepted file types: %s.', 'gravityforms' ), str_replace( ',', ', ', $allowed_extensions ) ) )
|
||||
);
|
||||
|
||||
// Aria attributes.
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby( array( $extensions_message_id ) );
|
||||
|
||||
$hidden_class = $preview = '';
|
||||
$file_info = RGFormsModel::get_temp_filename( $form_id, "input_{$id}" );
|
||||
if ( $file_info ) {
|
||||
$hidden_class = ' gform_hidden';
|
||||
$file_label_style = $hidden_style;
|
||||
$preview = "<span class='ginput_preview'><strong>" . esc_html( $file_info['uploaded_filename'] ) . "</strong> | <a href='javascript:;' onclick='gformDeleteUploadedFile({$form_id}, {$id});' onkeypress='gformDeleteUploadedFile({$form_id}, {$id});'>" . __( 'delete', 'gravityforms' ) . '</a></span>';
|
||||
}
|
||||
|
||||
//in admin, render all meta fields to allow for immediate feedback, but hide the ones not selected
|
||||
$file_label = ( $is_admin || $this->displayAlt || $this->displayTitle || $this->displayCaption || $this->displayDescription ) ? "<label for='$field_id' class='gform-field-label gform-field-label--type-sub ginput_post_image_file' $file_label_style>" . gf_apply_filters( array( 'gform_postimage_file', $form_id ), __( 'File', 'gravityforms' ), $form_id ) . '</label>' : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
if( $is_sub_label_above ){
|
||||
$upload = sprintf( "<span class='ginput_full$class_suffix gform-grid-col'>$file_label{$preview}<input name='input_%d' id='%s' type='file' class='%s' $tabindex $required_attribute $invalid_attribute $aria_describedby %s/>{$extensions_message}</span>", $id, $field_id, esc_attr( $class . $hidden_class ), $disabled_text );
|
||||
} else {
|
||||
$upload = sprintf( "<span class='ginput_full$class_suffix gform-grid-col'>{$preview}<input name='input_%d' id='%s' type='file' class='%s' $tabindex $required_attribute $invalid_attribute $aria_describedby %s/>{$extensions_message}$file_label</span>", $id, $field_id, esc_attr( $class . $hidden_class ), $disabled_text );
|
||||
}
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
if( $is_sub_label_above ){
|
||||
$alt_field = $this->displayAlt || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_alt gform-grid-col' $alt_style><label for='%s_2' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_alt', $form_id ), __( 'Alternative Text', 'gravityforms' ), $form_id ) . "</label><input type='text' name='input_%d.2' id='%s_2' value='%s' $tabindex %s/></span>", $field_id, $id, $field_id, $alt, $disabled_text ) : '';
|
||||
} else {
|
||||
$alt_field = $this->displayAlt || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_alt gform-grid-col' $alt_style><input type='text' name='input_%d.2' id='%s_2' value='%s' $tabindex %s/><label for='%s_2' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_alt', $form_id ), __( 'Alternative Text', 'gravityforms' ), $form_id ) . '</label></span>', $id, $field_id, $alt, $disabled_text, $field_id ) : '';
|
||||
}
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
if( $is_sub_label_above ){
|
||||
$title_field = $this->displayTitle || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_title gform-grid-col' $title_style><label for='%s_1' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_title', $form_id ), __( 'Title', 'gravityforms' ), $form_id ) . "</label><input type='text' name='input_%d.1' id='%s_1' value='%s' $tabindex %s/></span>", $field_id, $id, $field_id, $title, $disabled_text ) : '';
|
||||
} else {
|
||||
$title_field = $this->displayTitle || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_title gform-grid-col' $title_style><input type='text' name='input_%d.1' id='%s_1' value='%s' $tabindex %s/><label for='%s_1' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_title', $form_id ), __( 'Title', 'gravityforms' ), $form_id ) . '</label></span>', $id, $field_id, $title, $disabled_text, $field_id ) : '';
|
||||
}
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
if( $is_sub_label_above ){
|
||||
$caption_field = $this->displayCaption || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_caption gform-grid-col' $caption_style><label for='%s_4' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_caption', $form_id ), __( 'Caption', 'gravityforms' ), $form_id ) . "</label><input type='text' name='input_%d.4' id='%s_4' value='%s' $tabindex %s/></span>", $field_id, $id, $field_id, $caption, $disabled_text ) : '';
|
||||
} else {
|
||||
$caption_field = $this->displayCaption || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_caption gform-grid-col' $caption_style><input type='text' name='input_%d.4' id='%s_4' value='%s' $tabindex %s/><label for='%s_4' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_caption', $form_id ), __( 'Caption', 'gravityforms' ), $form_id ) . '</label></span>', $id, $field_id, $caption, $disabled_text, $field_id ) : '';
|
||||
}
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
if( $is_sub_label_above ){
|
||||
$description_field = $this->displayDescription || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_description gform-grid-col' $description_style><label for='%s_7' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_description', $form_id ), __( 'Description', 'gravityforms' ), $form_id ) . "</label><input type='text' name='input_%d.7' id='%s_7' value='%s' $tabindex %s/></span>", $field_id, $id, $field_id, $description, $disabled_text ) : '';
|
||||
} else {
|
||||
$description_field = $this->displayDescription || $is_admin ? sprintf( "<span class='ginput_full$class_suffix ginput_post_image_description gform-grid-col' $description_style><input type='text' name='input_%d.7' id='%s_7' value='%s' $tabindex %s/><label for='%s_7' class='gform-field-label gform-field-label--type-sub'>" . gf_apply_filters( array( 'gform_postimage_description', $form_id ), __( 'Description', 'gravityforms' ), $form_id ) . '</label></span>', $id, $field_id, $description, $disabled_text, $field_id ) : '';
|
||||
}
|
||||
|
||||
return "<div class='ginput_complex$class_suffix ginput_container ginput_container_post_image gform-grid-row'>" . $upload . $alt_field . $title_field . $caption_field . $description_field . '</div>';
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
$form_id = $form['id'];
|
||||
$url = $this->get_single_file_value( $form_id, $input_name );
|
||||
|
||||
if ( empty( $url ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( ! GFCommon::is_valid_url( $url ) ) {
|
||||
GFCommon::log_debug( __METHOD__ . '(): aborting; File URL invalid.' );
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$image_alt = isset( $_POST["{$input_name}_2"] ) ? wp_strip_all_tags( $_POST["{$input_name}_2"] ) : '';
|
||||
$image_title = isset( $_POST["{$input_name}_1"] ) ? wp_strip_all_tags( $_POST["{$input_name}_1"] ) : '';
|
||||
$image_caption = isset( $_POST["{$input_name}_4"] ) ? wp_strip_all_tags( $_POST["{$input_name}_4"] ) : '';
|
||||
$image_description = isset( $_POST["{$input_name}_7"] ) ? wp_strip_all_tags( $_POST["{$input_name}_7"] ) : '';
|
||||
|
||||
return $url . '|:|' . $image_title . '|:|' . $image_caption . '|:|' . $image_description . '|:|' . $image_alt;
|
||||
}
|
||||
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
list( $url, $title, $caption, $description, $alt ) = rgexplode( '|:|', $value, 5 );
|
||||
if ( ! empty( $url ) ) {
|
||||
// displaying thumbnail (if file is an image) or an icon based on the extension.
|
||||
$thumb = GFEntryList::get_icon_url( $url );
|
||||
$value = "<a href='" . esc_attr( $url ) . "' target='_blank' aria-label='" . esc_attr__( 'View the image', 'gravityforms' ) . "'><img src='$thumb' alt='$alt' /></a>";
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
$ary = explode( '|:|', $value );
|
||||
$url = count( $ary ) > 0 ? $ary[0] : '';
|
||||
$title = count( $ary ) > 1 ? $ary[1] : '';
|
||||
$caption = count( $ary ) > 2 ? $ary[2] : '';
|
||||
$description = count( $ary ) > 3 ? $ary[3] : '';
|
||||
$alt = count( $ary ) > 4 ? $ary[4] : '';
|
||||
|
||||
if ( ! empty( $url ) ) {
|
||||
$url = str_replace( ' ', '%20', $url );
|
||||
|
||||
switch ( $format ) {
|
||||
case 'text' :
|
||||
$value = $url;
|
||||
$value .= ! empty( $alt ) ? "\n\n" . $this->label . ' (' . __( 'Alternative Text', 'gravityforms' ) . '): ' . $description : '';
|
||||
$value .= ! empty( $title ) ? "\n\n" . $this->label . ' (' . __( 'Title', 'gravityforms' ) . '): ' . $title : '';
|
||||
$value .= ! empty( $caption ) ? "\n\n" . $this->label . ' (' . __( 'Caption', 'gravityforms' ) . '): ' . $caption : '';
|
||||
$value .= ! empty( $description ) ? "\n\n" . $this->label . ' (' . __( 'Description', 'gravityforms' ) . '): ' . $description : '';
|
||||
break;
|
||||
|
||||
default :
|
||||
$value = "<a href='$url' target='_blank' aria-label='" . esc_attr__( 'View the image', 'gravityforms' ) . "'><img src='$url' width='100' alt='$alt' /></a>";
|
||||
$value .= ! empty( $alt ) ? '<div>' . esc_html__( 'Alternative Text', 'gravityforms' ) . ": $alt</div>" : '';
|
||||
$value .= ! empty( $title ) ? '<div>' . esc_html__( 'Title', 'gravityforms' ) . ": $title</div>" : '';
|
||||
$value .= ! empty( $caption ) ? '<div>' . esc_html__( 'Caption', 'gravityforms' ) . ": $caption</div>" : '';
|
||||
$value .= ! empty( $description ) ? '<div>' . esc_html__( 'Description', 'gravityforms' ) . ": $description</div>" : '';
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
|
||||
|
||||
$value[ $this->id . '.2' ] = $this->get_input_value_submission( 'input_' . $this->id . '_2', $get_from_post_global_var );
|
||||
$value[ $this->id . '.1' ] = $this->get_input_value_submission( 'input_' . $this->id . '_1', $get_from_post_global_var );
|
||||
$value[ $this->id . '.4' ] = $this->get_input_value_submission( 'input_' . $this->id . '_4', $get_from_post_global_var );
|
||||
$value[ $this->id . '.7' ] = $this->get_input_value_submission( 'input_' . $this->id . '_7', $get_from_post_global_var );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets merge tag values.
|
||||
*
|
||||
* @since Unknown
|
||||
* @since 2.5 Add alt text.
|
||||
* @access public
|
||||
*
|
||||
* @param array|string $value The value of the input.
|
||||
* @param string $input_id The input ID to use.
|
||||
* @param array $entry The Entry Object.
|
||||
* @param array $form The Form Object
|
||||
* @param string $modifier The modifier passed.
|
||||
* @param array|string $raw_value The raw value of the input.
|
||||
* @param bool $url_encode If the result should be URL encoded.
|
||||
* @param bool $esc_html If the HTML should be escaped.
|
||||
* @param string $format The format that the value should be.
|
||||
* @param bool $nl2br If the nl2br function should be used.
|
||||
*
|
||||
* @return string The processed merge tag.
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
list( $url, $title, $caption, $description, $alt ) = array_pad( explode( '|:|', $value ), 5, false );
|
||||
switch ( $modifier ) {
|
||||
case 'alt' :
|
||||
return $alt;
|
||||
|
||||
case 'title' :
|
||||
return $title;
|
||||
|
||||
case 'caption' :
|
||||
return $caption;
|
||||
|
||||
case 'description' :
|
||||
return $description;
|
||||
|
||||
default :
|
||||
return str_replace( ' ', '%20', $url );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the physical file paths as extra entry meta data.
|
||||
*
|
||||
* @since 2.5.16
|
||||
*
|
||||
* @param array $form The form object being saved.
|
||||
* @param array $entry The entry object being saved.
|
||||
*
|
||||
* @return array The array that contains the file URLs and their corresponding physical paths.
|
||||
*/
|
||||
public function get_extra_entry_metadata( $form, $entry ) {
|
||||
|
||||
// Leave only the file URL in the entry value so when parent saves the file path information the URL is a valid file URL.
|
||||
$ary = explode( '|:|', $entry[ $this->id ] );
|
||||
$entry[ $this->id ] = rgar( $ary, 0 );
|
||||
|
||||
return parent::get_extra_entry_metadata( $form, $entry );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GF_Fields::register( new GF_Field_Post_Image() );
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_Post_Tags extends GF_Field {
|
||||
|
||||
public $type = 'post_tags';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Tags', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit the tags for a post.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--tags';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'post_tag_type_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'default_value_setting',
|
||||
'visibility_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'placeholder_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$value = esc_attr( $value );
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
// Use the WordPress built-in class "howto" in the form editor.
|
||||
$text_hint_class = $is_form_editor ? 'howto' : 'gfield_post_tags_hint gfield_description';
|
||||
$text_hint = '<p class="' . $text_hint_class . '" id="' . $field_id . '_desc">' . gf_apply_filters( array(
|
||||
'gform_post_tags_hint',
|
||||
$form_id,
|
||||
$this->id,
|
||||
), esc_html__( 'Separate tags with commas', 'gravityforms' ), $form_id ) . '</p>';
|
||||
|
||||
return "<div class='ginput_container ginput_container_post_tags'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='text' value='{$value}' class='{$class}' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$disabled_text}/> {$text_hint}
|
||||
</div>";
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the hint text to aria-describedby.
|
||||
*
|
||||
* @param array $extra_ids any extra ids that should be added to the describedby attribute.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_aria_describedby( $extra_ids = array() ) {
|
||||
$id = (int) $this->id;
|
||||
$form_id = (int) $this->formId;
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$describedby = '';
|
||||
if ( $this->inputType === 'text' || empty( $this->inputType ) ) {
|
||||
$describedby .= "{$field_id}_desc";
|
||||
}
|
||||
|
||||
if ( ! empty( $this->description ) ) {
|
||||
$describedby .= " gfield_description_{$form_id}_{$id}";
|
||||
}
|
||||
|
||||
if ( $this->failed_validation ) {
|
||||
$describedby .= " validation_message_{$this->formId}_{$this->id}";
|
||||
}
|
||||
|
||||
if ( ! empty( $extra_ids ) ) {
|
||||
$describedby .= implode( ' ', $extra_ids );
|
||||
}
|
||||
|
||||
return empty( $describedby ) ? '' : 'aria-describedby="' . $describedby . '"';
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Post_Tags() );
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Post_Title extends GF_Field {
|
||||
|
||||
public $type = 'post_title';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Title', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit the title for a post.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--title';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'post_title_template_setting',
|
||||
'post_status_setting',
|
||||
'post_category_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'post_author_setting',
|
||||
'post_format_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$value = esc_attr( $value );
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
return "<div class='ginput_container ginput_container_post_title'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='text' value='{$value}' class='{$class}' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$aria_describedby} {$disabled_text}/>
|
||||
</div>";
|
||||
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the field value before saving to the entry.
|
||||
*
|
||||
* @since 2.2.6.4 Switched to wp_strip_all_tags.
|
||||
* @see https://developer.wordpress.org/reference/functions/wp_insert_post/#security
|
||||
*
|
||||
* @param string $value The field value to be processed.
|
||||
* @param int $form_id The ID of the form currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sanitize_entry_value( $value, $form_id ) {
|
||||
return wp_strip_all_tags( $value );
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Post_Title() );
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Price extends GF_Field {
|
||||
|
||||
public $type = 'price';
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--product';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'rules_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'placeholder_setting',
|
||||
'size_setting',
|
||||
'duplicate_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$price = GFCommon::to_number( $value );
|
||||
if ( ! rgblank( $value ) && ( $price === false || $price < 0 ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? __( 'Please enter a valid amount.', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$value = esc_attr( $value );
|
||||
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$describedby_attribute = $this->get_aria_describedby();
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
return "<div class='ginput_container ginput_container_product_price'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='text' value='{$value}' class='{$class} ginput_amount' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$describedby_attribute} {$disabled_text}/>
|
||||
</div>";
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
return GFCommon::to_money( $value, $currency );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Price() );
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Product extends GF_Field {
|
||||
|
||||
public $type = 'product';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Product', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows the creation of products in the form.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--product';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'product_field_type_setting',
|
||||
'prepopulate_field_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'label_placement_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Product() );
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Quantity extends GF_Field {
|
||||
|
||||
public $type = 'quantity';
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'product_field_setting',
|
||||
'quantity_field_type_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'label_placement_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Quantity', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows a quantity to be specified for product field.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--quantity';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Quantity() );
|
||||
@@ -0,0 +1,556 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Radio extends GF_Field {
|
||||
|
||||
public $type = 'radio';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Radio Buttons', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to select one option from a list.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--radio-button';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'choices_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'other_choice_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this field will be processed by the state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_state_validation_supported() {
|
||||
if ( $this->enableOtherChoice && rgpost( "is_submit_{$this->formId}" ) && rgpost( "input_{$this->id}" ) == 'gf_other_choice' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::is_state_validation_supported();
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
if ( $this->isRequired && $this->enableOtherChoice && rgpost( "input_{$this->id}" ) == 'gf_other_choice' ) {
|
||||
if ( empty( $value ) || strtolower( $value ) == strtolower( GFCommon::get_other_choice_value( $this ) ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'This field is required.', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_first_input_id( $form ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
$tag = GFCommon::is_legacy_markup_enabled( $form ) ? 'ul' : 'div';
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_radio'><{$tag} class='gfield_radio' id='%s'>%s</{$tag}></div>", $field_id, $this->get_radio_choices( $value, $disabled_text, $form_id ) );
|
||||
|
||||
}
|
||||
|
||||
public function get_radio_choices( $value = '', $disabled_text = '', $form_id = 0 ) {
|
||||
$choices = '';
|
||||
|
||||
if ( is_array( $this->choices ) ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_entry_detail || $is_form_editor;
|
||||
|
||||
$field_choices = $this->choices;
|
||||
$needs_other_choice = $this->enableOtherChoice;
|
||||
$editor_limited = false;
|
||||
|
||||
$choice_id = 0;
|
||||
$count = 1;
|
||||
|
||||
$tag = GFCommon::is_legacy_markup_enabled( $form_id ) ? 'li' : 'div';
|
||||
|
||||
foreach ( $field_choices as $choice ) {
|
||||
if ( rgar( $choice, 'isOtherChoice' ) ) {
|
||||
if ( ! $needs_other_choice ) {
|
||||
continue;
|
||||
}
|
||||
$needs_other_choice = false;
|
||||
}
|
||||
|
||||
$choices .= $this->get_choice_html( $choice, $choice_id, $value, $disabled_text, $is_admin );
|
||||
|
||||
if ( $is_form_editor && $count >= 5 ) {
|
||||
$editor_limited = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$count ++;
|
||||
}
|
||||
|
||||
if ( $needs_other_choice ) {
|
||||
$other_choice = array(
|
||||
'text' => GFCommon::get_other_choice_value( $this ),
|
||||
'value' => 'gf_other_choice',
|
||||
'isSelected' => false,
|
||||
'isOtherChoice' => true,
|
||||
);
|
||||
$field_choices[] = $other_choice;
|
||||
|
||||
if ( ! $is_form_editor || ! $editor_limited ) {
|
||||
$choices .= $this->get_choice_html( $other_choice, $choice_id, $value, $disabled_text, $is_admin );
|
||||
$count ++;
|
||||
}
|
||||
}
|
||||
|
||||
$total = sizeof( $field_choices );
|
||||
if ( $is_form_editor && ( $count < $total ) ) {
|
||||
$choices .= "<{$tag} class='gchoice_total'>" . sprintf( esc_html__( '%d of %d items shown. Edit field to view all', 'gravityforms' ), $count, $total ) . "</{$tag}>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the HTML for multiple choices to be overridden.
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param string $choices The choices HTML.
|
||||
* @param GF_Field_Radio $field The current field object.
|
||||
*/
|
||||
return gf_apply_filters( array( 'gform_field_choices', $this->formId ), $choices, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if we should add the aria description to a radio input.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $checked The checked attribute or a blank string.
|
||||
* @param int $choice_id The choice number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function add_aria_description( $checked, $choice_id ) {
|
||||
|
||||
// Determine if any choices are pre-selected.
|
||||
foreach ( $this['choices'] as $choice ) {
|
||||
$is_any_selected = rgar( $choice, 'isSelected' );
|
||||
if ( $is_any_selected ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if any choices are pre-selected, or if no choices are pre-selected and this is the first choice.
|
||||
return ( ! $is_any_selected && $choice_id === 1 ) || $checked;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the choice HTML.
|
||||
*
|
||||
* @since 2.4.17
|
||||
* @since 2.7 Added `gchoice_other_control` class to Other choice text input.
|
||||
*
|
||||
* @param array $choice The choice properties.
|
||||
* @param int &$choice_id The choice number.
|
||||
* @param string $value The current field value.
|
||||
* @param string $disabled_text The disabled attribute or an empty string.
|
||||
* @param bool $is_admin Indicates if this is the form editor or entry detail page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_choice_html( $choice, &$choice_id, $value, $disabled_text, $is_admin ) {
|
||||
$form_id = absint( $this->formId );
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form_id ) ) {
|
||||
return $this->get_legacy_choice_html( $choice, $choice_id, $value, $disabled_text, $is_admin );
|
||||
}
|
||||
|
||||
if ( $is_admin || $form_id == 0 ) {
|
||||
$id = $this->id . '_' . $choice_id ++;
|
||||
} else {
|
||||
$id = $form_id . '_' . $this->id . '_' . $choice_id ++;
|
||||
}
|
||||
|
||||
$field_value = ! empty( $choice['value'] ) || $this->enableChoiceValue ? $choice['value'] : $choice['text'];
|
||||
|
||||
if ( $this->enablePrice ) {
|
||||
$price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) );
|
||||
$field_value .= '|' . $price;
|
||||
}
|
||||
|
||||
if ( rgblank( $value ) && rgget( 'view' ) != 'entry' ) {
|
||||
$checked = rgar( $choice, 'isSelected' ) ? "checked='checked'" : '';
|
||||
} else {
|
||||
$checked = GFFormsModel::choice_value_match( $this, $choice, $value ) ? "checked='checked'" : '';
|
||||
}
|
||||
|
||||
$aria_describedby = $this->add_aria_description( $checked, $choice_id ) ? $this->get_aria_describedby() : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$label = sprintf( "<label for='choice_%s' id='label_%s' class='gform-field-label gform-field-label--type-inline'>%s</label>", $id, $id, $choice['text'] );
|
||||
|
||||
// Handle 'other' choice.
|
||||
if ( $this->enableOtherChoice && rgar( $choice, 'isOtherChoice' ) ) {
|
||||
$input_disabled_text = $disabled_text;
|
||||
|
||||
if ( $value == 'gf_other_choice' && rgpost( "input_{$this->id}_other" ) ) {
|
||||
$other_value = rgpost( "input_{$this->id}_other" );
|
||||
} elseif ( ! empty( $value ) && ! GFFormsModel::choices_value_match( $this, $this->choices, $value ) ) {
|
||||
$other_value = $value;
|
||||
$value = 'gf_other_choice';
|
||||
$checked = "checked='checked'";
|
||||
} else {
|
||||
if ( ! $input_disabled_text ) {
|
||||
$input_disabled_text = "disabled='disabled'";
|
||||
}
|
||||
$other_value = empty( $choice['text'] ) ? GFCommon::get_other_choice_value( $this ) : $choice['text'];
|
||||
}
|
||||
|
||||
$label .= "<br /><input id='input_{$this->formId}_{$this->id}_other' class='gchoice_other_control' name='input_{$this->id}_other' type='text' value='" . esc_attr( $other_value ) . "' aria-label='" . esc_attr__( 'Other Choice, please specify', 'gravityforms' ) . "' $tabindex $input_disabled_text />";
|
||||
}
|
||||
|
||||
$choice_markup = sprintf( "
|
||||
<div class='gchoice gchoice_$id'>
|
||||
<input class='gfield-choice-input' name='input_%d' type='radio' value='%s' %s id='choice_%s' onchange='gformToggleRadioOther( this )' %s $tabindex %s />
|
||||
%s
|
||||
</div>",
|
||||
$this->id, esc_attr( $field_value ), $checked, $id, $aria_describedby, $disabled_text, $label
|
||||
);
|
||||
|
||||
/**
|
||||
* Allows the HTML for a specific choice to be overridden.
|
||||
*
|
||||
* @since 1.9.6
|
||||
* @since 1.9.12 Added the field specific version.
|
||||
* @since 2.4.17 Moved from GF_Field_Radio::get_radio_choices().
|
||||
*
|
||||
* @param string $choice_markup The choice HTML.
|
||||
* @param array $choice The choice properties.
|
||||
* @param GF_Field_Radio $field The current field object.
|
||||
* @param string $value The current field value.
|
||||
*/
|
||||
return gf_apply_filters( array( 'gform_field_choice_markup_pre_render', $this->formId, $this->id ), $choice_markup, $choice, $this, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the choice HTML.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $choice The choice properties.
|
||||
* @param int &$choice_id The choice number.
|
||||
* @param string $value The current field value.
|
||||
* @param string $disabled_text The disabled attribute or an empty string.
|
||||
* @param bool $is_admin Indicates if this is the form editor or entry detail page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_legacy_choice_html( $choice, &$choice_id, $value, $disabled_text, $is_admin ) {
|
||||
$form_id = absint( $this->formId );
|
||||
|
||||
if ( $is_admin || $form_id == 0 ) {
|
||||
$id = $this->id . '_' . $choice_id ++;
|
||||
} else {
|
||||
$id = $form_id . '_' . $this->id . '_' . $choice_id ++;
|
||||
}
|
||||
|
||||
$field_value = ! empty( $choice['value'] ) || $this->enableChoiceValue ? $choice['value'] : $choice['text'];
|
||||
|
||||
if ( $this->enablePrice ) {
|
||||
$price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) );
|
||||
$field_value .= '|' . $price;
|
||||
}
|
||||
|
||||
if ( rgblank( $value ) && rgget( 'view' ) != 'entry' ) {
|
||||
$checked = rgar( $choice, 'isSelected' ) ? "checked='checked'" : '';
|
||||
} else {
|
||||
$checked = GFFormsModel::choice_value_match( $this, $choice, $value ) ? "checked='checked'" : '';
|
||||
}
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$label = sprintf( "<label for='choice_%s' id='label_%s' class='gform-field-label gform-field-label--type-inline'>%s</label>", $id, $id, $choice['text'] );
|
||||
$input_focus = '';
|
||||
|
||||
// Handle 'other' choice.
|
||||
if ( $this->enableOtherChoice && rgar( $choice, 'isOtherChoice' ) ) {
|
||||
$other_default_value = empty( $choice['text'] ) ? GFCommon::get_other_choice_value( $this ) : $choice['text'];
|
||||
|
||||
$onfocus = ! $is_admin ? 'jQuery(this).prev("input")[0].click(); if(jQuery(this).val() == "' . $other_default_value . '") { jQuery(this).val(""); }' : '';
|
||||
$onblur = ! $is_admin ? 'if(jQuery(this).val().replace(" ", "") == "") { jQuery(this).val("' . $other_default_value . '"); }' : '';
|
||||
|
||||
$input_focus = ! $is_admin ? "onfocus=\"jQuery(this).next('input').focus();\"" : '';
|
||||
$value_exists = GFFormsModel::choices_value_match( $this, $this->choices, $value );
|
||||
|
||||
if ( $value == 'gf_other_choice' && rgpost( "input_{$this->id}_other" ) ) {
|
||||
$other_value = rgpost( "input_{$this->id}_other" );
|
||||
} elseif ( ! $value_exists && ! empty( $value ) ) {
|
||||
$other_value = $value;
|
||||
$value = 'gf_other_choice';
|
||||
$checked = "checked='checked'";
|
||||
} else {
|
||||
$other_value = $other_default_value;
|
||||
}
|
||||
|
||||
$label = "<input class='small' id='input_{$this->formId}_{$this->id}_other' name='input_{$this->id}_other' type='text' value='" . esc_attr( $other_value ) . "' aria-label='" . esc_attr__( 'Other', 'gravityforms' ) . "' onfocus='$onfocus' onblur='$onblur' $tabindex $disabled_text />";
|
||||
}
|
||||
|
||||
$choice_markup = sprintf( "
|
||||
<li class='gchoice gchoice_$id'>
|
||||
<input name='input_%d' type='radio' value='%s' %s id='choice_%s' $tabindex %s %s />
|
||||
%s
|
||||
</li>",
|
||||
$this->id, esc_attr( $field_value ), $checked, $id, $disabled_text, $input_focus, $label
|
||||
);
|
||||
|
||||
/**
|
||||
* Allows the HTML for a specific choice to be overridden.
|
||||
*
|
||||
* @since 1.9.6
|
||||
* @since 1.9.12 Added the field specific version.
|
||||
* @since 2.4.17 Moved from GF_Field_Radio::get_radio_choices().
|
||||
*
|
||||
* @param string $choice_markup The choice HTML.
|
||||
* @param array $choice The choice properties.
|
||||
* @param GF_Field_Radio $field The current field object.
|
||||
* @param string $value The current field value.
|
||||
*/
|
||||
return gf_apply_filters( array( 'gform_field_choice_markup_pre_render', $this->formId, $this->id ), $choice_markup, $choice, $this, $value );
|
||||
}
|
||||
|
||||
public function get_value_default() {
|
||||
return $this->is_form_editor() ? $this->defaultValue : GFCommon::replace_variables_prepopulate( $this->defaultValue );
|
||||
}
|
||||
|
||||
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
|
||||
|
||||
$value = $this->get_input_value_submission( 'input_' . $this->id, $this->inputName, $field_values, $get_from_post_global_var );
|
||||
if ( $value == 'gf_other_choice' ) {
|
||||
//get value from text box
|
||||
$value = $this->get_input_value_submission( 'input_' . $this->id . '_other', $this->inputName, $field_values, $get_from_post_global_var );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
return $this->get_selected_choice_output( $value, rgar( $entry, 'currency' ) );
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
return $this->get_selected_choice_output( $value, $currency, $use_text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets merge tag values.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::to_money()
|
||||
* @uses GFCommon::format_post_category()
|
||||
* @uses GFFormsModel::is_field_hidden()
|
||||
* @uses GFFormsModel::get_choice_text()
|
||||
* @uses GFCommon::format_variable_value()
|
||||
* @uses GFCommon::implode_non_blank()
|
||||
*
|
||||
* @param array|string $value The value of the input.
|
||||
* @param string $input_id The input ID to use.
|
||||
* @param array $entry The Entry Object.
|
||||
* @param array $form The Form Object
|
||||
* @param string $modifier The modifier passed.
|
||||
* @param array|string $raw_value The raw value of the input.
|
||||
* @param bool $url_encode If the result should be URL encoded.
|
||||
* @param bool $esc_html If the HTML should be escaped.
|
||||
* @param string $format The format that the value should be.
|
||||
* @param bool $nl2br If the nl2br function should be used.
|
||||
*
|
||||
* @return string The processed merge tag.
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
$modifiers = $this->get_modifiers();
|
||||
$use_value = in_array( 'value', $modifiers );
|
||||
$format_currency = ! $use_value && in_array( 'currency', $modifiers );
|
||||
$use_price = $format_currency || ( ! $use_value && in_array( 'price', $modifiers ) );
|
||||
|
||||
if ( is_array( $raw_value ) && (string) intval( $input_id ) != $input_id ) {
|
||||
$items = array( $input_id => $value ); // Float input Ids. (i.e. 4.1 ). Used when targeting specific checkbox items.
|
||||
} elseif ( is_array( $raw_value ) ) {
|
||||
$items = $raw_value;
|
||||
} else {
|
||||
$items = array( $input_id => $raw_value );
|
||||
}
|
||||
|
||||
$ary = array();
|
||||
|
||||
foreach ( $items as $input_id => $item ) {
|
||||
if ( $use_value ) {
|
||||
list( $val, $price ) = rgexplode( '|', $item, 2 );
|
||||
} elseif ( $use_price ) {
|
||||
list( $name, $val ) = rgexplode( '|', $item, 2 );
|
||||
if ( $format_currency ) {
|
||||
$val = GFCommon::to_money( $val, rgar( $entry, 'currency' ) );
|
||||
}
|
||||
} elseif ( $this->type == 'post_category' ) {
|
||||
$use_id = strtolower( $modifier ) == 'id';
|
||||
$item_value = GFCommon::format_post_category( $item, $use_id );
|
||||
|
||||
$val = RGFormsModel::is_field_hidden( $form, $this, array(), $entry ) ? '' : $item_value;
|
||||
} else {
|
||||
$val = RGFormsModel::is_field_hidden( $form, $this, array(), $entry ) ? '' : RGFormsModel::get_choice_text( $this, $raw_value, $input_id );
|
||||
}
|
||||
|
||||
$ary[] = GFCommon::format_variable_value( $val, $url_encode, $esc_html, $format );
|
||||
}
|
||||
|
||||
return GFCommon::implode_non_blank( ', ', $ary );
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
|
||||
if ( $this->enableOtherChoice && $value == 'gf_other_choice' ) {
|
||||
$value = rgpost( "input_{$this->id}_other" );
|
||||
}
|
||||
|
||||
$value = $this->sanitize_entry_value( $value, $form['id'] );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
|
||||
if ( empty( $input_id ) ) {
|
||||
$input_id = $this->id;
|
||||
}
|
||||
|
||||
$value = rgar( $entry, $input_id );
|
||||
|
||||
return $is_csv ? $value : GFCommon::selection_display( $value, $this, rgar( $entry, 'currency' ), $use_text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip scripts and some HTML tags.
|
||||
*
|
||||
* @param string $value The field value to be processed.
|
||||
* @param int $form_id The ID of the form currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sanitize_entry_value( $value, $form_id ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$allowable_tags = $this->get_allowable_tags( $form_id );
|
||||
|
||||
if ( $allowable_tags !== true ) {
|
||||
$value = strip_tags( $value, $allowable_tags );
|
||||
}
|
||||
|
||||
$allowed_protocols = wp_allowed_protocols();
|
||||
$value = wp_kses_no_null( $value, array( 'slash_zero' => 'keep' ) );
|
||||
$value = wp_kses_hook( $value, 'post', $allowed_protocols );
|
||||
$value = wp_kses_split( $value, 'post', $allowed_protocols );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = $this->type == 'product' ? array( 'is' ) : array( 'is', 'isnot', '>', '<' );
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Radio() );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GF_Field_Section extends GF_Field {
|
||||
|
||||
public $type = 'section';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Section', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Adds a content separator to your form to help organize groups of fields. This is a visual element and does not collect any data.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--section';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'label_setting',
|
||||
'description_setting',
|
||||
'visibility_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the field label.
|
||||
*
|
||||
* @since 2.5.2 Don't force this field to have a label.
|
||||
*
|
||||
* @param bool $force_frontend_label Should the frontend label be displayed in the admin even if an admin label is configured.
|
||||
* @param string $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_label( $force_frontend_label, $value ) {
|
||||
$label = $force_frontend_label ? $this->label : GFCommon::get_label( $this );
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
public function get_field_content( $value, $force_frontend_label, $form ) {
|
||||
|
||||
$field_label = $this->get_field_label( $force_frontend_label, $value );
|
||||
|
||||
$admin_buttons = $this->get_admin_buttons();
|
||||
|
||||
$admin_hidden_markup = ( $this->visibility == 'hidden' ) ? $this->get_hidden_admin_markup() : '';
|
||||
|
||||
$description = $this->get_description( $this->description, 'gsection_description' );
|
||||
$tag = GFCommon::is_legacy_markup_enabled( $form ) ? 'h2' : 'h3';
|
||||
/* translators: 1. Admin buttons markup 2. Heading tag 3. The field label 4. The description */
|
||||
$field_content = sprintf( '%1$s%2$s<%3$s class="gsection_title">%4$s</%3$s>%5$s', $admin_buttons, $admin_hidden_markup, $tag, esc_html( $field_label ), $description );
|
||||
|
||||
return $field_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to be performed once the field has been converted to an object.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public function post_convert_field() {
|
||||
parent::post_convert_field();
|
||||
|
||||
// Section fields are not currently supported in columns.
|
||||
unset( $this->layoutGridColumnSpan );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Section() );
|
||||
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Select extends GF_Field {
|
||||
|
||||
public $type = 'select';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Drop Down', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to select one option from a list.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--dropdown';
|
||||
}
|
||||
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'enable_enhanced_ui_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'choices_setting',
|
||||
'rules_setting',
|
||||
'placeholder_setting',
|
||||
'default_value_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'autocomplete_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$css_class = trim( esc_attr( $class ) . ' gfield_select' );
|
||||
$tabindex = $this->get_tabindex();
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$describedby_attribute = $this->get_aria_describedby();
|
||||
$autocomplete_attribute = $this->enableAutocomplete ? $this->get_field_autocomplete_attribute() : '';
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_select'><select name='input_%d' id='%s' class='%s' $tabindex $describedby_attribute %s %s %s %s>%s</select></div>", $id, $field_id, $css_class, $disabled_text, $required_attribute, $invalid_attribute, $autocomplete_attribute, $this->get_choices( $value ) );
|
||||
|
||||
}
|
||||
|
||||
public function get_choices( $value ) {
|
||||
return GFCommon::get_select_choices( $this, $value );
|
||||
}
|
||||
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
return esc_html( $this->get_selected_choice_output( $value, rgar( $entry, 'currency' ) ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets merge tag values.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::to_money()
|
||||
* @uses GFCommon::format_post_category()
|
||||
* @uses GFFormsModel::is_field_hidden()
|
||||
* @uses GFFormsModel::get_choice_text()
|
||||
* @uses GFCommon::format_variable_value()
|
||||
* @uses GFCommon::implode_non_blank()
|
||||
*
|
||||
* @param array|string $value The value of the input.
|
||||
* @param string $input_id The input ID to use.
|
||||
* @param array $entry The Entry Object.
|
||||
* @param array $form The Form Object
|
||||
* @param string $modifier The modifier passed.
|
||||
* @param array|string $raw_value The raw value of the input.
|
||||
* @param bool $url_encode If the result should be URL encoded.
|
||||
* @param bool $esc_html If the HTML should be escaped.
|
||||
* @param string $format The format that the value should be.
|
||||
* @param bool $nl2br If the nl2br function should be used.
|
||||
*
|
||||
* @return string The processed merge tag.
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
$modifiers = $this->get_modifiers();
|
||||
$use_value = in_array( 'value', $modifiers );
|
||||
$format_currency = ! $use_value && in_array( 'currency', $modifiers );
|
||||
$use_price = $format_currency || ( ! $use_value && in_array( 'price', $modifiers ) );
|
||||
|
||||
if ( is_array( $raw_value ) && (string) intval( $input_id ) != $input_id ) {
|
||||
$items = array( $input_id => $value ); // Float input Ids. (i.e. 4.1 ). Used when targeting specific checkbox items.
|
||||
} elseif ( is_array( $raw_value ) ) {
|
||||
$items = $raw_value;
|
||||
} else {
|
||||
$items = array( $input_id => $raw_value );
|
||||
}
|
||||
|
||||
$ary = array();
|
||||
|
||||
foreach ( $items as $input_id => $item ) {
|
||||
if ( $use_value ) {
|
||||
list( $val, $price ) = rgexplode( '|', $item, 2 );
|
||||
} elseif ( $use_price ) {
|
||||
list( $name, $val ) = rgexplode( '|', $item, 2 );
|
||||
if ( $format_currency ) {
|
||||
$val = GFCommon::to_money( $val, rgar( $entry, 'currency' ) );
|
||||
}
|
||||
} elseif ( $this->type == 'post_category' ) {
|
||||
$use_id = strtolower( $modifier ) == 'id';
|
||||
$item_value = GFCommon::format_post_category( $item, $use_id );
|
||||
|
||||
$val = RGFormsModel::is_field_hidden( $form, $this, array(), $entry ) ? '' : $item_value;
|
||||
} else {
|
||||
$val = RGFormsModel::is_field_hidden( $form, $this, array(), $entry ) ? '' : RGFormsModel::get_choice_text( $this, $raw_value, $input_id );
|
||||
}
|
||||
|
||||
$ary[] = GFCommon::format_variable_value( $val, $url_encode, $esc_html, $format );
|
||||
}
|
||||
|
||||
return GFCommon::implode_non_blank( ', ', $ary );
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
return esc_html( $this->get_selected_choice_output( $value, $currency, $use_text ) );
|
||||
}
|
||||
|
||||
public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
|
||||
if ( empty( $input_id ) ) {
|
||||
$input_id = $this->id;
|
||||
}
|
||||
|
||||
$value = rgar( $entry, $input_id );
|
||||
|
||||
return $is_csv ? $value : GFCommon::selection_display( $value, $this, rgar( $entry, 'currency' ), $use_text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips all tags from the input value.
|
||||
*
|
||||
* @param string $value The field value to be processed.
|
||||
* @param int $form_id The ID of the form currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sanitize_entry_value( $value, $form_id ) {
|
||||
|
||||
$value = wp_strip_all_tags( $value );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = $this->type == 'product' ? array( 'is' ) : array( 'is', 'isnot', '>', '<' );
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Select() );
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Shipping extends GF_Field {
|
||||
|
||||
public $type = 'shipping';
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'shipping_field_type_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'label_placement_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Shipping', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows a shipping fee to be added to the form total.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--shipping';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Shipping() );
|
||||
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_SingleProduct extends GF_Field {
|
||||
|
||||
public $type = 'singleproduct';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--product';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'base_price_setting',
|
||||
'disable_quantity_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'rules_setting',
|
||||
'duplicate_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$quantity_id = $this->id . '.3';
|
||||
$quantity = rgget( $quantity_id, $value );
|
||||
|
||||
if ( $this->isRequired && rgblank( $quantity ) && ! $this->disableQuantity ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty($this->errorMessage) ? esc_html__( 'This field is required.', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( ! empty( $quantity ) && ( ! is_numeric( $quantity ) || intval( $quantity ) != floatval( $quantity ) || intval( $quantity ) < 0 ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Please enter a valid quantity', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value_default() {
|
||||
$value = array();
|
||||
if ( is_array( $this->inputs ) ) {
|
||||
foreach ( $this->inputs as $index => $input ) {
|
||||
$input_value = $this->is_form_editor() ? rgar( $input, 'defaultValue' ) : GFCommon::replace_variables_prepopulate( rgar( $input, 'defaultValue' ) );
|
||||
if ( rgblank( $input_value ) && $input['id'] == "{$this->id}.2" ) {
|
||||
$input_value = $this->basePrice;
|
||||
}
|
||||
$value[ strval( $input['id'] ) ] = $input_value;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field inputs.
|
||||
*
|
||||
* @since unknown
|
||||
* @since 2.5 Add accessibility enhancements.
|
||||
*
|
||||
* @param array $form The form object.
|
||||
* @param string $value The field value.
|
||||
* @param array $entry The entry object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_legacy_markup = GFCommon::is_legacy_markup_enabled( $form );
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$product_name = ! is_array( $value ) || empty( $value[ $this->id . '.1' ] ) ? esc_attr( $this->label ) : esc_attr( $value[ $this->id . '.1' ] );
|
||||
$price = ! is_array( $value ) || empty( $value[ $this->id . '.2' ] ) ? $this->basePrice : esc_attr( $value[ $this->id . '.2' ] );
|
||||
$quantity = is_array( $value ) ? esc_attr( $value[ $this->id . '.3' ] ) : '';
|
||||
|
||||
if ( empty( $price ) ) {
|
||||
$price = 0;
|
||||
}
|
||||
|
||||
$price = GFCommon::to_money( $price );
|
||||
|
||||
$has_quantity = sizeof( GFCommon::get_product_fields_by_type( $form, array( 'quantity' ), $this->id ) ) > 0;
|
||||
if ( $has_quantity ) {
|
||||
$this->disableQuantity = true;
|
||||
}
|
||||
|
||||
$currency = $is_entry_detail && ! empty( $entry ) ? $entry['currency'] : '';
|
||||
|
||||
$quantity_field = '';
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$product_quantity_sub_label = $this->get_product_quantity_label( $form_id );
|
||||
|
||||
if ( $is_entry_detail || $is_form_editor ) {
|
||||
$style = $this->disableQuantity ? "style='display:none;'" : '';
|
||||
$quantity_field = " <span class='ginput_quantity_label gform-field-label' {$style}>{$product_quantity_sub_label}</span> <input type='number' name='input_{$id}.3' value='{$quantity}' id='ginput_quantity_{$form_id}_{$this->id}' class='ginput_quantity' size='10' {$disabled_text} {$style}/>";
|
||||
} else if ( ! $this->disableQuantity ) {
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$describedby_extra_id = array();
|
||||
if ( ! $is_legacy_markup ) {
|
||||
$describedby_extra_id = array( "ginput_product_price_{$this->formId}_{$this->id}" );
|
||||
}
|
||||
|
||||
$quantity_aria_describedby = $this->get_aria_describedby( $describedby_extra_id );
|
||||
$quantity_aria_label = sprintf( 'aria-label="%s %s"', __( 'Quantity', 'gravityforms' ), $product_name );
|
||||
|
||||
$quantity_field .= " <span class='ginput_quantity_label gform-field-label' aria-hidden='true'>" . $product_quantity_sub_label . "</span> <input type='number' name='input_{$id}.3' value='{$quantity}' id='input_{$form_id}_{$this->id}_1' class='ginput_quantity' size='10' min='0' {$tabindex} {$disabled_text} {$quantity_aria_label} {$quantity_aria_describedby} />";
|
||||
} else {
|
||||
if ( ! is_numeric( $quantity ) ) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
if ( ! $has_quantity ) {
|
||||
$quantity_field .= "<input type='hidden' name='input_{$id}.3' value='{$quantity}' class='ginput_quantity_{$form_id}_{$this->id} gform_hidden' />";
|
||||
}
|
||||
}
|
||||
|
||||
$wrapper_open = $is_legacy_markup ? '' : "<div id='ginput_product_price_{$form_id}_{$this->id}' class='ginput_product_price_wrapper'>";
|
||||
$wrapper_close = $is_legacy_markup ? '' : '</div>';
|
||||
if ( $has_quantity ) {
|
||||
$product_aria_describedby = $this->get_aria_describedby();
|
||||
return "<div class='ginput_container ginput_container_singleproduct'>
|
||||
<input type='hidden' name='input_{$id}.1' value='{$product_name}' class='gform_hidden' />
|
||||
$wrapper_open
|
||||
<label for='ginput_price_{$form_id}_{$this->id}_2' class='gform-field-label gform-field-label--type-sub-large ginput_product_price_label'>" . gf_apply_filters( array( 'gform_product_price', $form_id, $this->id ), esc_html__( 'Price', 'gravityforms' ), $form_id ) . ":</label>
|
||||
<input type='text' readonly name='input_{$id}.2' class='ginput_product_price gform-text-input-reset' id='ginput_base_price_{$form_id}_{$this->id}' value='" . esc_attr( $price ) . "' {$product_aria_describedby} />
|
||||
$wrapper_close
|
||||
{$quantity_field}
|
||||
</div>";
|
||||
} else if ( $this->disableQuantity ) {
|
||||
$product_aria_describedby = $this->get_aria_describedby();
|
||||
return "<div class='ginput_container ginput_container_singleproduct'>
|
||||
<input type='hidden' name='input_{$id}.1' value='{$product_name}' class='gform_hidden' />
|
||||
$wrapper_open
|
||||
<label for='ginput_base_price_{$form_id}_{$this->id}' class='gform-field-label gform-field-label--type-sub-large ginput_product_price_label'>" . gf_apply_filters( array( 'gform_product_price', $form_id, $this->id ), esc_html__( 'Price', 'gravityforms' ), $form_id ) . ":</label>
|
||||
<input type='text' readonly class='ginput_product_price gform-text-input-reset' name='input_{$id}.2' id='ginput_base_price_{$form_id}_{$this->id}' class='gform_hidden' value='" . esc_attr( $price ) . "' aria-label='{$product_name} " . esc_html__( 'Price', 'gravityforms' ) . "' {$product_aria_describedby} />
|
||||
$wrapper_close
|
||||
{$quantity_field}
|
||||
</div>";
|
||||
} else {
|
||||
return "<div class='ginput_container ginput_container_singleproduct'>
|
||||
<input type='hidden' name='input_{$id}.1' value='{$product_name}' class='gform_hidden' />
|
||||
$wrapper_open
|
||||
<span class='gform-field-label gform-field-label--type-sub-large ginput_product_price_label'>" . gf_apply_filters( array( 'gform_product_price', $form_id, $this->id ), esc_html__( 'Price', 'gravityforms' ), $form_id ) . ":</span>
|
||||
<span class='gform-field-label gform-field-label--type-sub-large ginput_product_price' id='{$field_id}'>" . esc_html( GFCommon::to_money( $price, $currency ) ) . "</span>
|
||||
$wrapper_close
|
||||
<input type='hidden' name='input_{$id}.2' id='ginput_base_price_{$form_id}_{$this->id}' class='gform_hidden' value='" . esc_attr( $price ) . "'/>
|
||||
{$quantity_field}
|
||||
</div>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the field label.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param bool $force_frontend_label Should the frontend label be displayed in the admin even if an admin label is configured.
|
||||
* @param string $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_label( $force_frontend_label, $value ) {
|
||||
$field_label = parent::get_field_label( $force_frontend_label, $value );
|
||||
|
||||
// Checking the defined product name.
|
||||
if ( ! rgempty( $this->id . '.1', $value ) ) {
|
||||
$field_label = rgar( $value, $this->id . '.1' );
|
||||
}
|
||||
|
||||
if ( $this->disableQuantity || ! $this->get_context_property( 'rendering_form' ) ) {
|
||||
$label = esc_html( $field_label );
|
||||
} else {
|
||||
$product_quantity_sub_label = $this->get_product_quantity_label( $this->formId );
|
||||
$label = '<span class="gform-field-label gfield_label_product">' . esc_html( $field_label ) . '</span>' . ' <span class="screen-reader-text">' . $product_quantity_sub_label . '</span>';
|
||||
}
|
||||
return $label;
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
if ( is_array( $value ) && ! empty( $value ) ) {
|
||||
$product_name = trim( $value[ $this->id . '.1' ] );
|
||||
$price = trim( $value[ $this->id . '.2' ] );
|
||||
$quantity = trim( $value[ $this->id . '.3' ] );
|
||||
|
||||
$product_details = $product_name;
|
||||
|
||||
if ( ! rgblank( $quantity ) ) {
|
||||
$product_details .= ', ' . esc_html__( 'Qty: ', 'gravityforms' ) . $quantity;
|
||||
}
|
||||
|
||||
if ( ! rgblank( $price ) ) {
|
||||
$product_details .= ', ' . esc_html__( 'Price: ', 'gravityforms' ) . GFCommon::format_number( $price, 'currency', $currency );
|
||||
}
|
||||
|
||||
return $product_details;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to be performed after the field has been converted to an object.
|
||||
*
|
||||
* @since 2.4.8.2
|
||||
*/
|
||||
public function post_convert_field() {
|
||||
parent::post_convert_field();
|
||||
|
||||
// Ensure the choices property is not an array to prevent issues with some features such as the conditional logic reset to default.
|
||||
$this->choices = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_SingleProduct() );
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_SingleShipping extends GF_Field {
|
||||
|
||||
public $type = 'singleshipping';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--shipping';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'base_price_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$currency = $is_entry_detail && ! empty( $entry ) ? $entry['currency'] : '';
|
||||
|
||||
$price = ! empty( $value ) ? $value : $this->basePrice;
|
||||
if ( empty( $price ) ) {
|
||||
$price = 0;
|
||||
}
|
||||
$price = esc_attr( GFCommon::to_money( $price ) );
|
||||
|
||||
return "<div class='ginput_container ginput_container_singleshipping'>
|
||||
<input type='text' readonly class='ginput_shipping_price gform-text-input-reset' id='{$field_id}' name='input_{$id}' value='{$price}' />
|
||||
</div>";
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
return GFCommon::to_money( $value, $currency );
|
||||
}
|
||||
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$price_number = GFCommon::to_number( $this->basePrice );
|
||||
$this->basePrice = GFCommon::to_money( $price_number );
|
||||
}
|
||||
|
||||
public function get_value_default() {
|
||||
$value = $this->is_form_editor() ? $this->defaultValue : GFCommon::replace_variables_prepopulate( $this->defaultValue );
|
||||
if( rgblank( $value ) ) {
|
||||
$value = $this->basePrice;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to be performed after the field has been converted to an object.
|
||||
*
|
||||
* @since 2.4.8.2
|
||||
*/
|
||||
public function post_convert_field() {
|
||||
parent::post_convert_field();
|
||||
|
||||
// Ensure the choices property is not an array to prevent issues with some features such as the conditional logic reset to default.
|
||||
$this->choices = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_SingleShipping() );
|
||||
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Submit extends GF_Field {
|
||||
|
||||
public $type = 'submit';
|
||||
|
||||
public $position = 'last';
|
||||
|
||||
public function __construct( $data = array() ) {
|
||||
add_filter( 'gform_pre_render', array( $this, 'inject_inline_button' ), 100 );
|
||||
|
||||
parent::__construct( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field title.
|
||||
*
|
||||
* The submit button editor field title is declared in gf_vars['button'] instead of here.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public function get_form_editor_field_title() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field description.
|
||||
*
|
||||
* The submit button editor field description is declared in gf_vars['buttonDescription'] instead of here.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--smart-button';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class names of the settings which should be available on the field in the form editor.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_submit_setting',
|
||||
'submit_text_setting',
|
||||
'submit_type_setting',
|
||||
'submit_image_setting',
|
||||
'submit_width_setting',
|
||||
'submit_location_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor button.
|
||||
*
|
||||
* This field is automatically added to the form, so it doesn't have a button.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public function get_form_editor_button() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This field supports conditional logic.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result (bool) by setting $this->failed_validation.
|
||||
* Return the validation message (string) by setting $this->validation_message.
|
||||
*
|
||||
* @since 2.4.11
|
||||
*
|
||||
* @param string|array $value The field value from get_value_submission().
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*/
|
||||
public function validate( $value, $form ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if the field markup should not be reloaded after AJAX save.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function disable_ajax_reload() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML markup for the field's containing element.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $atts Container attributes.
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container( $atts, $form ) {
|
||||
|
||||
// Add a data attribute to the container div so that we can target it in the layout editor.
|
||||
$atts['data-field-class'] = 'gform_editor_submit_container';
|
||||
$atts['data-field-position'] = rgar( $form['button'], 'location' ) ? $form['button']['location'] : 'bottom';
|
||||
$atts['id'] = 'field_submit';
|
||||
|
||||
return parent::get_field_container( $atts, $form );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field inner markup.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string|array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
* @param null|array $entry Null or the Entry Object currently being edited.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$class = esc_attr( 'gform-button gform-button--white ' );
|
||||
$default_text = __( 'Submit', 'gravityforms' );
|
||||
$button = rgar( $form, 'button', array( 'type' => 'link' ) );
|
||||
|
||||
$inline = rgar( $form['button'], 'location', 'bottom' );
|
||||
|
||||
// If we're in the editor or the button is inline, display the button. Otherwise, the button will be added to the footer in form_display.php.
|
||||
if ( $is_form_editor || 'inline' == $inline ) {
|
||||
$submit = GFFormDisplay::get_form_button( $form_id, "gform_submit_button_{$form_id}", $button, $default_text, $class, $default_text, 0 );
|
||||
return gf_apply_filters( array( 'gform_submit_button', $form_id ), $submit, $form );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field markup; including field label, description, validation, and the form editor admin buttons.
|
||||
*
|
||||
* The {FIELD} placeholder will be replaced in GFFormDisplay::get_field_content with the markup returned by GF_Field::get_field_input().
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string|array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
* @param bool $force_frontend_label Should the frontend label be displayed in the admin even if an admin label is configured.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_content( $value, $force_frontend_label, $form ) {
|
||||
|
||||
$admin_buttons = $this->get_admin_buttons();
|
||||
|
||||
$admin_hidden_markup = ( $this->visibility == 'hidden' ) ? $this->get_hidden_admin_markup() : '';
|
||||
|
||||
$field_content = sprintf( "%s%s{FIELD}", $admin_buttons, $admin_hidden_markup );
|
||||
|
||||
return $field_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the submit button as a field if it is inline. Target of the gform_pre_render filter.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $form The form object.
|
||||
*
|
||||
* @return array Returns the new form object
|
||||
*/
|
||||
public function inject_inline_button( $form ) {
|
||||
|
||||
if ( empty( $form ) || rgars( $form, 'button/location' ) !== 'inline' || $this->is_form_editor() || $this->is_entry_detail_edit() ) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
$is_injected = (bool) GFFormsModel::get_fields_by_type( $form, array( $this->type ) );
|
||||
if ( ! $is_injected ) {
|
||||
$form['fields'][] = $this;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate CSS Grid class for the column span of the field.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_css_grid_class( $form = '' ) {
|
||||
$span = rgar( $form['button'], 'layoutGridColumnSpan', '12' );
|
||||
switch ( $span ) {
|
||||
case 12:
|
||||
$class = 'gfield--width-full';
|
||||
break;
|
||||
case 11:
|
||||
$class = 'gfield--width-eleven-twelfths';
|
||||
break;
|
||||
case 10:
|
||||
$class = 'gfield--width-five-sixths';
|
||||
break;
|
||||
case 9:
|
||||
$class = 'gfield--width-three-quarter';
|
||||
break;
|
||||
case 8:
|
||||
$class = 'gfield--width-two-thirds';
|
||||
break;
|
||||
case 7:
|
||||
$class = 'gfield--width-seven-twelfths';
|
||||
break;
|
||||
case 6:
|
||||
$class = 'gfield--width-half';
|
||||
break;
|
||||
case 5:
|
||||
$class = 'gfield--width-five-twelfths';
|
||||
break;
|
||||
case 4:
|
||||
$class = 'gfield--width-third';
|
||||
break;
|
||||
case 3:
|
||||
$class = 'gfield--width-quarter';
|
||||
break;
|
||||
case 2:
|
||||
$class = 'gfield--width-one-sixth';
|
||||
break;
|
||||
case 1:
|
||||
$class = 'gfield--width-one-twelfth';
|
||||
break;
|
||||
default:
|
||||
$class = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Submit() );
|
||||
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Text extends GF_Field {
|
||||
|
||||
public $type = 'text';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Single Line Text', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit a single line of text.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--single-line-text';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'input_mask_setting',
|
||||
'maxlen_setting',
|
||||
'password_field_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'autocomplete_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result (bool) by setting $this->failed_validation.
|
||||
* Return the validation message (string) by setting $this->validation_message.
|
||||
*
|
||||
* @since 2.4.11
|
||||
*
|
||||
* @param string|array $value The field value from get_value_submission().
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*/
|
||||
public function validate( $value, $form ) {
|
||||
|
||||
if ( ! $this->maxLength || ! is_numeric( $this->maxLength ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( GFCommon::safe_strlen( $value ) > $this->maxLength ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'The text entered exceeds the maximum number of characters.', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$html_input_type = 'text';
|
||||
|
||||
if ( $this->enablePasswordInput && ! $is_entry_detail ) {
|
||||
$html_input_type = 'password';
|
||||
}
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$value = esc_attr( $value );
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
|
||||
$max_length = is_numeric( $this->maxLength ) ? "maxlength='{$this->maxLength}'" : '';
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
$autocomplete = $this->enableAutocomplete ? $this->get_field_autocomplete_attribute() : '';
|
||||
|
||||
// For Post Tags, Use the WordPress built-in class "howto" in the form editor.
|
||||
$text_hint = '';
|
||||
if ( $this->type === 'post_tags' ) {
|
||||
$text_hint_class = $is_form_editor ? 'howto' : 'gfield_post_tags_hint gfield_description';
|
||||
$text_hint = '<p class="' . $text_hint_class . '" id="' . $field_id . '_desc">' . gf_apply_filters( array(
|
||||
'gform_post_tags_hint',
|
||||
$form_id,
|
||||
$this->id,
|
||||
), esc_html__( 'Separate tags with commas', 'gravityforms' ), $form_id ) . '</p>';
|
||||
}
|
||||
|
||||
$input = "<input name='input_{$id}' id='{$field_id}' type='{$html_input_type}' value='{$value}' class='{$class}' {$max_length} {$aria_describedby} {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text} {$autocomplete} /> {$text_hint}";
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_text'>%s</div>", $input );
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return in_array( $this->type, array( 'post_custom_field', 'post_tags' ) ) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets merge tag values.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GF_Field::get_allowable_tags()
|
||||
*
|
||||
* @param array|string $value The value of the input.
|
||||
* @param string $input_id The input ID to use.
|
||||
* @param array $entry The Entry Object.
|
||||
* @param array $form The Form Object
|
||||
* @param string $modifier The modifier passed.
|
||||
* @param array|string $raw_value The raw value of the input.
|
||||
* @param bool $url_encode If the result should be URL encoded.
|
||||
* @param bool $esc_html If the HTML should be escaped.
|
||||
* @param string $format The format that the value should be.
|
||||
* @param bool $nl2br If the nl2br function should be used.
|
||||
*
|
||||
* @return string The processed merge tag.
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
|
||||
if ( $format === 'html' ) {
|
||||
$value = $raw_value;
|
||||
if ( $nl2br ) {
|
||||
$value = nl2br( $value );
|
||||
}
|
||||
|
||||
$form_id = absint( $form['id'] );
|
||||
$allowable_tags = $this->get_allowable_tags( $form_id );
|
||||
|
||||
if ( $allowable_tags === false ) {
|
||||
// The value is unsafe so encode the value.
|
||||
$return = esc_html( $value );
|
||||
} else {
|
||||
// The value contains HTML but the value was sanitized before saving.
|
||||
$return = $value;
|
||||
}
|
||||
} else {
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value safe for displaying on the entry list page.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GF_Field::get_allowable_tags()
|
||||
*
|
||||
* @param string $value The field value.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param string $field_id The field or input ID currently being processed.
|
||||
* @param array $columns The properties for the columns being displayed on the entry list page.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$form_id = absint( $form['id'] );
|
||||
$allowable_tags = $this->get_allowable_tags( $form_id );
|
||||
|
||||
if ( $allowable_tags === false ) {
|
||||
// The value is unsafe so encode the value.
|
||||
$return = esc_html( $value );
|
||||
} else {
|
||||
// The value contains HTML but the value was sanitized before saving.
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value safe for displaying on the entry detail page and for the {all_fields} merge tag.
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param string $currency The entry currency code.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param string $media The location where the value will be displayed. Possible values: screen or email.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( $format === 'html' ) {
|
||||
$value = nl2br( $value );
|
||||
|
||||
$allowable_tags = $this->get_allowable_tags();
|
||||
|
||||
if ( $allowable_tags === false ) {
|
||||
// The value is unsafe so encode the value.
|
||||
$return = esc_html( $value );
|
||||
} else {
|
||||
// The value contains HTML but the value was sanitized before saving.
|
||||
$return = $value;
|
||||
}
|
||||
} else {
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the hint text to aria-describedby.
|
||||
*
|
||||
* @param array $extra_ids any extra ids that should be added to the describedby attribute.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_aria_describedby( $extra_ids = array() ) {
|
||||
if ( $this->type === 'text' || $this->type === 'post_custom_field' ) {
|
||||
return parent::get_aria_describedby( $extra_ids );
|
||||
}
|
||||
|
||||
$id = (int) $this->id;
|
||||
$form_id = (int) $this->formId;
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$describedby = '';
|
||||
if ( $this->inputType === 'text' || empty( $this->inputType ) ) {
|
||||
$describedby .= "{$field_id}_desc";
|
||||
}
|
||||
|
||||
if ( ! empty( $this->description ) ) {
|
||||
$describedby .= " gfield_description_{$form_id}_{$id}";
|
||||
}
|
||||
|
||||
if ( $this->failed_validation ) {
|
||||
$describedby .= " validation_message_{$this->formId}_{$this->id}";
|
||||
}
|
||||
|
||||
if ( ! empty( $extra_ids ) ) {
|
||||
$describedby .= implode( ' ', $extra_ids );
|
||||
}
|
||||
|
||||
return empty( $describedby ) ? '' : 'aria-describedby="' . $describedby . '"';
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Text() );
|
||||
@@ -0,0 +1,425 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Textarea extends GF_Field {
|
||||
|
||||
public $type = 'textarea';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Paragraph Text', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit multiple lines of text.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--paragraph-text';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'maxlen_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'default_value_textarea_setting',
|
||||
'placeholder_textarea_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'rich_text_editor_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function allow_html() {
|
||||
return empty( $this->useRichTextEditor ) ? false : true;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
global $current_screen;
|
||||
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$is_admin = $is_entry_detail || $is_form_editor;
|
||||
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
$size = $this->size;
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$maxlength_attribute = is_numeric( $this->maxLength ) ? "maxlength='{$this->maxLength}'" : '';
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
if ( $this->get_allowable_tags() === false ) {
|
||||
$value = esc_textarea( $value );
|
||||
} else {
|
||||
$value = wp_kses_post( $value );
|
||||
}
|
||||
|
||||
//see if the field is set to use the rich text editor
|
||||
if ( ! $is_admin && $this->is_rich_edit_enabled() && ( ! $current_screen || ( $current_screen && ! rgobj( $current_screen, 'is_block_editor' ) ) ) ) {
|
||||
//placeholders cannot be used with the rte; message displayed in admin when this occurs
|
||||
//field cannot be used in conditional logic by another field; message displayed in admin and field removed from conditional logic drop down
|
||||
$tabindex = GFCommon::$tab_index > 0 ? GFCommon::$tab_index ++ : '';
|
||||
|
||||
add_filter( 'mce_buttons', array( $this, 'filter_mce_buttons' ), 10, 2 );
|
||||
add_filter( 'mce_buttons_2', array( $this, 'filter_mce_buttons' ), 10, 2 );
|
||||
add_filter( 'mce_buttons_3', array( $this, 'filter_mce_buttons' ), 10, 2 );
|
||||
add_filter( 'mce_buttons_4', array( $this, 'filter_mce_buttons' ), 10, 2 );
|
||||
|
||||
/**
|
||||
* Filters the field options for the rich text editor.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $editor_settings Array of settings that can be changed.
|
||||
* @param object $this The field object
|
||||
* @param array $form Current form object
|
||||
* @param array $entry Current entry object, if available
|
||||
*
|
||||
* Additional filters for specific form and fields IDs.
|
||||
*/
|
||||
$editor_settings = apply_filters( 'gform_rich_text_editor_options', array(
|
||||
'textarea_name' => 'input_' . $id,
|
||||
'wpautop' => true,
|
||||
'editor_class' => $class,
|
||||
'editor_height' => rgar( array( 'small' => 110, 'medium' => 180, 'large' => 280 ), $this->size ? $this->size : 'medium' ),
|
||||
'tabindex' => $tabindex,
|
||||
'media_buttons' => false,
|
||||
'quicktags' => false,
|
||||
'tinymce' => array( 'init_instance_callback' => "function (editor) {
|
||||
editor.on( 'keyup paste mouseover', function (e) {
|
||||
var content = editor.getContent( { format: 'text' } ).trim();
|
||||
var textarea = jQuery( '#' + editor.id );
|
||||
textarea.val( content ).trigger( 'keyup' ).trigger( 'paste' ).trigger( 'mouseover' );
|
||||
|
||||
|
||||
});}" ),
|
||||
), $this, $form, $entry );
|
||||
|
||||
$editor_settings = apply_filters( sprintf( 'gform_rich_text_editor_options_%d', $form['id'] ), $editor_settings, $this, $form, $entry );
|
||||
$editor_settings = apply_filters( sprintf( 'gform_rich_text_editor_options_%d_%d', $form['id'], $this->id ), $editor_settings, $this, $form, $entry );
|
||||
|
||||
if ( ! has_action( 'wp_tiny_mce_init', array( __class__, 'start_wp_tiny_mce_init_buffer' ) ) ) {
|
||||
add_action( 'wp_tiny_mce_init', array( __class__, 'start_wp_tiny_mce_init_buffer' ) );
|
||||
}
|
||||
|
||||
ob_start();
|
||||
wp_editor( $value, $field_id, $editor_settings );
|
||||
$input = ob_get_clean();
|
||||
|
||||
remove_filter( 'mce_buttons', array( $this, 'filter_mce_buttons' ), 10 );
|
||||
remove_filter( 'mce_buttons_2', array( $this, 'filter_mce_buttons' ), 10 );
|
||||
remove_filter( 'mce_buttons_3', array( $this, 'filter_mce_buttons' ), 10 );
|
||||
remove_filter( 'mce_buttons_4', array( $this, 'filter_mce_buttons' ), 10 );
|
||||
} else {
|
||||
|
||||
$input = '';
|
||||
$input_style = '';
|
||||
|
||||
// RTE preview
|
||||
if ( $this->is_form_editor() ) {
|
||||
$display = $this->useRichTextEditor ? 'block' : 'none';
|
||||
$input_style = $this->useRichTextEditor ? 'style="display:none;"' : '';
|
||||
$size = $this->size ? $this->size : 'medium';
|
||||
$input = "<div id='{$field_id}_rte_preview' class='gform-rte-preview {$size}' style='display:{$display}'>
|
||||
<ul class='rte_preview_header'>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M7.761 19c-.253 0-.44-.06-.56-.18-.12-.12-.18-.307-.18-.56l-.02-12.52c0-.267.08-.457.2-.57.12-.113.307-.17.56-.17h5.019c1.56 0 2.723.317 3.49.95.767.633 1.15 1.497 1.15 2.59 0 .667-.21 1.283-.63 1.85-.42.567-.937.963-1.55 1.19l.02.08c.387.067.793.247 1.22.54.427.293.787.677 1.08 1.15.293.473.44 1.01.44 1.61 0 1.32-.427 2.323-1.28 3.01-.853.687-2.12 1.03-3.8 1.03H7.761zm4.969-8.26c.687 0 1.237-.17 1.65-.51.414-.34.621-.77.621-1.29 0-1.147-.757-1.72-2.271-1.72H9.28v3.52h3.45zm.59 6.02c.725 0 1.283-.17 1.674-.51.39-.34.586-.823.586-1.45 0-.587-.223-1.037-.67-1.35-.446-.313-1.088-.47-1.925-.47H9.28v3.78h4.04z' fill='#555d66' stroke='none' stroke-width='1' fill-rule='evenodd'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' ersion='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M16.746 4.723l-.176.84h-.263c-.638 0-1.097.12-1.377.36-.28.242-.47.6-.567 1.075l-2.07 9.805c-.059.28-.088.465-.088.556 0 .534.482.801 1.445.801h.254l-.175.84h-5.82l.155-.84h.264c1.107 0 1.761-.478 1.963-1.435l2.08-9.805c.052-.247.078-.433.078-.557 0-.534-.482-.8-1.445-.8h-.254l.176-.84h5.82z' fill='#555d66' stroke='none' stroke-width='1' fill-rule='evenodd'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 48 48' version='1.1' xmlns='http://www.w3.org/2000/svg'><g stroke='none' stroke-width='1' fill='#555d66' fill-rule='evenodd'><circle cx='11' cy='14' r='3'/><circle cx='11' cy='24' r='3'/><circle cx='11' cy='34' r='3'/><path opacity='.2' d='M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z'/></g></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 48 48' version='1.1' xmlns='http://www.w3.org/2000/svg'><g stroke='none' stroke-width='1' fill='#555d66' fill-rule='evenodd'><path opacity='.2' d='M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z'/><path d='M10.054 17v-4.769H9.98l-1.47 1.013v-1.166l1.549-1.067h1.249V17h-1.254zm3.557.112c-.444 0-.734-.303-.734-.722 0-.42.29-.718.734-.718.449 0 .735.299.735.718 0 .42-.286.722-.735.722zm-5.076 5.692c0-1.158.889-1.947 2.184-1.947 1.249 0 2.12.718 2.12 1.748 0 .651-.352 1.212-1.39 2.187l-1.146 1.092v.074h2.624V27H8.606v-.876l1.955-1.913c.842-.822 1.054-1.133 1.054-1.523 0-.482-.39-.822-.938-.822-.581 0-.98.382-.98.934v.025H8.536v-.021zm6.35 4.308c-.444 0-.734-.303-.734-.722 0-.42.29-.718.734-.718.449 0 .735.299.735.718 0 .42-.286.722-.735.722zm-4.818 7.29v-.934h.73c.569 0 .955-.332.955-.822 0-.481-.374-.788-.959-.788-.58 0-.967.328-1 .846H8.635c.042-1.133.884-1.847 2.191-1.847 1.229 0 2.113.673 2.113 1.615 0 .693-.436 1.233-1.104 1.37v.074c.822.092 1.336.64 1.336 1.428 0 1.05-.987 1.81-2.353 1.81-1.336 0-2.241-.74-2.295-1.868h1.2c.037.506.464.826 1.108.826.626 0 1.062-.353 1.062-.863 0-.523-.41-.847-1.083-.847h-.743zm4.765 2.71c-.445 0-.735-.303-.735-.722 0-.42.29-.718.735-.718.448 0 .734.299.734.718 0 .42-.286.722-.734.722z'/></g></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M7.5 17h.882a1 1 0 00.894-.553L11 13V8a1 1 0 00-1-1H6a1 1 0 00-1 1v4a1 1 0 001 1h2l-1.33 2.658A.927.927 0 007.5 17zm8 0h.882a1 1 0 00.894-.553L19 13V8a1 1 0 00-1-1h-4a1 1 0 00-1 1v4a1 1 0 001 1h2l-1.33 2.658A.927.927 0 0015.5 17z' fill='#555d66' fill-rule='nonzero' stroke='none' stroke-width='1'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M5 5h14a1 1 0 010 2H5a1 1 0 110-2zm0 4h8a1 1 0 010 2H5a1 1 0 110-2zm0 8h8a1 1 0 010 2H5a1 1 0 010-2zm0-4h14a1 1 0 010 2H5a1 1 0 010-2z' fill='#555d66' stroke='none' stroke-width='1' fill-rule='evenodd'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M5 5h14a1 1 0 010 2H5a1 1 0 110-2zm3 4h8a1 1 0 010 2H8a1 1 0 110-2zm0 8h8a1 1 0 010 2H8a1 1 0 010-2zm-3-4h14a1 1 0 010 2H5a1 1 0 010-2z' fill='#555d66' stroke='none' stroke-width='1' fill-rule='evenodd'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M5 5h14a1 1 0 010 2H5a1 1 0 110-2zm6 4h8a1 1 0 010 2h-8a1 1 0 010-2zm0 8h8a1 1 0 010 2h-8a1 1 0 010-2zm-6-4h14a1 1 0 010 2H5a1 1 0 010-2z' fill='#555d66' stroke='none' stroke-width='1' fill-rule='evenodd'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M6.19 12.345a.97.97 0 011.653.683.966.966 0 01-.283.684l-2.055 2.052a1.932 1.932 0 000 2.735 1.94 1.94 0 002.74 0l4.794-4.787a.966.966 0 000-1.367.966.966 0 010-1.368.97.97 0 011.37 0 2.898 2.898 0 010 4.103l-4.795 4.787a3.879 3.879 0 01-5.48 0 3.864 3.864 0 010-5.47l2.056-2.053v.001zm11.62-.69a.97.97 0 01-1.653-.684c0-.256.102-.502.283-.683l2.055-2.052a1.932 1.932 0 000-2.735 1.94 1.94 0 00-2.74 0l-4.793 4.787a.966.966 0 000 1.367.966.966 0 010 1.368.97.97 0 01-1.37 0 2.898 2.898 0 010-4.103l4.795-4.787a3.879 3.879 0 015.48 0 3.864 3.864 0 010 5.47l-2.057 2.053v-.001z' fill='#555d66' fill-rule='nonzero' stroke='none' stroke-width='1'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M15.32 9.937L14.063 8.68l2.902-2.902h-2.298a.889.889 0 110-1.778h4.444c.491 0 .889.398.889.889v4.444a.889.889 0 11-1.778 0V7.035L15.32 9.937zm0 4.126l2.902 2.902v-2.298a.889.889 0 111.778 0v4.444c0 .491-.398.889-.889.889h-4.444a.889.889 0 110-1.778h2.298l-2.902-2.902 1.257-1.257zM9.937 15.32l-2.902 2.902h2.298a.889.889 0 110 1.778H4.89A.889.889 0 014 19.111v-4.444a.889.889 0 111.778 0v2.298l2.902-2.902 1.257 1.257zM8.68 9.937L5.778 7.035v2.298a.889.889 0 01-1.778 0V4.89C4 4.398 4.398 4 4.889 4h4.444a.889.889 0 010 1.778H7.035L9.937 8.68 8.68 9.937z' fill='#555d66' fill-rule='nonzero' stroke='none' stroke-width='1'/></svg></li>
|
||||
<li class='icon'><svg width='24' height='24' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg'><path d='M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z' fill='#555d66' fill-rule='nonzero' stroke='none' stroke-width='1'/></svg></li>
|
||||
</ul>
|
||||
</div>";
|
||||
}
|
||||
|
||||
$input .= "<textarea name='input_{$id}' id='{$field_id}' class='textarea {$class}' {$tabindex} {$aria_describedby} {$maxlength_attribute} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text} {$input_style} rows='10' cols='50'>{$value}</textarea>";
|
||||
|
||||
}
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_textarea'>%s</div>", $input );
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
if ( ! is_numeric( $this->maxLength ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->useRichTextEditor ) {
|
||||
$value = wp_specialchars_decode( $value );
|
||||
}
|
||||
|
||||
// Clean the string of characters not counted by the textareaCounter plugin.
|
||||
$value = strip_tags( $value );
|
||||
$value = str_replace( "\r", '', $value );
|
||||
$value = trim( $value );
|
||||
|
||||
if ( GFCommon::safe_strlen( $value ) > $this->maxLength ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'The text entered exceeds the maximum number of characters.', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public static function start_wp_tiny_mce_init_buffer() {
|
||||
ob_start();
|
||||
add_action( 'after_wp_tiny_mce', array( __class__, 'end_wp_tiny_mce_init_buffer' ), 1 );
|
||||
}
|
||||
|
||||
public static function end_wp_tiny_mce_init_buffer() {
|
||||
|
||||
$script = ob_get_clean();
|
||||
$pattern = '/(<script.*>)([\s\S]+)(<\/script>)/';
|
||||
|
||||
preg_match_all( $pattern, $script, $matches, PREG_SET_ORDER );
|
||||
|
||||
// Fix editor height issue: https://core.trac.wordpress.org/ticket/45461.
|
||||
$wp_version = get_bloginfo( 'version' );
|
||||
$height_issue_fix = version_compare( $wp_version, '5.0', '>=' ) && version_compare( $wp_version, '5.2', '<' ) ? ' gform_post_conditional_logic' : '';
|
||||
|
||||
foreach ( $matches as $match ) {
|
||||
|
||||
list( $search, $open_tag, $guts, $close_tag ) = $match;
|
||||
|
||||
$custom = "\tif ( typeof current_page === 'undefined' ) { return; }\n\twindow.gformInitTinymce = function(){\n\tfor( var id in tinymce.editors ) { tinymce.EditorManager.remove( tinymce.editors[id] ); }";
|
||||
$replace = sprintf(
|
||||
"%s\nfunction gformInitMCEInstances() { jQuery( document ).on( 'gform_post_render%s', function( event, form_id, current_page ) { \n%s\n%s\n\t}\n\tgformInitTinymce();\n} );}; gform.initializeOnLoaded( gformInitMCEInstances );\n%s",
|
||||
$open_tag,
|
||||
$height_issue_fix,
|
||||
$custom,
|
||||
$guts,
|
||||
$close_tag
|
||||
);
|
||||
$script = str_replace( $search, $replace, $script );
|
||||
|
||||
}
|
||||
|
||||
echo $script;
|
||||
|
||||
}
|
||||
|
||||
public function filter_mce_buttons( $mce_buttons, $editor_id ) {
|
||||
|
||||
$remove_key = array_search( 'wp_more', $mce_buttons );
|
||||
if ( $remove_key !== false ) {
|
||||
unset( $mce_buttons[ $remove_key ] );
|
||||
}
|
||||
|
||||
// Get current filter to detect which mce_buttons core filter is running.
|
||||
$current_filter = current_filter();
|
||||
|
||||
// Depending on the current mce_buttons filter, set variable to support filtering all potential rows.
|
||||
switch ( $current_filter ) {
|
||||
|
||||
case 'mce_buttons_2':
|
||||
$mce_filter = '_row_two';
|
||||
break;
|
||||
|
||||
case 'mce_buttons_3':
|
||||
$mce_filter = '_row_three';
|
||||
break;
|
||||
|
||||
case 'mce_buttons_4':
|
||||
$mce_filter = '_row_four';
|
||||
break;
|
||||
|
||||
default:
|
||||
$mce_filter = '';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the buttons within the TinyMCE editor
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $mce_buttons Buttons to be included.
|
||||
* @param string $editor_id HTML ID of the field.
|
||||
* @param object $this The field object
|
||||
*
|
||||
* Additional filters for specific form and fields IDs.
|
||||
*/
|
||||
$mce_buttons = gf_apply_filters( array( 'gform_rich_text_editor_buttons' . $mce_filter, $this->formId, $this->id ), $mce_buttons, $editor_id, $this );
|
||||
|
||||
return $mce_buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for display on the entry detail page and for the {all_fields} merge tag.
|
||||
* Return a value that's safe to display for the context of the given $format.
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param string $currency The entry currency code.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param string $media The location where the value will be displayed. Possible values: screen or email.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
|
||||
if ( $format === 'html' ) {
|
||||
|
||||
$allowable_tags = $this->get_allowable_tags();
|
||||
|
||||
if ( $allowable_tags === false ) {
|
||||
// The value is unsafe so encode the value.
|
||||
$value = esc_html( $value );
|
||||
$return = nl2br( $value );
|
||||
|
||||
} else {
|
||||
// The value contains HTML but the value was sanitized before saving.
|
||||
$return = wpautop( $value );
|
||||
}
|
||||
} else {
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for when the field/input merge tag is processed. Not called for the {all_fields} merge tag.
|
||||
*
|
||||
* Return a value that is safe for the context specified by $format.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @param string|array $value The field value. Depending on the location the merge tag is being used the following functions may have already been applied to the value: esc_html, nl2br, and urlencode.
|
||||
* @param string $input_id The field or input ID from the merge tag currently being processed.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $modifier The merge tag modifier. e.g. value
|
||||
* @param string|array $raw_value The raw field value from before any formatting was applied to $value.
|
||||
* @param bool $url_encode Indicates if the urlencode function may have been applied to the $value.
|
||||
* @param bool $esc_html Indicates if the esc_html function may have been applied to the $value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param bool $nl2br Indicates if the nl2br function may have been applied to the $value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
|
||||
if ( $format === 'html' ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$allowable_tags = $this->get_allowable_tags( $form_id );
|
||||
|
||||
if ( $allowable_tags === false ) {
|
||||
// The raw value is unsafe so escape it.
|
||||
$return = esc_html( $raw_value );
|
||||
// Run nl2br() to preserve line breaks when auto-formatting is disabled on notifications/confirmations.
|
||||
$return = nl2br( $return );
|
||||
} else {
|
||||
// The value contains HTML but the value was sanitized before saving.
|
||||
$return = wpautop( $raw_value );
|
||||
}
|
||||
} else {
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the RTE can be enabled for the current field and user.
|
||||
*
|
||||
* @since 2.2.5.14
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_rich_edit_enabled() {
|
||||
if ( ! $this->useRichTextEditor ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
global $wp_rich_edit;
|
||||
$wp_rich_edit = null;
|
||||
|
||||
add_filter( 'get_user_option_rich_editing', array( $this, 'filter_user_option_rich_editing' ) );
|
||||
$user_can_rich_edit = user_can_richedit();
|
||||
remove_filter( 'get_user_option_rich_editing', array( $this, 'filter_user_option_rich_editing' ) );
|
||||
|
||||
return $user_can_rich_edit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the rich_editing option for the current user.
|
||||
*
|
||||
* @since 2.2.5.14
|
||||
*
|
||||
* @param string $value The value of the rich_editing option for the current user.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function filter_user_option_rich_editing( $value ) {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Textarea() );
|
||||
@@ -0,0 +1,579 @@
|
||||
<?php
|
||||
|
||||
// If Gravity Forms isn't loaded, bail.
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Field_Time
|
||||
*
|
||||
* Handles Time fields.
|
||||
*
|
||||
* @since Unknown
|
||||
* @uses GF_Field
|
||||
*/
|
||||
class GF_Field_Time extends GF_Field {
|
||||
|
||||
/**
|
||||
* Sets the field type to be used in the field framework.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @var string $type The type of field this is.
|
||||
*/
|
||||
public $type = 'time';
|
||||
|
||||
/**
|
||||
* Sets the title of the field to be used in the form editor.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFCommon::get_field_type_title()
|
||||
* @used-by GFAddOn::get_field_map_choices()
|
||||
* @used-by GFAddOn::prepare_field_select_field()
|
||||
* @used-by GFAddOn::settings_field_map_select()
|
||||
* @used-by GF_Field::get_form_editor_button()
|
||||
*
|
||||
* @return string The field title.
|
||||
*/
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Time', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to submit a time as hours and minutes.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--time';
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the field editor settings that are available for this field.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDetail::inline_scripts()
|
||||
*
|
||||
* @return array Contains the settings available within the field editor.
|
||||
*/
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'sub_labels_setting',
|
||||
'label_placement_setting',
|
||||
'sub_label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'time_format_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'default_input_values_setting',
|
||||
'input_placeholders_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the IDs of required inputs.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_required_inputs_ids() {
|
||||
return array( '1', '2' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default properties.
|
||||
*
|
||||
* Inputs are required for the field to function correctly, so this ensures that the inputs exist.
|
||||
*
|
||||
* @since 2.7.4
|
||||
*
|
||||
* @return array[] Array of default properties.
|
||||
*/
|
||||
public function get_default_properties() {
|
||||
return array(
|
||||
'inputs' => array(
|
||||
array(
|
||||
'id' => "{$this->id}.1",
|
||||
'label' => 'Hour',
|
||||
'name' => '',
|
||||
),
|
||||
array(
|
||||
'id' => "{$this->id}.2",
|
||||
'label' => 'Minute',
|
||||
'name' => '',
|
||||
),
|
||||
array(
|
||||
'id' => "{$this->id}.3",
|
||||
'label' => 'AM/PM',
|
||||
'name' => '',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates the field inputs.
|
||||
*
|
||||
* @since 1.9
|
||||
* @since 2.5.6 Updated to use set_required_error().
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDisplay::validate()
|
||||
* @uses GF_Field_Time::$failed_validation
|
||||
* @uses GF_Field_Time::$validation_message
|
||||
* @uses GF_Field_Time::$timeFormat
|
||||
* @uses GF_Field_Time::$errorMessage
|
||||
*
|
||||
* @param array|string $value The field value or values to validate.
|
||||
* @param array $form The Form Object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validate( $value, $form ) {
|
||||
// Create variable values if time came in one field.
|
||||
if ( ! is_array( $value ) && ! empty( $value ) ) {
|
||||
preg_match( '/^(\d*):(\d*) ?(.*)$/', $value, $matches );
|
||||
$value = array();
|
||||
$value[0] = $matches[1];
|
||||
$value[1] = $matches[2];
|
||||
}
|
||||
|
||||
if ( is_array( $value ) && $this->isRequired ) {
|
||||
$this->set_required_error( $value, true );
|
||||
}
|
||||
|
||||
$hour = rgar( $value, 0 );
|
||||
$minute = rgar( $value, 1 );
|
||||
|
||||
if ( empty( $hour ) && empty( $minute ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$is_valid_format = is_numeric( $hour ) && is_numeric( $minute );
|
||||
|
||||
$min_hour = $this->timeFormat == '24' ? 0 : 1;
|
||||
$max_hour = $this->timeFormat == '24' ? 24 : 12;
|
||||
$max_minute = $hour >= 24 ? 0 : 59;
|
||||
|
||||
if ( ! $is_valid_format || $hour < $min_hour || $hour > $max_hour || $minute < 0 || $minute > $max_minute ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'Please enter a valid time.', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value to use the input ids as the keys before it's used to generate the complex validation message.
|
||||
*
|
||||
* @since 2.6.5
|
||||
*
|
||||
* @param array $value The value to be prepared.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function prepare_complex_validation_value( $value ) {
|
||||
return array(
|
||||
"{$this->id}.1" => rgar( $value, 0 ),
|
||||
"{$this->id}.2" => rgar( $value, 1 ),
|
||||
"{$this->id}.3" => rgar( $value, 2 ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines how the Time field input is shown.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFCommon::get_field_input()
|
||||
* @uses GF_Field::is_entry_detail()
|
||||
* @uses GF_Field::is_form_editor()
|
||||
* @uses GF_Field_Time::$subLabelPlacement
|
||||
* @uses GFFormsModel::get_input()
|
||||
* @uses GF_Field::get_input_placeholder_attribute()
|
||||
* @uses GF_Field::get_tabindex()
|
||||
*
|
||||
* @param array $form The Form Object.
|
||||
* @param string $value The field default value. Defaults to empty string.
|
||||
* @param array|null $entry The Entry Object, if available. Defaults to null.
|
||||
*
|
||||
* @return string The field HTML markup.
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$form_id = absint( $form['id'] );
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$form_sub_label_placement = rgar( $form, 'subLabelPlacement' );
|
||||
$field_sub_label_placement = $this->subLabelPlacement;
|
||||
$colon_pmam_placement = empty( $field_sub_label_placement ) || $field_sub_label_placement == 'hidden_label' ? 'below' : $field_sub_label_placement;
|
||||
$is_sub_label_above = $field_sub_label_placement == 'above' || ( empty( $field_sub_label_placement ) && $form_sub_label_placement == 'above' );
|
||||
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
|
||||
$hour = $minute = $am_selected = $pm_selected = '';
|
||||
|
||||
if ( ! is_array( $value ) && ! empty( $value ) ) {
|
||||
preg_match( '/^(\d*):(\d*) ?(.*)$/', $value, $matches );
|
||||
$hour = esc_attr( $matches[1] );
|
||||
$minute = esc_attr( $matches[2] );
|
||||
$the_rest = strtolower( rgar( $matches, 3 ) );
|
||||
$am_selected = strpos( $the_rest, 'am' ) > -1 ? "selected='selected'" : '';
|
||||
$pm_selected = strpos( $the_rest, 'pm' ) > -1 ? "selected='selected'" : '';
|
||||
} elseif ( is_array( $value ) ) {
|
||||
$value = array_values( $value );
|
||||
$hour = esc_attr( $value[0] );
|
||||
$minute = esc_attr( $value[1] );
|
||||
$am_selected = strtolower( rgar( $value, 2 ) ) == 'am' ? "selected='selected'" : '';
|
||||
$pm_selected = strtolower( rgar( $value, 2 ) ) == 'pm' ? "selected='selected'" : '';
|
||||
}
|
||||
|
||||
$hour_input = GFFormsModel::get_input( $this, $this->id . '.1' );
|
||||
$minute_input = GFFormsModel::get_input( $this, $this->id . '.2' );
|
||||
|
||||
$hour_placeholder_attribute = $this->get_input_placeholder_attribute( $hour_input ) ? $this->get_input_placeholder_attribute( $hour_input ) : "placeholder='" . esc_attr__( 'HH', 'gravityforms' ) . "'";
|
||||
$minute_placeholder_attribute = $this->get_input_placeholder_attribute( $minute_input ) ? $this->get_input_placeholder_attribute( $minute_input ) : "placeholder='" . esc_attr( _x( 'MM', 'Abbreviation: Minutes', 'gravityforms' ) ) . "'";
|
||||
|
||||
$hour_tabindex = $this->get_tabindex();
|
||||
$minute_tabindex = $this->get_tabindex();
|
||||
$ampm_tabindex = $this->get_tabindex();
|
||||
|
||||
$input_type = 'number';
|
||||
|
||||
$max_hour = $this->timeFormat == '24' ? 24 : 12;
|
||||
$hour_html5_attributes = "min='0' max='{$max_hour}' step='1'";
|
||||
$minute_html5_attributes = "min='0' max='59' step='1'";
|
||||
|
||||
$clear_multi_div_open = GFCommon::is_legacy_markup_enabled( $form ) ? '<div class="clear-multi">' : '';
|
||||
$clear_multi_div_close = GFCommon::is_legacy_markup_enabled( $form ) ? '</div>' : '';
|
||||
|
||||
$output_shim = $is_sub_label_above && GFCommon::is_legacy_markup_enabled( $form );
|
||||
|
||||
$ampm_field_style = $is_form_editor && $this->timeFormat == '24' ? "style='display:none;'" : '';
|
||||
if ( $is_form_editor || $this->timeFormat != '24' ) {
|
||||
$am_text = esc_html__( 'AM', 'gravityforms' );
|
||||
$pm_text = esc_html__( 'PM', 'gravityforms' );
|
||||
$ampm_field = "<div class='gfield_time_ampm ginput_container ginput_container_time {$colon_pmam_placement} gform-grid-col' {$ampm_field_style}>
|
||||
" . ( $output_shim ? "<div class='gfield_time_ampm_shim' aria-hidden='true'> </div>" : "" ) . "
|
||||
<select name='input_{$id}[]' id='{$field_id}_3' $ampm_tabindex {$disabled_text}>
|
||||
<option value='am' {$am_selected}>{$am_text}</option>
|
||||
<option value='pm' {$pm_selected}>{$pm_text}</option>
|
||||
</select>
|
||||
<label class='gform-field-label gform-field-label--type-sub am_pm_label screen-reader-text' for='{$field_id}_3'>" . esc_html__( 'AM/PM', 'gravityforms' ) . "</label>
|
||||
</div>";
|
||||
} else {
|
||||
$ampm_field = '';
|
||||
}
|
||||
|
||||
$hour_label_class = $minute_label_class = '';
|
||||
|
||||
if ( rgar( $hour_input, 'customLabel' ) !== '' ) {
|
||||
$hour_label = esc_html( $hour_input['customLabel'] );
|
||||
} else if ( rgar( $hour_input, 'placeholder' ) ) {
|
||||
$hour_label = esc_html__( 'HH', 'gravityforms' );
|
||||
} else {
|
||||
$hour_label = esc_html__( 'Hours', 'gravityforms' );
|
||||
$hour_label_class = " screen-reader-text";
|
||||
}
|
||||
|
||||
if ( rgar( $minute_input, 'customLabel' ) !== '' ) {
|
||||
$minute_label = esc_html( $minute_input['customLabel'] );
|
||||
} else if ( rgar( $minute_input, 'placeholder' ) ) {
|
||||
$minute_label = esc_html( _x( 'MM', 'Abbreviation: Minutes', 'gravityforms' ) );
|
||||
} else {
|
||||
$minute_label = esc_html__( 'Minutes', 'gravityforms' );
|
||||
$minute_label_class = " screen-reader-text";
|
||||
}
|
||||
|
||||
if ( $field_sub_label_placement === 'hidden_label' ) {
|
||||
$hour_label_class = ' hidden_sub_label screen-reader-text';
|
||||
$minute_label_class = ' hidden_sub_label screen-reader-text';
|
||||
}
|
||||
|
||||
$input_values = array(
|
||||
$this->id . '.1' => $hour,
|
||||
$this->id . '.2' => $minute,
|
||||
);
|
||||
|
||||
$hour_aria_attributes = $this->get_aria_attributes( $input_values, '1' );
|
||||
$minute_aria_attributes = $this->get_aria_attributes( $input_values, '2' );
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
$legacy_markup_colon = GFCommon::is_legacy_markup_enabled( $form ) ? '<i>:</i>' : '';
|
||||
$new_markup_colon = GFCommon::is_legacy_markup_enabled( $form ) ? '' : '<div class="' . $colon_pmam_placement . ' hour_minute_colon gform-grid-col">:</div>';
|
||||
|
||||
if ( $is_sub_label_above ) {
|
||||
$markup = "{$clear_multi_div_open}
|
||||
<div class='gfield_time_hour ginput_container ginput_container_time gform-grid-col' id='{$field_id}'>
|
||||
<label class='gform-field-label gform-field-label--type-sub hour_label{$hour_label_class}' for='{$field_id}_1'>{$hour_label}</label>
|
||||
<input type='{$input_type}' maxlength='2' name='input_{$id}[]' id='{$field_id}_1' value='{$hour}' {$hour_tabindex} {$hour_html5_attributes} {$disabled_text} {$hour_placeholder_attribute} {$hour_aria_attributes} {$aria_describedby}/> {$legacy_markup_colon}
|
||||
</div>
|
||||
{$new_markup_colon}
|
||||
<div class='gfield_time_minute ginput_container ginput_container_time gform-grid-col'>
|
||||
<label class='gform-field-label gform-field-label--type-sub minute_label{$minute_label_class}' for='{$field_id}_2'>{$minute_label}</label>
|
||||
<input type='{$input_type}' maxlength='2' name='input_{$id}[]' id='{$field_id}_2' value='{$minute}' {$minute_tabindex} {$minute_html5_attributes} {$disabled_text} {$minute_placeholder_attribute} {$minute_aria_attributes}/>
|
||||
</div>
|
||||
{$ampm_field}
|
||||
{$clear_multi_div_close}";
|
||||
} else {
|
||||
$markup = "{$clear_multi_div_open}
|
||||
<div class='gfield_time_hour ginput_container ginput_container_time gform-grid-col' id='{$field_id}'>
|
||||
<input type='{$input_type}' maxlength='2' name='input_{$id}[]' id='{$field_id}_1' value='{$hour}' {$hour_tabindex} {$hour_html5_attributes} {$disabled_text} {$hour_placeholder_attribute} {$hour_aria_attributes} {$aria_describedby}/> {$legacy_markup_colon}
|
||||
<label class='gform-field-label gform-field-label--type-sub hour_label{$hour_label_class}' for='{$field_id}_1'>{$hour_label}</label>
|
||||
</div>
|
||||
{$new_markup_colon}
|
||||
<div class='gfield_time_minute ginput_container ginput_container_time gform-grid-col'>
|
||||
<input type='{$input_type}' maxlength='2' name='input_{$id}[]' id='{$field_id}_2' value='{$minute}' {$minute_tabindex} {$minute_html5_attributes} {$disabled_text} {$minute_placeholder_attribute} {$minute_aria_attributes}/>
|
||||
<label class='gform-field-label gform-field-label--type-sub minute_label{$minute_label_class}' for='{$field_id}_2'>{$minute_label}</label>
|
||||
</div>
|
||||
{$ampm_field}
|
||||
{$clear_multi_div_close}";
|
||||
}
|
||||
|
||||
|
||||
return sprintf( '<div class="ginput_container ginput_complex gform-grid-row">%s</div>', $markup );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this field expects an array during submission.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_value_submission_array() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if any of the submission values are empty.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDisplay::is_empty()
|
||||
*
|
||||
* @param int $form_id The form ID.
|
||||
*
|
||||
* @return bool True if empty. False otherwise.
|
||||
*/
|
||||
public function is_value_submission_empty( $form_id ) {
|
||||
$value = rgpost( 'input_' . $this->id );
|
||||
|
||||
if ( ! is_array( $value ) ) {
|
||||
return strlen( trim( $value ) ) <= 0;
|
||||
}
|
||||
|
||||
// Ignoring the AM/PM value; it's always set for embedded forms.
|
||||
unset( $value[2] );
|
||||
|
||||
return GFCommon::is_empty_array( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given value is considered empty for this field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string|array $value The value.
|
||||
*
|
||||
* @return bool True if empty. False otherwise.
|
||||
*/
|
||||
public function is_value_empty( $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
foreach ( $value as $input ) {
|
||||
if ( strlen( trim( $input ) ) <= 0 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return strlen( trim( $value ) ) <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the field value to be saved after an entry is submitted.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormsModel::prepare_value()
|
||||
*
|
||||
* @param string $value The value to prepare.
|
||||
* @param array $form The Form Object. Not used.
|
||||
* @param string $input_name The name of the input. Not used.
|
||||
* @param int $lead_id The entry ID. Not used.
|
||||
* @param array $lead The Entry Object. Not used.
|
||||
*
|
||||
* @return array|string The field value, prepared and stripped of tags.
|
||||
*/
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
|
||||
if ( empty( $value ) && ! is_array( $value ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// If $value is a default value and also an array, it will be an associative array; to be safe, let's convert all array $value to numeric.
|
||||
if ( is_array( $value ) ) {
|
||||
$value = array_values( $value );
|
||||
}
|
||||
|
||||
if ( ! is_array( $value ) && ! empty( $value ) ) {
|
||||
preg_match( '/^(\d*):(\d*) ?(.*)$/', $value, $matches );
|
||||
$value = array();
|
||||
$value[0] = $matches[1];
|
||||
$value[1] = $matches[2];
|
||||
$value[2] = rgar( $matches, 3 );
|
||||
}
|
||||
|
||||
$hour = wp_strip_all_tags( $value[0] );
|
||||
$minute = wp_strip_all_tags( $value[1] );
|
||||
$ampm = wp_strip_all_tags( rgar( $value, 2 ) );
|
||||
if ( ! empty( $ampm ) ) {
|
||||
$ampm = " $ampm";
|
||||
}
|
||||
|
||||
if ( ! ( rgblank( $hour ) && rgblank( $minute ) ) ) {
|
||||
$value = sprintf( '%02d:%02d%s', $hour, $minute, $ampm );
|
||||
} else {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JS script to be rendered in the front end of the form.
|
||||
*
|
||||
* @param array $form The Form Object
|
||||
*
|
||||
* @return string Returns a JS script to be processed in the front end.
|
||||
*/
|
||||
public function get_form_inline_script_on_page_render( $form ) {
|
||||
|
||||
//Only return merge tag script if form supports JS merge tags
|
||||
if ( ! GFFormDisplay::has_js_merge_tag( $form ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return "gform.addFilter( 'gform_value_merge_tag_{$form['id']}_{$this->id}', function( value, input, modifier ) { if( modifier === 'label' ) { return false; } var ampm = input.length == 3 ? ' ' + jQuery(input[2]).val() : ''; return jQuery(input[0]).val() + ':' + jQuery(input[1]).val() + ' ' + ampm; } );";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scripts to be included for this field type in the form editor.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_inline_script_on_page_render() {
|
||||
// No support for custom sub AM/PM sub label.
|
||||
return "gform.addAction( 'gform_post_load_field_settings' , function( [ field, form ] ) { if( GetInputType( field ) === 'time' ) { jQuery('.field_custom_input_row_input_' + field.id + '_3').hide(); } } );";
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides GF_Field to prevent the standard input ID from being used.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function get_entry_inputs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the "for" attribute in the field label. Inputs are only allowed one label (a11y) and the inputs already have labels.
|
||||
*
|
||||
* @since 2.4
|
||||
* @access public
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_first_input_id( $form ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes settings for the Time field.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @used-by GFFormDetail::add_field()
|
||||
* @used-by GFFormsModel::sanitize_settings()
|
||||
* @uses GF_Field::sanitize_settings
|
||||
* @uses GF_Field_Time::$timeFormat
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
if ( ! $this->timeFormat || ! in_array( $this->timeFormat, array( 12, 24 ) ) ) {
|
||||
$this->timeFormat = '12';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Register the Time field with the field framework.
|
||||
GF_Fields::register( new GF_Field_Time() );
|
||||
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Total extends GF_Field {
|
||||
|
||||
public $type = 'total';
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'label_setting',
|
||||
'admin_label_setting',
|
||||
'label_placement_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Total', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--total';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML markup for the field's containing element.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $atts Container attributes.
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container( $atts, $form ) {
|
||||
|
||||
// aria-atomic and aria-live need to be added to make the change of the total announced.
|
||||
$atts['aria-atomic'] = 'true';
|
||||
$atts['aria-live'] = 'polite';
|
||||
|
||||
return parent::get_field_container( $atts, $form );
|
||||
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = absint( $form['id'] );
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
if ( $is_entry_detail ) {
|
||||
return "<div class='ginput_container ginput_container_total'>
|
||||
<input type='text' name='input_{$id}' value='{$value}' />
|
||||
</div>";
|
||||
} else {
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return "<div class='ginput_container ginput_container_total'>
|
||||
<span class='ginput_total ginput_total_{$form_id}'>" . GFCommon::to_money( '0' ) . "</span>
|
||||
<input type='hidden' name='input_{$id}' id='{$field_id}' class='gform_hidden'/>
|
||||
</div>";
|
||||
} else {
|
||||
return "<div class='ginput_container ginput_container_total'>
|
||||
<input type='text' readonly name='input_{$id}' id='{$field_id}' value='" . GFCommon::to_money( '0' ) . "' class='gform-text-input-reset ginput_total ginput_total_{$form_id}' />
|
||||
</div>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
return GFCommon::to_money( $value, $currency );
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
$lead = empty( $lead ) ? RGFormsModel::get_lead( $lead_id ) : $lead;
|
||||
$value = GFCommon::get_order_total( $form, $lead );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
return GFCommon::to_money( $value, $entry['currency'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets merge tag values.
|
||||
*
|
||||
* @since Unknown
|
||||
* @access public
|
||||
*
|
||||
* @uses GFCommon::to_number()
|
||||
* @uses GFCommon::to_money()
|
||||
* @uses GFCommon::format_variable_value()
|
||||
*
|
||||
* @param array|string $value The value of the input.
|
||||
* @param string $input_id The input ID to use.
|
||||
* @param array $entry The Entry Object.
|
||||
* @param array $form The Form Object
|
||||
* @param string $modifier The modifier passed.
|
||||
* @param array|string $raw_value The raw value of the input.
|
||||
* @param bool $url_encode If the result should be URL encoded.
|
||||
* @param bool $esc_html If the HTML should be escaped.
|
||||
* @param string $format The format that the value should be.
|
||||
* @param bool $nl2br If the nl2br function should be used.
|
||||
*
|
||||
* @return string The processed merge tag.
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
$format_numeric = in_array( 'price', $this->get_modifiers() );
|
||||
|
||||
$value = $format_numeric ? GFCommon::to_number( $value ) : GFCommon::to_money( $value );
|
||||
|
||||
return GFCommon::format_variable_value( $value, $url_encode, $esc_html, $format );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the field value.
|
||||
*
|
||||
* @since 2.8.2
|
||||
*
|
||||
* @param string $value The submitted value.
|
||||
* @param array $form The form currently being validated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validate( $value, $form ) {
|
||||
if ( ! $this->validateTotal ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// API requests, such as the one used by Convo Forms, are not currently supported.
|
||||
if ( GFFormDisplay::get_submission_context() !== 'form-submit' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$entry = GFFormsModel::get_current_lead( $form );
|
||||
if ( empty( $entry ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$currency_code = rgar( $entry, 'currency' );
|
||||
$currency = new RGCurrency( $currency_code );
|
||||
$expected_value = GFCommon::get_order_total( $form, $entry );
|
||||
$clean_value = GFCommon::to_number( $value, $currency_code );
|
||||
|
||||
if ( $currency->is_zero_decimal() ) {
|
||||
$expected_value_int = (int) $expected_value;
|
||||
$clean_value_int = (int) $clean_value;
|
||||
} else {
|
||||
$expected_value_int = (int) round( $expected_value * 100 );
|
||||
$clean_value_int = (int) round( $clean_value * 100 );
|
||||
}
|
||||
|
||||
if ( $expected_value_int === $clean_value_int ) {
|
||||
return;
|
||||
}
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . sprintf( '(): Amount mismatch (%s - #%d). Submitted: %s. Clean (int): %s. Expected (int): %s.', $this->label, $this->id, var_export( $value, true ), var_export( $clean_value_int, true ), var_export( $expected_value_int, true ) ) );
|
||||
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = sprintf( esc_html__( 'Submitted value (%s) does not match expected value (%s).', 'gravityforms' ), $clean_value ? GFCommon::to_money( $clean_value, $currency_code ) : esc_html( $value ), GFCommon::to_money( $expected_value, $currency_code ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the field properties.
|
||||
*
|
||||
* @since 2.8.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
if ( isset( $this->validateTotal ) ) {
|
||||
$this->validateTotal = (bool) $this->validateTotal;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Total() );
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Website extends GF_Field {
|
||||
|
||||
public $type = 'website';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Website', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to enter a website URL.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--link';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'prepopulate_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'size_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'duplicate_setting',
|
||||
'default_value_setting',
|
||||
'placeholder_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
if ( empty( $value ) || in_array( $value, array( 'http://', 'https://' ) ) ) {
|
||||
$value = '';
|
||||
if ( $this->isRequired ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'This field is required.', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $value ) && ! GFCommon::is_valid_url( $value ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'Please enter a valid Website URL (e.g. https://gravityforms.com).', 'gravityforms' ) : $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$form_id = $form['id'];
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$size = $this->size;
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
$class = $size . $class_suffix;
|
||||
$class = esc_attr( $class );
|
||||
$html_input_type = 'url';
|
||||
|
||||
$placeholder_attribute = $this->get_field_placeholder_attribute();
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
$aria_describedby = $this->get_aria_describedby();
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$value = esc_attr( $value );
|
||||
$class = esc_attr( $class );
|
||||
|
||||
return "<div class='ginput_container ginput_container_website'>
|
||||
<input name='input_{$id}' id='{$field_id}' type='$html_input_type' value='{$value}' class='{$class}' {$tabindex} {$aria_describedby} {$disabled_text} {$placeholder_attribute} {$required_attribute} {$invalid_attribute}/>
|
||||
</div>";
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
$safe_value = esc_url( $value );
|
||||
return GFCommon::is_valid_url( $value ) && $format == 'html' ? "<a href='$safe_value' target='_blank'>$safe_value</a>" : $safe_value;
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
|
||||
if ( empty( $value ) || in_array( $value, array( 'http://', 'https://' ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$value = filter_var( $value, FILTER_VALIDATE_URL );
|
||||
|
||||
return $value ? $value : '';
|
||||
}
|
||||
|
||||
// # FIELD FILTER UI HELPERS ---------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = parent::get_filter_operators();
|
||||
$operators[] = 'contains';
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Website() );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-field.php' );
|
||||
|
||||
class GF_Fields {
|
||||
|
||||
public static $deprecation_notice_fired = false;
|
||||
|
||||
/* @var GF_Field[] */
|
||||
private static $_fields = array();
|
||||
|
||||
public static function register( $field ) {
|
||||
if ( ! is_subclass_of( $field, 'GF_Field' ) ) {
|
||||
throw new Exception( 'Must be a subclass of GF_Field' );
|
||||
}
|
||||
if ( empty( $field->type ) ) {
|
||||
throw new Exception( 'The type must be set' );
|
||||
}
|
||||
if ( isset( self::$_fields[ $field->type ] ) ) {
|
||||
throw new Exception( 'Field type already registered: ' . $field->type );
|
||||
}
|
||||
self::$_fields[ $field->type ] = $field;
|
||||
}
|
||||
|
||||
public static function exists( $field_type ) {
|
||||
return isset( self::$_fields[ $field_type ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field_type
|
||||
*
|
||||
* @return GF_Field
|
||||
*/
|
||||
public static function get_instance( $field_type ) {
|
||||
return isset( self::$_fields[ $field_type ] ) ? self::$_fields[ $field_type ] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for get_instance()
|
||||
*
|
||||
* @param $field_type
|
||||
*
|
||||
* @return GF_Field
|
||||
*/
|
||||
public static function get( $field_type ) {
|
||||
return self::get_instance( $field_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the registered field types.
|
||||
*
|
||||
* @return GF_Field[]
|
||||
*/
|
||||
public static function get_all() {
|
||||
return self::$_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Field object from an array of field properties.
|
||||
*
|
||||
* @param array|GF_Field $properties
|
||||
*
|
||||
* @return GF_Field | bool
|
||||
*/
|
||||
public static function create( $properties ) {
|
||||
if ( $properties instanceof GF_Field ) {
|
||||
$type = $properties->type;
|
||||
$type = empty( $properties->inputType ) ? $type : $properties->inputType;
|
||||
} else {
|
||||
$type = isset( $properties['type'] ) ? $properties['type'] : '';
|
||||
$type = empty( $properties['inputType'] ) ? $type : $properties['inputType'];
|
||||
}
|
||||
|
||||
if ( empty( $type ) || ! isset( self::$_fields[ $type ] ) ) {
|
||||
return new GF_Field( $properties );
|
||||
}
|
||||
$class = self::$_fields[ $type ];
|
||||
$class_name = get_class( $class );
|
||||
$field = new $class_name( $properties );
|
||||
|
||||
/**
|
||||
* Filter the GF_Field object after it is created.
|
||||
*
|
||||
* @since 1.9.18.2
|
||||
*
|
||||
* @param GF_Field $field A GF_Field object.
|
||||
* @param array $properties An array of field properties used to generate the GF_Field object.
|
||||
*
|
||||
* @see https://docs.gravityforms.com/gform_gf_field_create/
|
||||
*/
|
||||
return apply_filters( 'gform_gf_field_create', $field, $properties );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Load all the field files automatically.
|
||||
GFCommon::glob_require_once( '/includes/fields/class-gf-field-*.php' );
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
Reference in New Issue
Block a user