Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions includes/fields/class-acf-field-checkbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -499,22 +499,34 @@ function update_value( $value, $post_id, $field ) {
// select -> update_value()
$value = acf_get_field_type( 'select' )->update_value( $value, $post_id, $field );

// save_other_choice
if ( $field['save_custom'] ) {
// save_custom
if ( ! empty( $field['save_custom'] ) && is_array( $value ) ) {

// get raw $field (may have been changed via repeater field)
// if field is local, it won't have an ID
$selector = $field['ID'] ? $field['ID'] : $field['key'];
$field = acf_get_field( $selector );
if ( ! $field ) {
return false;
$selector = '';
if ( ! empty( $field['ID'] ) ) {
$selector = $field['ID'];
} elseif ( ! empty( $field['key'] ) ) {
$selector = $field['key'];
}

// bail early if no ID (JSON only)
if ( ! $field['ID'] ) {
// bail early if we have no selector for lookup
if ( ! $selector ) {
return $value;
}

$field = acf_get_field( $selector );

// bail early if lookup failed or field is JSON only
if ( ! is_array( $field ) || empty( $field['ID'] ) ) {
return $value;
}

if ( ! isset( $field['choices'] ) || ! is_array( $field['choices'] ) ) {
$field['choices'] = array();
}

// loop
foreach ( $value as $v ) {

Expand Down
21 changes: 18 additions & 3 deletions includes/fields/class-acf-field-select.php
Original file line number Diff line number Diff line change
Expand Up @@ -576,14 +576,29 @@ public function update_value( $value, $post_id, $field ) {
// Save custom options back to the field definition if configured.
if ( ! empty( $field['save_options'] ) && is_array( $value ) ) {
// Get the raw field, using the ID if present or the key otherwise (i.e. when using JSON).
$selector = $field['ID'] ? $field['ID'] : $field['key'];
$field = acf_get_field( $selector );
$selector = '';
if ( ! empty( $field['ID'] ) ) {
$selector = $field['ID'];
} elseif ( ! empty( $field['key'] ) ) {
$selector = $field['key'];
}

// Bail when field lookup can't be attempted.
if ( ! $selector ) {
return $value;
}

$field = acf_get_field( $selector );

// Bail if we don't have a valid field or field ID (JSON only).
if ( empty( $field['ID'] ) ) {
if ( ! is_array( $field ) || empty( $field['ID'] ) ) {
return $value;
}

if ( ! isset( $field['choices'] ) || ! is_array( $field['choices'] ) ) {
$field['choices'] = array();
}

foreach ( $value as $v ) {
// Ignore if the option already exists.
if ( isset( $field['choices'][ $v ] ) ) {
Expand Down
29 changes: 29 additions & 0 deletions tests/php/includes/fields/test-class-acf-field-checkbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,35 @@ public function test_update_value_empty() {
$this->assertEmpty( $result );
}

/**
* Test save_custom does not trigger warnings for JSON-only fields.
*/
public function test_update_value_save_custom_handles_json_field_without_id() {
$field = $this->get_field(
array(
'save_custom' => 1,
)
);

$result = $this->field_instance->update_value( array( 'custom_value' ), $this->post_id, $field );
$this->assertSame( array( 'custom_value' ), $result );
}

/**
* Test save_custom bails early when field key and ID are both missing.
*/
public function test_update_value_save_custom_handles_missing_field_identifier() {
$field = $this->get_field(
array(
'save_custom' => 1,
)
);
unset( $field['key'] );

$result = $this->field_instance->update_value( array( 'custom_value' ), $this->post_id, $field );
$this->assertSame( array( 'custom_value' ), $result );
}

/**
* Test validate_value with valid selection.
*/
Expand Down
31 changes: 31 additions & 0 deletions tests/php/includes/fields/test-class-acf-field-select.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,37 @@ public function test_update_value_converts_to_strings() {
$this->assertContains( 'blue', $result );
}

/**
* Test save_options does not trigger warnings for JSON-only fields.
*/
public function test_update_value_save_options_handles_json_field_without_id() {
$field = $this->get_field(
array(
'save_options' => 1,
'multiple' => 1,
)
);

$result = $this->field_instance->update_value( array( 'custom_value' ), $this->post_id, $field );
$this->assertSame( array( 'custom_value' ), $result );
}

/**
* Test save_options bails early when field key and ID are both missing.
*/
public function test_update_value_save_options_handles_missing_field_identifier() {
$field = $this->get_field(
array(
'save_options' => 1,
'multiple' => 1,
)
);
unset( $field['key'] );

$result = $this->field_instance->update_value( array( 'custom_value' ), $this->post_id, $field );
$this->assertSame( array( 'custom_value' ), $result );
}

/**
* Test get_rest_schema returns valid schema.
*/
Expand Down
Loading