Skip to content

Commit b70ef41

Browse files
authored
fix: handle RadioField submission values when using a custom "other" choice (#421)
1 parent e68b7c0 commit b70ef41

File tree

11 files changed

+389
-5
lines changed

11 files changed

+389
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- feat!: Implement `FormField` model and `DataLoader`, and refactor `FormFieldsConnectionResolver` to extend `AbstractConnectionResolver`.
66
- feat!: Refactor `FormsConnectionResolver` and `EntriesConnectionResolver` for compatibility with WPGraphQL v1.26.0 improvements.
77
- feat!: Narrow `FormField.choices` and `FormField.inputs` field types to their implementations.
8+
- fix: Handle RadioField submission values when using a custom "other" choice. H/t @Gytjarek .
89
- dev: Use `FormFieldsDataLoader` to resolve fields instead of instantiating a new `Model`.
910
- chore: Add iterable type hints.
1011
- chore!: Bump minimum WPGraphQL version to v1.26.0.

src/Data/EntryObjectMutation.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ public static function get_field_value_input( array $args, array $form, bool $is
7171
case 'calculation':
7272
$field_value_input = FieldValueInput\ProductValueInput::class;
7373
break;
74+
case 'radio':
75+
$field_value_input = FieldValueInput\RadioValueInput::class;
76+
break;
7477
case 'date':
7578
case 'hidden':
7679
case 'number':
@@ -79,7 +82,6 @@ public static function get_field_value_input( array $args, array $form, bool $is
7982
case 'post_excerpt':
8083
case 'post_title':
8184
case 'price':
82-
case 'radio':
8385
case 'select':
8486
case 'text':
8587
case 'textarea':
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/**
3+
* Manipulates input data for Radio field values.
4+
*
5+
* @package WPGraphQL\GF\Data\FieldValueInput
6+
* @since @todo
7+
*/
8+
9+
declare( strict_types = 1 );
10+
11+
namespace WPGraphQL\GF\Data\FieldValueInput;
12+
13+
use GFCommon;
14+
15+
/**
16+
* Class - RadioValueInput
17+
*/
18+
class RadioValueInput extends AbstractFieldValueInput {
19+
/**
20+
* {@inheritDoc}
21+
*
22+
* @var string
23+
*/
24+
protected $args;
25+
26+
/**
27+
* {@inheritDoc}
28+
*
29+
* @var array<int|string,?string>
30+
*/
31+
public $value;
32+
33+
/**
34+
* {@inheritDoc}
35+
*/
36+
protected function get_field_name(): string {
37+
return 'value';
38+
}
39+
40+
/**
41+
* {@inheritDoc}
42+
*
43+
* @return array<int|string,?string>
44+
*/
45+
protected function prepare_value() {
46+
$value = $this->args;
47+
48+
// Handle values with price.
49+
if ( ! empty( $this->field->enablePrice ) && false === strpos( $value, '|' ) ) {
50+
$value_key = ! empty( $this->field->enablePrice ) || ! empty( $this->field->enableChoiceValue ) ? 'value' : 'text';
51+
$choice_key = array_search( $value, array_column( $this->field->choices, $value_key ), true );
52+
$choice = $this->field->choices[ $choice_key ];
53+
$price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) );
54+
$value = $value . '|' . $price;
55+
}
56+
57+
if ( empty( $this->field->enableOtherChoice ) ) {
58+
return [
59+
$this->field->id => $value,
60+
];
61+
}
62+
63+
$allowed_values = wp_list_pluck( $this->field->choices, 'value' );
64+
65+
if ( ! in_array( $value, $allowed_values, true ) ) {
66+
$_POST[ $this->field->id . '_other' ] = $value;
67+
$_POST[ $this->field->id ] = 'gf_other_choice';
68+
return [
69+
$this->field->id => 'gf_other_choice',
70+
$this->field->id . '_other' => $value,
71+
];
72+
}
73+
74+
return [
75+
$this->field->id => $value,
76+
];
77+
}
78+
79+
/**
80+
* {@inheritDoc}
81+
*/
82+
public function add_value_to_submission( array &$field_values ): void {
83+
$field_values += $this->value;
84+
}
85+
}

src/Model/FormField.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* @property int $databaseId The database ID of the field.
2626
* @property string $id The global Relay ID of the field.
2727
* @property array<string,mixed>[] $inputs The inputs for the field.
28+
* @property string $inputType The input type of the field.
2829
* @property \GF_Field $gfField The Gravity Forms field object.
2930
* @property int $layoutGridColumSpan The layout grid column span of the field.
3031
*/
@@ -224,6 +225,7 @@ static function ( $choice ) use ( $data ) {
224225
);
225226
},
226227
'databaseId' => static fn (): int => (int) $data->id,
228+
'gfField' => static fn (): GF_Field => $data,
227229
'id' => static fn (): string => Relay::toGlobalId( FormFieldsLoader::$name, $data->formId . ':' . $data->id ),
228230
'inputs' => static function () use ( $data ): ?array {
229231
// Emails fields are handled later.
@@ -269,7 +271,7 @@ static function ( $input ) use ( $data ) {
269271

270272
return $inputs;
271273
},
272-
'gfField' => static fn (): GF_Field => $data,
274+
'inputType' => static fn (): string => $data->get_input_type(),
273275
'layoutGridColumSpan' => static fn (): ?int => ! empty( $data->layoutGridColumnSpan ) ? (int) $data->layoutGridColumnSpan : null,
274276
];
275277
}

src/Mutation/UpdateEntry.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ public static function prepare_field_values_for_save( array $values, array $entr
290290
$field_id = strtok( (string) $id, '.' );
291291
$field = GFUtils::get_field_by_id( $form, (int) $field_id );
292292

293+
// Radio fields use the `_other` field for the other choice.
294+
if ( 'radio' === $field->get_input_type() && 'gf_other_choice' === $value ) {
295+
$value = $values[ $id . '_other' ];
296+
}
297+
293298
// Post images can sometimes already be prepared.
294299
if ( 'post_image' !== $field->type || is_array( $value ) ) {
295300
$value = GFFormsModel::prepare_value( $form, $field, $value, $input_name, $entry['id'], $entry );

src/Type/WPObject/FormField/FieldValue/FieldValues.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ public static function value(): array {
4040
return null;
4141
}
4242

43+
// If its a radio field with a "other" choice on a draft entry, the value is stored in a different field.
44+
if ( 'radio' === $source->inputType && isset( $context->gfEntry->entry[ $source->databaseId ] ) && 'gf_other_choice' === $context->gfEntry->entry[ $source->databaseId ] && isset( $context->gfEntry->entry[ $source->databaseId . '_other' ] ) ) {
45+
return $context->gfEntry->entry[ $source->databaseId . '_other' ];
46+
}
47+
4348
return $source->gfField->get_value_export( $context->gfEntry->entry, (string) $source->databaseId ) ?: null;
4449
},
4550
],

tests/_support/Helper/Wpunit.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,6 @@ public function getRadioFieldArgs(): array {
995995
'description',
996996
'descriptionPlacement',
997997
'enableChoiceValue',
998-
'enableOtherChoice',
999998
'errorMessage',
1000999
'inputName',
10011000
'isRequired',

0 commit comments

Comments
 (0)