diff --git a/projects/packages/forms/changelog/fix-forms-rating-field-input-validation b/projects/packages/forms/changelog/fix-forms-rating-field-input-validation new file mode 100644 index 000000000000..f98db0640628 --- /dev/null +++ b/projects/packages/forms/changelog/fix-forms-rating-field-input-validation @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Forms: Handle non-string values in the rating field rendering pipeline. 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 e4c9aaf3eefc..ced99a935511 100644 --- a/projects/packages/forms/src/contact-form/class-feedback-field.php +++ b/projects/packages/forms/src/contact-form/class-feedback-field.php @@ -317,6 +317,12 @@ private function get_country_code_from_phone( $phone_number ) { * @return array|string Structured rating data or original value if parsing fails. */ private function get_rating_value() { + // Field values arrive as `mixed` (per the constructor); short-circuit + // to an empty string for non-string values. + if ( ! is_string( $this->value ) ) { + return ''; + } + if ( empty( $this->value ) ) { return $this->value; } 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 b4787e95667a..645abbaf80c1 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 @@ -587,6 +587,43 @@ public function test_rating_field_with_zero_rating() { $this->assertEquals( 5, $value['maxRating'] ); } + /** + * Test rating field with non-string array input renders safely in web context. + */ + public function test_rating_field_with_array_value_renders_safely_in_web_context() { + $field = new Feedback_Field( 'rating_key', 'Rating', array( '1/5', '2/5' ), 'rating' ); + + $value = $field->get_render_value( 'web' ); + + $this->assertIsString( $value ); + $this->assertSame( '', $value ); + } + + /** + * Test rating field with non-string array input renders safely in email context. + */ + public function test_rating_field_with_array_value_renders_safely_in_email_context() { + $field = new Feedback_Field( 'rating_key', 'Rating', array( '3/5' ), 'rating' ); + + $value = $field->get_render_value( 'email' ); + + $this->assertIsString( $value ); + $this->assertSame( '', $value ); + } + + /** + * Regression pin for the email_html rating path. render_email_rating() already + * guards non-string input; this test exists to keep that safe path safe. + */ + public function test_rating_field_with_array_value_renders_safely_in_email_html_context() { + $field = new Feedback_Field( 'rating_key', 'Rating', array( '3/5' ), 'rating' ); + + $value = $field->get_render_value( 'email_html' ); + + $this->assertIsString( $value ); + $this->assertStringNotContainsString( '★', $value ); + } + // ─── Email HTML rendering tests ─── /**