$value ) { $this->{$key} = $value; } } /** * Whether the choice field has entries that persist after changing the field type. * * @since 2.9 * * @return boolean */ public function has_persistent_choices() { return in_array( $this->type, array( 'multi_choice', 'image_choice' ) ); } /** * Fires the deprecation notice only once per page. Not fired during AJAX requests. * * @param string $offset The array key being accessed. */ private function maybe_fire_array_access_deprecation_notice( $offset ) { if ( self::SUPPRESS_DEPRECATION_NOTICE ) { return; }; if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { return; } if ( ! self::$deprecation_notice_fired ) { _deprecated_function( "Array access to the field object is now deprecated. Further notices will be suppressed. \$field['" . esc_attr( $offset ) . "']", '2.0', 'the object operator e.g. $field->' . esc_attr( $offset ) ); self::$deprecation_notice_fired = true; } } /** * Whether or not an offset exists. * * @since 1.9 * * @param mixed $offset The offset to check for. * * @return bool */ #[\ReturnTypeWillChange] public function offsetExists( $offset ) { $this->maybe_fire_array_access_deprecation_notice( $offset ); return isset( $this->$offset ); } /** * Returns the value at specified offset. * * @since 1.9 * * @param mixed $offset The offset to retrieve. * * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet( $offset ) { $this->maybe_fire_array_access_deprecation_notice( $offset ); if ( ! isset( $this->$offset ) ) { $this->$offset = ''; } return $this->$offset; } /** * Assigns a value to the specified offset. * * @since 1.9 * * @param mixed $offset The offset to assign the value to. * @param mixed $data The value to set. * * @return void */ #[\ReturnTypeWillChange] public function offsetSet( $offset, $data ) { $this->maybe_fire_array_access_deprecation_notice( $offset ); if ( $offset === null ) { $this[] = $data; } else { $this->$offset = $data; } } /** * Unsets an offset. * * @since 1.9 * * @param mixed $offset The offset to unset. * * @return void */ #[\ReturnTypeWillChange] public function offsetUnset( $offset ) { $this->maybe_fire_array_access_deprecation_notice( $offset ); unset( $this->$offset ); } public function __isset( $key ) { return isset( $this->$key ); } public function __set( $key, $value ) { switch( $key ) { case '_context_properties' : _doing_it_wrong( '$field->_context_properties', 'Use $field->get_context_property() instead.', '2.3' ); break; case 'adminOnly': // intercept 3rd parties trying to set the adminOnly property and convert to visibility property $this->visibility = $value ? 'administrative' : 'visible'; break; default: $this->$key = $value; } } /** * The getter method of the field property. * * @since unknown * @since 2.4.19 Add whitelist for the size property. * * @param string $key The field property. * * @return bool|mixed */ public function &__get( $key ) { switch ( $key ) { case '_context_properties' : _doing_it_wrong( '$field->_context_properties', 'Use $field->get_context_property() instead.', '2.3' ); $value = false; return $value; case 'adminOnly' : // intercept 3rd parties trying to get the adminOnly property and fetch visibility property instead $value = $this->visibility == 'administrative'; // set and return variable to avoid notice return $value; case 'size': $value = ''; if ( isset( $this->size ) ) { $value = GFCommon::whitelist( $this->size, array( 'small', 'medium', 'large' ) ); } return $value; default: if ( ! isset( $this->$key ) ) { $this->$key = ''; } } return $this->$key; } public function __unset( $key ) { unset( $this->$key ); } /** * Set a context property for this field. * * @since 2.3 * @since 2.5.10 - Property key can be an array in order to set a nested value. * * * @param array|string $property_key * @param mixed $value * * @return void */ public function set_context_property( $property_key, $value ) { if ( is_array( $property_key ) ) { $temp = &$this->_context_properties; foreach ( $property_key as $key ) { if ( ! isset( $temp[ $key ] ) ) { $temp[ $key ] = array(); } $temp = &$temp[ $key ]; } $temp = $value; unset( $temp ); return; } $this->_context_properties[ $property_key ] = $value; } public function get_context_property( $property_key ) { return isset( $this->_context_properties[ $property_key ] ) ? $this->_context_properties[ $property_key ] : null; } /** * Set the validation state for a single input within this field. * * @since 2.5.10 * * @param string $input_id * @param bool $is_valid * * @return void */ public function set_input_validation_state( $input_id, $is_valid ) { $input_id = explode( '.', $input_id ); $input_id = end( $input_id ); $this->set_context_property( array( 'input_validation_states', $input_id ), $is_valid ); } /** * Determine whether a single input has been marked as invalid via context properties. * * @since 2.5.10 * * @param $input_id * * @return bool */ protected function is_input_valid( $input_id ) { if ( empty( $this->get_entry_inputs() ) ) { return true; } $input_id = explode( '.', $input_id ); $input_id = end( $input_id ); $validations = $this->get_context_property( 'input_validation_states' ); return isset( $validations[ $input_id ] ) ? $validations[ $input_id ] : true; } /** * Get default properties for a field. * * Used to populate a field with default properties if any properties are required for a field to function correctly. * * @since 2.7.4 * * @return array */ public function get_default_properties() { return array(); } // # FORM EDITOR & FIELD MARKUP ------------------------------------------------------------------------------------- /** * Returns the field title. * * @return string */ public function get_form_editor_field_title() { return $this->type; } /** * 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--cog'; } /** * Returns the form editor icon for the field type. * * Sometimes the field type and the input type are not the same, but we want the field type icon. * * @since 2.9.0 * * @return string */ public function get_form_editor_field_type_icon() { if ( $this->type !== $this->inputType ) { $field_class = GF_Fields::get( $this->type ); if ( $field_class ) { return $field_class->get_form_editor_field_icon(); } } return $this->get_form_editor_field_icon(); } /** * Returns the field's form editor description. * * @since 2.5 * * @return string */ public function get_form_editor_field_description() { return sprintf( esc_attr__( 'Add a %s field to your form.', 'gravityforms' ), $this->get_form_editor_field_title() ); } /** * Defines the IDs of required inputs. * * @since 2.5 * * @return string[] */ public function get_required_inputs_ids() { return array(); } /** * 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' * * Built-in fields don't need to implement this because the buttons are added in sequence in GFFormDetail * * @return array */ public function get_form_editor_button() { return array( 'group' => 'standard_fields', 'text' => $this->get_form_editor_field_title(), 'icon' => $this->get_form_editor_field_icon(), 'description' => $this->get_form_editor_field_description() ); } /** * Returns the class names of the settings which should be available on the field in the form editor. * * @return array */ public function get_form_editor_field_settings() { return array(); } /** * Override to indicate if this field type can be used when configuring conditional logic rules. * * @return bool */ public function is_conditional_logic_supported() { return false; } /** * Returns the scripts to be included for this field type in the form editor. * * @return string */ public function get_form_editor_inline_script_on_page_render() { return ''; } /** * Returns the scripts to be included with the form init scripts on the front-end. * * @param array $form The Form Object currently being processed. * * @return string */ public function get_form_inline_script_on_page_render( $form ) { return ''; } /** * Returns the field inner markup. * * @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 ) { return ''; } /** * 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(). * * @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 ) { $form_id = (int) rgar( $form, 'id' ); $field_label = $this->get_field_label( $force_frontend_label, $value ); if ( ! in_array( $this->inputType, array( 'calculation', 'singleproduct' ), true ) ) { // Calculation and Single Product field add a screen reader text to the label so do not escape it. $field_label = esc_html( $field_label ); } $validation_message_id = 'validation_message_' . $form_id . '_' . $this->id; $validation_message = ( $this->failed_validation && ! empty( $this->validation_message ) ) ? sprintf( "
", $validation_message_id, $this->validation_message ) : ''; $is_form_editor = $this->is_form_editor(); $is_entry_detail = $this->is_entry_detail(); $is_admin = $is_form_editor || $is_entry_detail; $required_div = $this->isRequired ? '' . $this->get_required_indicator() . '' : ''; $admin_buttons = $this->get_admin_buttons(); $target_input_id = $this->get_first_input_id( $form ); $label_tag = $this->get_field_label_tag( $form ); // Label wrapper is required for correct positioning of the legend in compact view in Safari. $legend_wrapper = $is_form_editor && 'legend' === $label_tag ? '' : ''; $legend_wrapper_close = $is_form_editor && 'legend' === $label_tag ? '' : ''; $for_attribute = empty( $target_input_id ) || $label_tag === 'legend' ? '' : "for='{$target_input_id}'"; $admin_hidden_markup = ( $this->visibility == 'hidden' ) ? $this->get_hidden_admin_markup() : ''; $description = $this->get_description( $this->description, 'gfield_description' ); $clear = ''; if( $this->is_description_above( $form ) || $this->is_validation_above( $form ) ) { $clear = $is_admin ? "" : ''; } $field_content = sprintf( "%s%s<$label_tag class='%s' $for_attribute>$legend_wrapper%s%s$legend_wrapper_close$label_tag>%s%s{FIELD}%s%s$clear", $admin_buttons, $admin_hidden_markup, esc_attr( $this->get_field_label_class() ), $field_label, $required_div, $this->is_description_above( $form ) ? $description : '', $this->is_validation_above( $form ) ? $validation_message : '', $this->is_description_above( $form ) ? '' : $description, $this->is_validation_above( $form ) ? '' : $validation_message ); return $field_content; } /** * Returns the HTML tag for the field label. * * @since 2.5 * * @param array $form The current Form object. * * @return string */ public function get_field_label_tag( $form ) { // Get field container tag. $container_tag = $this->get_field_container_tag( $form ); return $container_tag === 'fieldset' ? 'legend' : 'label'; } /** * Checks if any messages should be displayed in the sidebar for this field, and returns the HTML markup for them. * * Messages could be warning messages, that will be displayed in error style, or notification messages, that will be displayed in info style. * * @since 2.8.0 * * @return array[]|array|string An array of arrays that lists all the messages and their types, an array that contains one message and type, or a warning message string that defaults to the warning type. */ public function get_field_sidebar_messages() { return ''; } /** * 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 ) { // Get the field container tag. $tag = $this->get_field_container_tag( $form ); // Parse the provided attributes. $atts = wp_parse_args( $atts, array( 'id' => '', 'class' => '', 'style' => '', 'tabindex' => '', 'aria-atomic' => '', 'aria-live' => '', 'data-field-class' => '', 'data-field-position' => '', ) ); $tabindex_string = ( rgar( $atts, 'tabindex' ) ) === '' ? '' : ' tabindex="' . esc_attr( $atts['tabindex'] ) . '"'; $disable_ajax_reload = $this->disable_ajax_reload(); $ajax_reload_id = $disable_ajax_reload === 'skip' || $disable_ajax_reload === 'true' || $disable_ajax_reload === true ? 'true' : esc_attr( rgar( $atts, 'id' ) ); $is_form_editor = $this->is_form_editor(); $target_input_id = esc_attr( rgar( $atts, 'id' ) ); // Get the field sidebar messages, this could be an array of messages or a warning message string. $field_sidebar_messages = GFCommon::is_form_editor() ? $this->get_field_sidebar_messages() : ''; /** * Allows the field sidebar messages to be modified. * * @since 2.9.30 * * @param array|string $field_sidebar_messages The field sidebar messages. * @param GF_Field $field The field object. */ $field_sidebar_messages = $is_form_editor ? apply_filters( 'gform_field_sidebar_messages', $field_sidebar_messages, $this ) : $field_sidebar_messages; $sidebar_message_type = 'warning'; $sidebar_message_content = $field_sidebar_messages; if ( is_array( $field_sidebar_messages ) ) { $sidebar_message = is_array( rgar( $field_sidebar_messages, '0' ) ) ? array_shift( $field_sidebar_messages ) : $field_sidebar_messages; $sidebar_message_type = rgar( $sidebar_message, 'type' ); $sidebar_message_content = rgar( $sidebar_message, 'content' ); } if ( ! empty( $sidebar_message_content ) ) { $atts['class'] .= ' gfield-has-sidebar-message gfield-has-sidebar-message--type-' . ( $sidebar_message_type === 'error' ? 'warning' : $sidebar_message_type ); if ( $sidebar_message_type === 'error' ) { $atts['aria-invalid'] = 'true'; } } return sprintf( '<%1$s id="%2$s" class="%3$s" %4$s%5$s%6$s%7$s%8$s%9$s %10$s>%11$s{FIELD_CONTENT}%1$s>', $tag, esc_attr( rgar( $atts, 'id' ) ), esc_attr( rgar( $atts, 'class' ) ), rgar( $atts, 'style' ) ? ' style="' . esc_attr( $atts['style'] ) . '"' : '', ( rgar( $atts, 'tabindex' ) ) === false ? '' : $tabindex_string, rgar( $atts, 'aria-atomic' ) ? ' aria-atomic="' . esc_attr( $atts['aria-atomic'] ) . '"' : '', rgar( $atts, 'aria-live' ) ? ' aria-live="' . esc_attr( $atts['aria-live'] ) . '"' : '', rgar( $atts, 'data-field-class' ) ? ' data-field-class="' . esc_attr( $atts['data-field-class'] ) . '"' : '', rgar( $atts, 'data-field-position' ) ? ' data-field-position="' . esc_attr( $atts['data-field-position'] ) . '"' : '', rgar( $atts, 'aria-invalid' ) ? ' aria-invalid="true"' : '', empty( $sidebar_message_content ) ? '' : '' ); } /** * 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 ) { return GFCommon::is_legacy_markup_enabled( $form ) ? 'li' : 'div'; } /** * Get field label class. * * @since unknown * @since 2.5 Added `screen-reader-text` if the label hasn't been set; added `gfield_label_before_complex` if the field has inputs. * @since 2.7 Added `gform-field-label` for the theme framework. * * @return string */ public function get_field_label_class() { $class = 'gfield_label'; $class .= ' gform-field-label'; // Added `screen-reader-text` if the label hasn't been set. $class .= ( rgblank( $this->label ) ) ? ' screen-reader-text' : ''; // Added `gfield_label_before_complex` if the field has inputs. $class .= is_array( $this->inputs ) ? ' gfield_label_before_complex' : ''; return $class; } /** * Get field CSS class. * * @since 2.7 * * @return string */ public function get_field_css_class() { return ''; } /** * Return an aria-label for a field action (delete, edit, duplicate). * * @since 2.5 * * @param str $action The button action as descriptive text. * @param str $label The field label. * * @return str The passed aria-label or an automatically generated label if it is blank. */ public function get_field_action_aria_label( $action = '', $label = '' ) { if ( $label !== '' ) { $label = wp_strip_all_tags( $label ); } else { $label = wp_strip_all_tags( $this->get_field_label( true, '' ) ); } // Sometimes the field editor label is different from the field type, so make sure we're using the correct field type. $field_class = GF_Fields::get( $this->type ); if ( is_object( $field_class ) ) { $field_title = $field_class->get_form_editor_field_title(); } else { $field_title = $this->type; } return sprintf( '%1$s - %2$s, %3$s.', esc_attr( $label ), esc_attr( $field_title ), esc_attr( $action ) ); } // # SUBMISSION ----------------------------------------------------------------------------------------------------- /** * Whether this field expects an array during submission. * * @since 2.4 * * @return bool */ public function is_value_submission_array() { return false; } /** * Returns the input ID given the choice key for Multiple Choice and Image Choice fields. * * @since 2.9 * * @param string $key The choice key. * * @return string */ public function get_input_id_from_choice_key( $key ) { $input_id = ''; if ( is_array( $this->inputs ) ) { foreach ( $this->inputs as $input ) { if ( rgar( $input, 'key' ) == $key ) { $input_id = rgar( $input, 'id' ); break; } } } return $input_id; } /** * Returns the choice ID given the input key for Multiple Choice and Image Choice fields. * * @since 2.9 * * @param string $key The choice key. * * @return string */ public function get_choice_id_from_input_key( $key ) { $choice_id = ''; if ( is_array( $this->choices ) ) { foreach ( $this->choices as $index => $choice ) { if ( rgar( $choice, 'key' ) == $key ) { $choice_id = $index; break; } } } return $choice_id; } /** * Used to determine the required validation result. * * @param int $form_id The ID of the form currently being processed. * * @return bool */ public function is_value_submission_empty( $form_id ) { $copy_values_option_activated = $this->enableCopyValuesOption && rgpost( 'input_' . $this->id . '_copy_values_activated' ); // GF_Field_Radio can now have inputs if it's a Choice or Image Choice field if ( is_array( $this->inputs ) && ! ( $this instanceof GF_Field_Radio ) ) { foreach ( $this->inputs as $input ) { if ( $copy_values_option_activated ) { $input_id = $input['id']; $input_name = 'input_' . str_replace( '.', '_', $input_id ); $source_field_id = $this->copyValuesOptionField; $source_input_name = str_replace( 'input_' . $this->id, 'input_' . $source_field_id, $input_name ); $value = rgpost( $source_input_name ); } else { $value = rgpost( 'input_' . str_replace( '.', '_', $input['id'] ) ); } if ( is_array( $value ) && ! empty( $value ) ) { return false; } if ( ! is_array( $value ) && strlen( trim( $value ) ) > 0 ) { return false; } } return true; } else { if ( $copy_values_option_activated ) { $value = rgpost( 'input_' . $this->copyValuesOptionField ); } else { $value = rgpost( 'input_' . $this->id ); } if ( is_array( $value ) ) { //empty if any of the inputs are empty (for inputs with the same name) foreach ( $value as $input ) { $input = GFCommon::trim_deep( $input ); if ( GFCommon::safe_strlen( $input ) <= 0 ) { return true; } } return false; } elseif ( $this->enablePrice ) { list( $label, $price ) = rgexplode( '|', $value, 2, true ); $is_empty = ( strlen( trim( $price ) ) <= 0 ); return $is_empty; } else { $is_empty = ( strlen( trim( $value ) ) <= 0 ) || ( $this->type == 'post_category' && $value < 0 ); return $is_empty; } } } /** * Is the given value considered empty for this field. * * @since 2.4 * * @param $value * * @return bool */ public function is_value_empty( $value ) { if ( is_array( $this->inputs ) ) { if ( $this->is_value_submission_array() ) { foreach ( $this->inputs as $i => $input ) { $v = isset( $value[ $i ] ) ? $value[ $i ] : ''; if ( is_array( $v ) && ! empty( $v ) ) { return false; } if ( ! is_array( $v ) && strlen( trim( $v ) ) > 0 ) { return false; } } } else { foreach ( $this->inputs as $input ) { $input_id = (string) $input['id']; $v = isset( $value[ $input_id ] ) ? $value[ $input_id ] : ''; if ( is_array( $v ) && ! empty( $v ) ) { return false; } if ( ! is_array( $v ) && strlen( trim( $v ) ) > 0 ) { return false; } } } } elseif ( is_array( $value ) ) { // empty if any of the inputs are empty (for inputs with the same name) foreach ( $value as $input ) { $input = GFCommon::trim_deep( $input ); if ( GFCommon::safe_strlen( $input ) <= 0 ) { return true; } } return false; } elseif ( empty( $value ) ) { return true; } else { return false; } return true; } /** * Override this method to perform custom validation logic. * * Return the result (bool) by setting $this->failed_validation. * Return the validation message (string) by setting $this->validation_message. * * @since 1.9 * * @param string|array $value The field value from get_value_submission(). * @param array $form The Form Object currently being processed. * * @return void */ public function validate( $value, $form ) { // } /** * Sets the failed_validation and validation_message properties for a required field error. * * @since 2.6.5 * * @param mixed $value The field value. * @param bool $require_complex_message Indicates if the field must have a complex validation message for the error to be set. * * @return void */ public function set_required_error( $value, $require_complex_message = false ) { $complex_message = $this->complex_validation_message( $value, $this->get_required_inputs_ids() ); if ( $require_complex_message && ! $complex_message ) { return; } $this->failed_validation = true; $this->validation_message = empty( $this->errorMessage ) ? __( 'This field is required.', 'gravityforms' ) : $this->errorMessage; if ( $complex_message ) { $this->validation_message .= ' ' . $complex_message; } } /** * Override to modify the value 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 $value; } /** * Create a validation message for a required field with multiple inputs. * * The validation message will specify which inputs need to be filled out. * * @since 2.5 * @since 2.6.5 Updated to use prepare_complex_validation_value(). * * @param array $value The value entered by the user. * @param array $required_inputs The required inputs to validate. * * @return string|false */ public function complex_validation_message( $value, $required_inputs ) { if ( empty( $this->inputs ) || empty( $required_inputs ) ) { return false; } $value = $this->prepare_complex_validation_value( $value ); $error_inputs = array(); foreach ( $required_inputs as $input ) { if ( rgblank( rgar( $value, $this->id . '.' . $input ) ) && ! $this->get_input_property( $input, 'isHidden' ) ) { $custom_label = $this->get_input_property( $input, 'customLabel' ); $label = $custom_label ? $custom_label : $this->get_input_property( $input, 'label' ); $error_inputs[] = $label; } } if ( empty( $error_inputs ) ) { return false; } $field_list = implode( ', ', $error_inputs ); // Translators: comma-separated list of the labels of missing fields. return sprintf( __( 'Please complete the following fields: %s.', 'gravityforms' ), $field_list ); } /** * Gets a property value from an input. * * @since Unknown * @access public * * @used-by GF_Field_Name::validate() * @uses GFFormsModel::get_input() * * @param int $input_id The input ID to obtain the property from. * @param string $property_name The property name to search for. * * @return null|string The property value if found. Otherwise, null. */ public function get_input_property( $input_id, $property_name ) { $input = GFFormsModel::get_input( $this, $this->id . '.' . (string) $input_id ); return rgar( $input, $property_name ); } /** * Retrieve the field value on submission. * * @param array $field_values The dynamic population parameter names with their corresponding values to be populated. * @param bool|true $get_from_post_global_var Whether to get the value from the $_POST array as opposed to $field_values. * * @return array|string */ public function get_value_submission( $field_values, $get_from_post_global_var = true ) { $inputs = $this->get_entry_inputs(); if ( is_array( $inputs ) ) { $value = array(); foreach ( $inputs as $input ) { $value[ strval( $input['id'] ) ] = $this->get_input_value_submission( 'input_' . str_replace( '.', '_', strval( $input['id'] ) ), rgar( $input, 'name' ), $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; } /** * Retrieve the input value on submission. * * @since 1.9 * @since 2.9.17 Updated to return null if the field failed state validation. * * @param string $standard_name The input name used when accessing the $_POST. * @param string $custom_name The dynamic population parameter name. * @param array $field_values The dynamic population parameter names with their corresponding values to be populated. * @param bool|true $get_from_post_global_var Whether to get the value from the $_POST array as opposed to $field_values. * * @return array|string|null */ public function get_input_value_submission( $standard_name, $custom_name = '', $field_values = array(), $get_from_post_global_var = true ) { $form_id = $this->formId; if ( ! empty( $_POST[ 'is_submit_' . $form_id ] ) && $get_from_post_global_var ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing $value = $this->get_context_property( 'failed_state_validation' ) ? null : rgpost( $standard_name ); return GFFormsModel::maybe_trim_input( $value, $form_id, $this ); } elseif ( $this->allowsPrepopulate ) { return GFFormsModel::get_parameter_value( $custom_name, $field_values, $this ); } return null; } // # ENTRY RELATED -------------------------------------------------------------------------------------------------- /** * Override and return null if a multi-input field value is to be stored under the field ID instead of the individual input IDs. * * @return array|null */ public function get_entry_inputs() { return $this->inputs; } /** * Sanitize and format the value before it is saved to the Entry Object. * * @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 ) { if ( rgblank( $value ) ) { return ''; } elseif ( is_array( $value ) ) { foreach ( $value as &$v ) { if ( is_array( $v ) ) { $v = ''; } $v = $this->sanitize_entry_value( $v, $form['id'] ); } return implode( ',', $value ); } else { return $this->sanitize_entry_value( $value, $form['id'] ); } } /** * 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 = isset( $form['id'] ) ? absint( $form['id'] ) : null; $allowable_tags = $this->get_allowable_tags( $form_id ); if ( $allowable_tags === false ) { // The value is unsafe so encode the value. if ( is_array( $value ) ) { foreach ( $value as &$v ) { $v = esc_html( $v ); } $return = $value; } else { $return = esc_html( $value ); } } else { // The value contains HTML but the value was sanitized before saving. if ( is_array( $raw_value ) ) { $return = rgar( $raw_value, $input_id ); } else { $return = $raw_value; } } if ( $nl2br ) { if ( is_array( $return ) ) { foreach ( $return as &$r ) { $r = nl2br( $r ); } } else { $return = nl2br( $return ); } } } else { $return = $value; } return $return; } /** * Format the entry value for display on the entries list page. * * Return a value that's safe to display on the page. * * @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 ) { $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; } /** * Returns the field value formatted for the {all_fields} merge tag (email output). * * @since 2.9.31 * * @param string|array $value The field value. * @param array $entry The entry. * @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. * * @return string|false */ public function get_value_all_fields_merge_tag( $value, $entry, $use_text, $format ) { return $this->get_value_entry_detail( $value, $entry, $use_text, $format, 'email' ); } /** * 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. * * @since 1.9 * @since 2.9.14 Updated to display an inline error message on the entry detail page for array-based values. * @since 2.9.29 Changed the second parameter $currency (string) to $entry (array). * * @param string|array $value The field value. * @param array $entry The entry. * @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|false */ public function get_value_entry_detail( $value, $entry = array(), $use_text = false, $format = 'html', $media = 'screen' ) { if ( is_array( $value ) ) { if ( ! $this->is_entry_detail() ) { // Returning false for {all_fields}, so the field is omitted from the output even when the empty modifier is used. return $media === 'email' ? false : ''; } $class = get_class( $this ); if ( $class === GF_Field::class ) { $error_message = sprintf( esc_html__( 'Field value cannot be displayed. Please activate the add-on that includes the `%s` field type.', 'gravityforms' ), $this->type ); } else { $error_message = sprintf( esc_html__( 'Field value cannot be displayed. If you are the developer of the `%s` field type, please implement `%s::get_value_entry_detail()` to define how the value is displayed.', 'gravityforms' ), $this->type, $class ); } return '