diff --git a/projects/packages/forms/changelog/add-forms-feedback-field-id b/projects/packages/forms/changelog/add-forms-feedback-field-id new file mode 100644 index 0000000000000..46a37ae1f9e95 --- /dev/null +++ b/projects/packages/forms/changelog/add-forms-feedback-field-id @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Forms: Preserve html ids when processing feedback. diff --git a/projects/packages/forms/src/contact-form/class-feedback-field.php b/projects/packages/forms/src/contact-form/class-feedback-field.php index 14e54460d61e7..0b6a360433252 100644 --- a/projects/packages/forms/src/contact-form/class-feedback-field.php +++ b/projects/packages/forms/src/contact-form/class-feedback-field.php @@ -49,21 +49,32 @@ class Feedback_Field { */ private $meta; + /** + * The original form field ID from the form schema. + * + * @since $$next-version$$ + * + * @var string + */ + protected $form_field_id = ''; + /** * Constructor. * - * @param string $key The key of the field. - * @param mixed $label The label of the field. Non-string values will be converted to empty string. - * @param mixed $value The value of the field. - * @param string $type The type of the field (default is 'basic'). - * @param array $meta Additional metadata for the field (default is an empty array). + * @param string $key The key of the field. + * @param mixed $label The label of the field. Non-string values will be converted to empty string. + * @param mixed $value The value of the field. + * @param string $type The type of the field (default is 'basic'). + * @param array $meta Additional metadata for the field (default is an empty array). + * @param string|null $form_field_id The original form field ID (default is null). */ - public function __construct( $key, $label, $value, $type = 'basic', $meta = array() ) { - $this->key = $key; - $this->label = is_string( $label ) ? html_entity_decode( $label, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) : ''; - $this->value = $value; - $this->type = $type; - $this->meta = $meta; + public function __construct( $key, $label, $value, $type = 'basic', $meta = array(), $form_field_id = null ) { + $this->key = $key; + $this->label = is_string( $label ) ? html_entity_decode( $label, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) : ''; + $this->value = $value; + $this->type = $type; + $this->meta = $meta; + $this->form_field_id = is_string( $form_field_id ) ? $form_field_id : ''; } /** @@ -107,6 +118,17 @@ public function get_value() { return $this->value; } + /** + * Get the original form field ID. + * + * @since $$next-version$$ + * + * @return string + */ + public function get_form_field_id() { + return $this->form_field_id; + } + /** * Get the value of the field for rendering. * @@ -242,11 +264,12 @@ public function get_meta_key_value( $meta_key ) { */ public function serialize() { return array( - 'key' => $this->get_key(), - 'label' => $this->get_label(), - 'value' => $this->get_value(), - 'type' => $this->get_type(), - 'meta' => $this->get_meta(), + 'key' => $this->get_key(), + 'label' => $this->get_label(), + 'value' => $this->get_value(), + 'type' => $this->get_type(), + 'meta' => $this->get_meta(), + 'form_field_id' => $this->get_form_field_id(), ); } /** @@ -266,7 +289,8 @@ public static function from_serialized( $data ) { $data['label'], $data['value'], $data['type'] ?? 'basic', - $data['meta'] ?? array() + $data['meta'] ?? array(), + $data['form_field_id'] ?? '' ); } diff --git a/projects/packages/forms/src/contact-form/class-feedback.php b/projects/packages/forms/src/contact-form/class-feedback.php index 478585285d5b0..6685162e9c06b 100644 --- a/projects/packages/forms/src/contact-form/class-feedback.php +++ b/projects/packages/forms/src/contact-form/class-feedback.php @@ -1155,7 +1155,8 @@ private function get_computed_fields( $post_data, $form ) { $label = wp_strip_all_tags( $field->get_attribute( 'label' ) ); $key = $i . '_' . $label; - $fields[ $key ] = new Feedback_Field( $key, $label, $value, $type ); + $meta = array(); + $fields[ $key ] = new Feedback_Field( $key, $label, $value, $type, $meta, $field_id ); if ( ! $this->has_file && $fields[ $key ]->has_file() ) { $this->has_file = true; } @@ -1221,4 +1222,41 @@ private function get_computed_consent( $post_data, $form ) { return false; } + + /** + * Get a field by its original form ID. + * + * @since $$next-version$$ + * + * @param string $id Original form field ID. + * @return Feedback_Field|null + */ + public function get_field_by_form_field_id( $id ) { + if ( ! is_string( $id ) || $id === '' ) { + return null; + } + foreach ( $this->fields as $field ) { + if ( $field->get_form_field_id() === $id ) { + return $field; + } + } + return null; + } + + /** + * Get a field render value by its original form ID. + * + * @since $$next-version$$ + * + * @param string $id Original form field ID. + * @param string $context Render context. + * @return string + */ + public function get_field_value_by_form_field_id( $id, $context = 'default' ) { + $field = $this->get_field_by_form_field_id( $id ); + if ( ! $field ) { + return ''; + } + return (string) $field->get_render_value( $context ); + } } diff --git a/projects/packages/forms/tests/php/contact-form/Feedback_Field_Test.php b/projects/packages/forms/tests/php/contact-form/Feedback_Field_Test.php index 3b3dd7b293e5c..dd641673a273a 100644 --- a/projects/packages/forms/tests/php/contact-form/Feedback_Field_Test.php +++ b/projects/packages/forms/tests/php/contact-form/Feedback_Field_Test.php @@ -33,13 +33,14 @@ public function test_Feedback_Field_can_be_instantiated() { $this->assertEquals( 'test_value', $field->get_value() ); $this->assertEquals( 'basic', $field->get_type() ); $this->assertEquals( array(), $field->get_meta() ); + $this->assertSame( '', $field->get_form_field_id() ); } /** * Test that the Feedback_Field class can be instantiated with additional parameters. */ public function test_Feedback_Field_with_additional_parameters() { - $field = new Feedback_Field( 'test_key', 'test_label', 'test_value', 'text', array( 'meta_key' => 'meta_value' ) ); + $field = new Feedback_Field( 'test_key', 'test_label', 'test_value', 'text', array( 'meta_key' => 'meta_value' ), 'firstname' ); $this->assertEquals( 'test_key', $field->get_key() ); $this->assertEquals( 'test_label', $field->get_label() ); $this->assertEquals( 'test_value', $field->get_value() ); @@ -47,6 +48,7 @@ public function test_Feedback_Field_with_additional_parameters() { $this->assertEquals( array( 'meta_key' => 'meta_value' ), $field->get_meta() ); $this->assertEquals( 'meta_value', $field->get_meta_key_value( 'meta_key' ) ); $this->assertNull( $field->get_meta_key_value( 'non_existant' ) ); + $this->assertEquals( 'firstname', $field->get_form_field_id() ); } /** @@ -59,6 +61,7 @@ public function test_Feedback_Field_with_empty_values() { $this->assertSame( '', $field->get_value() ); $this->assertEquals( 'basic', $field->get_type() ); $this->assertEquals( array(), $field->get_meta() ); + $this->assertSame( '', $field->get_form_field_id() ); } /** diff --git a/projects/packages/forms/tests/php/contact-form/Feedback_Test.php b/projects/packages/forms/tests/php/contact-form/Feedback_Test.php index 1e60e64773e9e..0e02ff52a0970 100644 --- a/projects/packages/forms/tests/php/contact-form/Feedback_Test.php +++ b/projects/packages/forms/tests/php/contact-form/Feedback_Test.php @@ -1983,4 +1983,51 @@ public function test_validate_radio_form() { Contact_Form::reset_errors(); } + + public function test_get_field_by_id_and_value_by_id_new_submission() { + $form_id = Utility::get_form_id(); + $_post_data = Utility::get_post_request( + array( + 'name' => 'John Doe', + 'email' => 'john@example.com', + 'message' => 'Hello!', + ), + 'g' . $form_id + ); + + $form = new Contact_Form( + array( + 'title' => 'Test Form', + 'description' => 'This is a test form.', + ), + "[contact-field label='Name' type='name' required='1'/][contact-field label='Email' type='email' required='1'/][contact-field label='Message' type='textarea' required='1'/]" + ); + + $response = Feedback::from_submission( $_post_data, $form ); + $field_ids = $form->get_field_ids(); + $email_id = $field_ids['email']; + + $this->assertNotEmpty( $email_id ); + $this->assertEquals( 'john@example.com', $response->get_field_value_by_form_field_id( $email_id ) ); + + $field = $response->get_field_by_form_field_id( $email_id ); + $this->assertInstanceOf( Feedback_Field::class, $field ); + $this->assertEquals( $email_id, $field->get_form_field_id() ); + + // Save and reload; ensure the field id and value persist correctly + $saved_post_id = $response->save(); + $saved_response = Feedback::get( $saved_post_id ); + $this->assertEquals( 'john@example.com', $saved_response->get_field_value_by_form_field_id( $email_id ) ); + $saved_field = $saved_response->get_field_by_form_field_id( $email_id ); + $this->assertInstanceOf( Feedback_Field::class, $saved_field ); + $this->assertEquals( $email_id, $saved_field->get_form_field_id() ); + } + + public function test_get_field_by_id_and_value_by_id_legacy() { + $post_id = Utility::create_legacy_feedback( array() ); + $response = Feedback::get( $post_id ); + + $this->assertSame( '', $response->get_field_value_by_form_field_id( 'email' ) ); + $this->assertNull( $response->get_field_by_form_field_id( 'email' ) ); + } } diff --git a/projects/plugins/jetpack/changelog/add-forms-feedback-field-id b/projects/plugins/jetpack/changelog/add-forms-feedback-field-id new file mode 100644 index 0000000000000..79fb0d4eb5dc2 --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-forms-feedback-field-id @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Forms: Preserve html ids when processing feedback.