",
$limit_message,
$select_all_enabled_class,
esc_attr( $field_id ),
$choices_markup,
$button_markup
);
}
public function get_button_markup( $value, $entry ) {
/**
* Modify the "Select All" checkbox label.
*
* @since 2.3
*
* @param string $select_label The "Select All" label.
* @param object $field The field currently being processed.
*/
$select_label = gf_apply_filters( array( 'gform_checkbox_select_all_label', $this->formId, $this->id ), esc_html__( 'Select All', 'gravityforms' ), $this );
$select_label = esc_html( $select_label );
/**
* Modify the "Deselect All" checkbox label.
*
* @since 2.3
*
* @param string $deselect_label The "Deselect All" label.
* @param object $field The field currently being processed.
*/
$deselect_label = gf_apply_filters( array( 'gform_checkbox_deselect_all_label', $this->formId, $this->id ), esc_html__( 'Deselect All', 'gravityforms' ), $this );
$deselect_label = esc_html( $deselect_label );
// Determine if all checkboxes are selected.
$all_selected = $this->get_selected_choices_count( $value, $entry ) === count( $this->choices );
// Prepare button markup.
$button_markup = sprintf(
'',
$this->id,
$select_label,
$deselect_label,
$all_selected ? 1 : 0,
$all_selected ? $deselect_label : $select_label,
$this->is_form_editor() ? ' disabled="disabled"' : ''
);
return $button_markup;
}
/**
* Get the message that describes the choice limit.
*
* @since 2.9.0
*
* @return string
*/
public function get_limit_message() {
$text = $this->get_limit_message_text();
if ( ! $text ) {
return '';
}
$form_id = $this->formId;
$form = GFAPI::get_form( $form_id );
// If the validation message is the same as the limit message, and they both display above the field, don't display the limit message.
if ( $this->failed_validation && $this->validation_message === $text && $this->is_validation_above( $form ) ) {
return;
}
$id = $this->id;
return "{$text}";
}
/**
* Get the text of the choice limit message, or return false if there is no limit.
*
* @since 2.9.0
*
* @return false|string
*/
public function get_limit_message_text() {
if ( $this->choiceLimit === 'exactly' && $this->choiceLimitNumber ) {
$message = sprintf(
esc_attr(
_n(
'Select exactly %s choice.',
'Select exactly %s choices.',
$this->choiceLimitNumber,
'gravityforms'
)
),
"$this->choiceLimitNumber"
);
/**
* Modify the message displayed when a checkbox is limited to an exact number of entries.
*
* @since 2.9.0
*
* @param string $message The message to filter.
* @param int $number The number of choices that must be selected.
* @param object $field The field currently being processed.
*/
return gf_apply_filters( array( 'gform_checkbox_limit_exact_message', $this->formId, $this->id ), $message, $this->choiceLimitNumber, $this );
}
if ( $this->choiceLimit === 'range' ) {
$min = $this->choiceLimitMin;
$max = $this->choiceLimitMax;
if ( ! $min && $max ) {
$message = sprintf(
esc_attr(
_n(
'Select up to %s choice.',
'Select up to %s choices.',
$max,
'gravityforms'
)
),
"$max"
);
/**
* Modify the message displayed when a checkbox is limited to a maximum number of choices.
*
* @since 2.9.0
*
* @param string $message The message to filter.
* @param int $max The maximum number of choices that must be selected.
* @param object $field The field currently being processed.
*/
return gf_apply_filters( array( 'gform_checkbox_limit_max_message', $this->formId, $this->id ), $message, $max, $this );
}
if ( ! $max && $min ) {
$message = sprintf(
esc_attr(
_n(
'Select at least %s choice.',
'Select at least %s choices.',
$min,
'gravityforms'
)
),
"$min"
);
/**
* Modify the message displayed when a checkbox is limited to a minimum number of choices.
*
* @since 2.9.0
*
* @param string $message The message to filter.
* @param int $min The minimum number of choices that must be selected.
* @param object $field The field currently being processed.
*/
return gf_apply_filters( array( 'gform_checkbox_limit_min_message', $this->formId, $this->id ), $message, $min, $this );
}
if( $min && $max ) {
$message = sprintf( esc_html__( 'Select between %s and %s choices.', 'gravityforms' ), "$min", "$max" );
/**
* Modify the message displayed when a checkbox is limited to a maximum number of entries.
*
* @since 2.9.0
*
* @param string $message The message to filter.
* @param int $min The minimum number of choices that must be selected.
* @param int $max The maximum number of choices that must be selected.
* @param object $field The field currently being processed.
*/
return gf_apply_filters( array( 'gform_checkbox_limit_range_message', $this->formId, $this->id ), $message, $min, $max, $this );
}
}
return false;
}
/**
* Returns the field inner markup.
*
* @since 2.5
*
* @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_legacy_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";
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
$tag = GFCommon::is_legacy_markup_enabled( $form ) ? 'ul' : 'div';
return sprintf(
"
<{$tag} class='gfield_checkbox' id='%s'>%s{$tag}>
",
esc_attr( $field_id ),
$this->get_checkbox_choices( $value, $disabled_text, $form_id )
);
}
/**
* Returns the number of selected choices.
* Used during field rendering to set the initial state of the (De)Select All toggle.
*
* @since 2.5
*
* @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 int
*/
private function get_selected_choices_count( $value = '', $entry = null ) {
// Initialize selected, choice number counts.
$checkboxes_selected = 0;
$choice_number = 1;
foreach ( $this->choices as $choice ) {
// Hack to skip numbers ending in 0, so that 5.1 doesn't conflict with 5.10.
if ( $choice_number % 10 == 0 ) {
$choice_number ++;
}
// Prepare input ID.
if ( rgar( $choice, 'key' ) ) {
$input_id = $this->get_input_id_from_choice_key( $choice['key'] );
} else {
$input_id = $this->id . '.' . $choice_number;
}
if ( ( $this->is_form_editor() || ( ! isset( $_GET['gf_token'] ) && empty( $_POST ) ) ) && rgar( $choice, 'isSelected' ) ) {
$checkboxes_selected++;
} else if ( is_array( $value ) && GFFormsModel::choice_value_match( $this, $choice, rgget( $input_id, $value ) ) ) {
$checkboxes_selected++;
} else if ( ! is_array( $value ) && GFFormsModel::choice_value_match( $this, $choice, $value ) ) {
$checkboxes_selected++;
}
$choice_number++;
}
return $checkboxes_selected;
}
// # SUBMISSION -----------------------------------------------------------------------------------------------------
/**
* Retrieve the field value on submission.
*
* @since Unknown
* @access public
*
* @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.
*
* @uses GFFormsModel::choice_value_match()
* @uses GFFormsModel::get_parameter_value()
*
* @return array|string
*/
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
// Get parameter values for field.
$parameter_values = GFFormsModel::get_parameter_value( $this->inputName, $field_values, $this );
// If parameter values exist but are not an array, convert to array.
if ( ! empty( $parameter_values ) && ! is_array( $parameter_values ) ) {
$parameter_values = explode( ',', $parameter_values );
}
// If no inputs are defined, return an empty string.
if ( ! is_array( $this->inputs ) ) {
return '';
}
// Set initial choice index.
$choice_index = 0;
// Initialize submission value array.
$value = array();
// Loop through field inputs.
foreach ( $this->inputs as $input ) {
if ( ! empty( $_POST[ 'is_submit_' . $this->formId ] ) && $get_from_post_global_var ) {
$input_value = rgpost( 'input_' . str_replace( '.', '_', strval( $input['id'] ) ) );
$value[ strval( $input['id'] ) ] = $input_value;
} else {
if ( is_array( $parameter_values ) ) {
foreach ( $parameter_values as $item ) {
$item = trim( $item );
if ( rgar( $input, 'key' ) ) {
$choice_id = $this->get_choice_id_from_input_key( $input['key'] );
if ( '' == $choice_id ) {
continue;
}
$choice = $this->choices[ $choice_id ];
} else {
$choice = $this->choices[ $choice_index ];
}
if ( GFFormsModel::choice_value_match( $this, $choice, $item ) ) {
$value[ $input['id'] . '' ] = $item;
break;
}
}
}
}
// Increase choice index.
$choice_index ++;
}
return $value;
}
public function validate( $value, $form ) {
if ( $this->choiceLimit == 'exactly' ) {
$selected_choices_count = $this->get_selected_choices_count( $value );
if ( 0 === $selected_choices_count ) {
return;
}
if ( $selected_choices_count != $this->choiceLimitNumber ) {
$this->failed_validation = true;
$this->validation_message = $this->get_limit_message_text();
}
} elseif ( $this->choiceLimit == 'range' ) {
$selected_choices_count = $this->get_selected_choices_count( $value );
if ( 0 === $selected_choices_count ) {
return;
}
if ( ( $this->choiceLimitMin && $selected_choices_count < $this->choiceLimitMin ) || ( $this->choiceLimitMax && $selected_choices_count > $this->choiceLimitMax ) ) {
$this->failed_validation = true;
$this->validation_message = $this->get_limit_message_text();
}
}
}
// # ENTRY RELATED --------------------------------------------------------------------------------------------------
/**
* Format the entry value for display on the entries list page.
*
* Return a value that's safe to display on the 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.
*
* @uses GFCommon::implode_non_blank()
* @uses GFCommon::prepare_post_category_value()
* @uses GFCommon::selection_display()
* @uses GF_Field_Checkbox::is_checkbox_checked()
*
* @return string
*/
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
// If this is the main checkbox field (not an input), display a comma separated list of all inputs.
if ( absint( $field_id ) == $field_id ) {
$lead_field_keys = array_keys( $entry );
$items = array();
foreach ( $lead_field_keys as $input_id ) {
if ( is_numeric( $input_id ) && absint( $input_id ) == $field_id ) {
$items[] = $this->get_selected_choice_output( rgar( $entry, $input_id ), rgar( $entry, 'currency' ) );
}
}
$value = GFCommon::implode_non_blank( ', ', $items );
// Special case for post category checkbox fields.
if ( $this->type == 'post_category' ) {
$value = GFCommon::prepare_post_category_value( $value, $this, 'entry_list' );
}
} else {
$value = '';
if ( ! rgblank( $this->is_checkbox_checked( $field_id, $columns[ $field_id ]['label'], $entry ) ) ) {
$value = "";
}
}
return $value;
}
/**
* 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 Unknown
* @access public
*
* @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.
*
* @uses GFCommon::selection_display()
*
* @return string
*/
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
if ( is_array( $value ) ) {
$items = '';
foreach ( $value as $key => $item ) {
if ( ! rgblank( $item ) ) {
switch ( $format ) {
case 'text' :
$items .= $this->get_selected_choice_output( $item, $currency, $use_text ) . ', ';
break;
default:
$items .= '