';
return $list;
}
/**
* Builds the field input HTML markup.
*
* @since Unknown
* @access public
*
* @param array $form The Form Object.
* @param string $value The field value. Defaults to empty string.
* @param null|array $entry The Entry Object. Defaults to null.
*
* @return string The List field HTML markup.
*/
public function get_legacy_field_input( $form, $value = '', $entry = null ) {
$form_id = $form['id'];
$is_form_editor = $this->is_form_editor();
if ( ! empty( $value ) ) {
$value = maybe_unserialize( $value );
}
if ( is_array( $value ) ) {
if ( ! is_array( $value[0] ) ) {
$value = $this->create_list_array( $value );
}
} else {
$value = array( array() );
}
$has_columns = is_array( $this->choices );
$columns = $has_columns ? $this->choices : array( array() );
$list = '';
if ( ! self::$_style_block_printed ){
// This style block needs to be inline so that the list field continues to work even if the option to turn off CSS output is activated.
$list .= '';
self::$_style_block_printed = true;
}
$list .= "
';
return $list;
}
/**
* Builds the input that will be inside the List field.
*
* @since Unknown
* @access public
*
* @param bool $has_columns If the input has columns.
* @param array $column The column details.
* @param string $value The existing value of the input.
* @param int $form_id The form ID.
* @param int $row The row number to which the input belongs.
*
* @return string The input HTML markup.
*/
public function get_list_input( $has_columns, $column, $value, $form_id, $row ) {
$tabindex = $this->get_tabindex();
$disabled = $this->is_form_editor() ? 'disabled' : '';
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
$invalid_attribute = $this->failed_validation ? "aria-invalid='true'" : "aria-invalid='false'";
$aria_describedby = $this->get_aria_describedby();
$column_index = 1;
if ( $has_columns && is_array( $this->choices ) ) {
foreach ( $this->choices as $choice ) {
if ( $choice['text'] == $column['text'] ) {
break;
}
$column_index ++;
}
}
$input_info = array( 'type' => 'text' );
$column_text = rgar( $column, 'text' );
$aria_label_template = isset( $column['text'] ) ? $column_text : $this->label;
$aria_label_template .= ", Row {0}";
/**
* Filters the column input.
*
* @since Unknown
*
* @param array $input_info Information about the input. Contains the input type.
* @param object GF_Field_List Field object for this field type.
* @param string $column['text'] The column text value.
* @param int $form_id The form ID.
*/
$input_info = gf_apply_filters( array(
'gform_column_input',
$form_id,
$this->id,
$column_index
), $input_info, $this, $column_text, $value, $form_id );
switch ( $input_info['type'] ) {
case 'select' :
$input = "';
break;
default :
// a11y: inputs without a label must have the aria-label attribute set.
$input = "";
break;
}
/**
* Filters the column input HTML markup.
*
* @since Unknown
*
* @param string $input The input markup.
* @param array $input_info The information that was used to build the input.
* @param object GF_Field_List An instance of the List field object.
* @param string $column['text'] The column text value.
* @param int $form_id The form ID.
*/
return gf_apply_filters( array(
'gform_column_input_content',
$form_id,
$this->id,
$column_index
), $input, $input_info, $this, rgar( $column, 'text' ), $value, $form_id );
}
/**
* 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 it has choices.
*
* @return string
*/
public function get_field_label_class() {
$class = 'gfield_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 it has choices.
$class .= is_array( $this->choices ) ? ' gfield_label_before_complex' : '';
return $class;
}
/**
* Whether this field expects an array during submission.
*
* @since 2.4
*
* @return bool
*/
public function is_value_submission_array() {
return true;
}
/**
* Gets the value of te field from the form submission.
*
* @since Unknown
* @access public
*
* @param array $field_values The properties to search for.
* @param bool $get_from_post_global_var If the global GET variable should be used to obtain the value. Defaults to true.
*
* @return array The submission value.
*/
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 );
return $value;
}
/**
* Creates an array from the list items. Recurses if the field is inside a Repeater.
*
* @since 2.4
*
* @param $value
*
* @return array
*/
public function create_list_array_recursive( $value ) {
if ( isset( $value[0] ) && is_array( $value[0] ) ) {
$new_value = array();
foreach ( $value as $k => $v ) {
$new_value[ $k ] = $this->create_list_array_recursive( $v );
}
} else {
$new_value = $this->create_list_array( $value );
}
return $new_value;
}
/**
* Check if the submission value is empty.
*
* @since Unknown
* @access public
*
* @param int $form_id The form ID to check.
*
* @return bool True if empty. False otherwise.
*/
public function is_value_submission_empty( $form_id ) {
$value = rgpost( 'input_' . $this->id );
if ( is_array( $value ) ) {
// Empty if all inputs are empty (for inputs with the same name).
foreach ( $value as $input ) {
if ( strlen( trim( $input ) ) > 0 ) {
return false;
}
}
}
return true;
}
/**
* Gets the field value HTML markup to be used on the entry detail page.
*
* @since Unknown
* @access public
*
* @param array $value The submitted entry value.
* @param string $currency Not used.
* @param bool $use_text Not used.
* @param string $format The format to be used when building the items.
* Accepted values are text, url, or html. Defaults to html.
* @param string $media Defines how the content will be output.
* Accepted values are screen or email. Defaults to screen.
*
* @return string The HTML markup to be displayed.
*/
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
if ( empty( $value ) ) {
return '';
}
$value = maybe_unserialize( $value );
if( ! is_array( $value ) || ! isset( $value[0] ) ) {
return '';
}
$has_columns = is_array( $value[0] );
if ( ! $has_columns ) {
$items = '';
foreach ( $value as $key => $item ) {
if ( ! empty( $item ) ) {
$item = wp_kses_post( $item );
switch ( $format ) {
case 'text' :
$items .= $item . ', ';
break;
case 'url' :
$items .= $item . ',';
break;
default :
if ( $media == 'email' ) {
$items .= "
' . "\n";
}
break;
}
return $list;
}
return '';
}
/**
* Gets the value of the field when the entry is saved.
*
* @since Unknown
* @access public
*
* @param string $value The value to use.
* @param array $form The form that the entry is associated with.
* @param string $input_name The name of the input containing the value.
* @param int $lead_id The entry ID.
* @param array $lead The Entry Object.
*
* @return string The entry value. Escaped.
*/
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
if ( $this->is_administrative() && $this->allowsPrepopulate ) {
$value = json_decode( $value );
}
if ( GFCommon::is_empty_array( $value ) ) {
$value = '';
} else {
$value = $this->create_list_array( $value );
$value = serialize( $value );
}
$value_safe = $this->sanitize_entry_value( $value, $form['id'] );
return $value_safe;
}
/**
* Gets merge tag values.
*
* @since Unknown
* @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 ) {
$modifiers = $this->get_modifiers();
$allowed_modifiers = array( 'text', 'html', 'url' );
if( $found_modifiers = array_intersect( $modifiers, $allowed_modifiers ) ) {
$output_format = $found_modifiers[0];
} else {
$output_format = $format;
}
return GFCommon::get_lead_field_display( $this, $raw_value, $entry['currency'], true, $output_format );
}
/**
* Format the entry value for display on the entries list page.
*
* By default, the List field will not be available for selection on the entry list.
* Use the gform_display_field_select_columns_entry_list filter to make the list field available.
*
*
* @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 ) {
return GFCommon::get_lead_field_display( $this, $value, $entry['currency'], true, 'html' );
}
/**
* Creates an array from the list items.
*
* @since Unknown
* @access public
*
* @param array $value The pre-formatted list.
*
* @return array The list rows.
*/
function create_list_array( $value ) {
if ( ! $this->enableColumns ) {
return $value;
} else {
$value = empty( $value ) ? array() : $value;
$col_count = count( $this->choices );
$rows = array();
$row_count = count( $value ) / $col_count;
$col_index = 0;
for ( $i = 0; $i < $row_count; $i ++ ) {
$row = array();
foreach ( $this->choices as $column ) {
$row[ $column['text'] ] = rgar( $value, $col_index );
$col_index ++;
}
$rows[] = $row;
}
return $rows;
}
}
/**
* Sanitizes the field settings.
*
* @since Unknown
* @access public
*/
public function sanitize_settings() {
parent::sanitize_settings();
$this->maxRows = absint( $this->maxRows );
$this->enableColumns = (bool) $this->enableColumns;
}
/**
* Gets the field value, formatted for exports. For CSV export return an array.
*
* @since Unknown
* @access public
*
* @used-by GFExport::start_export()
* @used-by GFAddOn::get_field_value()
* @uses GF_Field_List::$id
* @uses GF_Field_List::$enableColumns
* @uses GF_Field_List::$choices
* @uses GFCommon::implode_non_blank()
*
* @param array $entry The Entry Object.
* @param string $input_id Input ID to export. If not defined, uses the current input ID. Defaults to empty string.
* @param bool $use_text Not used. Defaults to false.
* @param bool $is_csv Is the value going to be used in the CSV export? Defaults to false.
*
* @return string|array
*/
public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
if ( empty( $input_id ) ) {
$input_id = $this->id;
} elseif ( ! ctype_digit( $input_id ) ) {
$field_id_array = explode( '.', $input_id );
$input_id = rgar( $field_id_array, 0 );
$column_num = rgar( $field_id_array, 1 );
}
$value = rgar( $entry, $input_id );
$value = maybe_unserialize( $value );
if ( empty( $value ) || $is_csv ) {
return $value;
}
$list_values = $column_values = $value;
if ( isset( $column_num ) && is_numeric( $column_num ) && $this->enableColumns ) {
$column = rgars( $this->choices, "{$column_num}/text" );
$column_values = array();
foreach ( $list_values as $value ) {
$column_values[] = rgar( $value, $column );
}
} elseif ( $this->enableColumns ) {
return json_encode( $list_values );
}
return GFCommon::implode_non_blank( ', ', $column_values );
}
// # 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 list field.
GF_Fields::register( new GF_Field_List() );