diff --git a/src/Form/Service/Abstract/AbstractParticipantFieldHandler.php b/src/Form/Service/Abstract/AbstractParticipantFieldHandler.php index 14f8cdc..d296ea3 100644 --- a/src/Form/Service/Abstract/AbstractParticipantFieldHandler.php +++ b/src/Form/Service/Abstract/AbstractParticipantFieldHandler.php @@ -153,6 +153,21 @@ abstract class AbstractParticipantFieldHandler implements ParticipantFieldHandle return is_numeric($value) ? (int) $value : null; } + /** + * Normalizes a checkbox/form toggle value to a boolean. + * + * Form checkboxes may submit true, false, 1, 0, '1', '0', or be absent. + * This method treats only true, 1, and '1' as checked; everything else as unchecked. + * + * @param mixed $value The raw value from form submission + * + * @return bool True if the checkbox is considered checked, false otherwise + */ + protected function normalizeCheckboxValue(mixed $value): bool + { + return true === $value || 1 === $value || '1' === $value; + } + /** * Returns field state modifications that should be applied after processing. * diff --git a/src/Form/Service/ParticipantBulkInsuranceFieldHandler.php b/src/Form/Service/ParticipantBulkInsuranceFieldHandler.php index c241fcc..fcdd652 100644 --- a/src/Form/Service/ParticipantBulkInsuranceFieldHandler.php +++ b/src/Form/Service/ParticipantBulkInsuranceFieldHandler.php @@ -68,6 +68,6 @@ class ParticipantBulkInsuranceFieldHandler extends AbstractParticipantFieldHandl // Get checkbox value from submitted data and store it $bulkInsuranceBooking = $this->getFieldValue($submittedData, $this->getFieldName()); - $participant->bulkInsuranceBooking = (bool) $bulkInsuranceBooking; + $participant->bulkInsuranceBooking = $this->normalizeCheckboxValue($bulkInsuranceBooking); } } diff --git a/src/Form/Service/ParticipantInsuranceFieldHandler.php b/src/Form/Service/ParticipantInsuranceFieldHandler.php index f6ed3c8..58f1a0a 100644 --- a/src/Form/Service/ParticipantInsuranceFieldHandler.php +++ b/src/Form/Service/ParticipantInsuranceFieldHandler.php @@ -334,7 +334,7 @@ class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler // Check if bulk insurance booking is enabled $bulkInsuranceBooking = $applicantData['bulkInsuranceBooking'] ?? false; - if (false === (bool) $bulkInsuranceBooking) { + if (false === $this->normalizeCheckboxValue($bulkInsuranceBooking)) { return false; } diff --git a/src/Form/Service/ParticipantParkingFieldHandler.php b/src/Form/Service/ParticipantParkingFieldHandler.php index 8a46876..11f05f3 100644 --- a/src/Form/Service/ParticipantParkingFieldHandler.php +++ b/src/Form/Service/ParticipantParkingFieldHandler.php @@ -66,7 +66,7 @@ class ParticipantParkingFieldHandler extends AbstractParticipantFieldHandler } $parkingSelected = $this->getFieldValue($submittedData, $this->getFieldName()); - $isParkingSelected = (bool) $parkingSelected; + $isParkingSelected = $this->normalizeCheckboxValue($parkingSelected); // Store boolean value for backward compatibility $participant->parking = $isParkingSelected; diff --git a/src/Form/Service/ParticipantRentalInsuranceFieldHandler.php b/src/Form/Service/ParticipantRentalInsuranceFieldHandler.php index 79848a7..090bbcd 100644 --- a/src/Form/Service/ParticipantRentalInsuranceFieldHandler.php +++ b/src/Form/Service/ParticipantRentalInsuranceFieldHandler.php @@ -100,7 +100,7 @@ class ParticipantRentalInsuranceFieldHandler extends AbstractParticipantFieldHan // Extract checkbox value from submitted data (this comes from the rentalInsuranceSelected property) $rentalInsuranceSelected = $this->getFieldValue($submittedData, $this->getFieldName()); - $isRentalInsuranceSelected = (bool) $rentalInsuranceSelected; + $isRentalInsuranceSelected = $this->normalizeCheckboxValue($rentalInsuranceSelected); // Store boolean value $participant->rentalInsuranceSelected = $isRentalInsuranceSelected; diff --git a/tests/Form/Service/ParticipantParkingFieldHandlerTest.php b/tests/Form/Service/ParticipantParkingFieldHandlerTest.php index ae26588..7568e65 100644 --- a/tests/Form/Service/ParticipantParkingFieldHandlerTest.php +++ b/tests/Form/Service/ParticipantParkingFieldHandlerTest.php @@ -37,6 +37,22 @@ class ParticipantParkingFieldHandlerTest extends TestCase $this->assertTrue($this->handler->shouldProcess(['some' => 'data'], BookingDto::MODE_EDIT, 5)); } + /** + * @dataProvider normalizeCheckboxValueCheckedProvider + */ + public function testNormalizeCheckboxValueReturnsTrueWhenChecked(mixed $value): void + { + $this->assertTrue($this->invokeNormalizeCheckboxValue($value)); + } + + /** + * @dataProvider normalizeCheckboxValueUncheckedProvider + */ + public function testNormalizeCheckboxValueReturnsFalseWhenUnchecked(mixed $value): void + { + $this->assertFalse($this->invokeNormalizeCheckboxValue($value)); + } + public function testProcessFieldWithoutParticipant(): void { $travel = new Travel(); @@ -241,6 +257,40 @@ class ParticipantParkingFieldHandlerTest extends TestCase $this->assertNull($participant->parkingService); } + /** + * @return array + */ + public static function normalizeCheckboxValueCheckedProvider(): array + { + return [ + 'true' => [true], + 'int 1' => [1], + 'string 1' => ['1'], + ]; + } + + /** + * @return array + */ + public static function normalizeCheckboxValueUncheckedProvider(): array + { + return [ + 'false' => [false], + 'int 0' => [0], + 'string 0' => ['0'], + 'empty string' => [''], + 'null' => [null], + 'non-numeric string' => ['off'], + ]; + } + + private function invokeNormalizeCheckboxValue(mixed $value): bool + { + $reflection = new \ReflectionMethod($this->handler, 'normalizeCheckboxValue'); + + return $reflection->invoke($this->handler, $value); + } + private function createTransportationService(string $subType): Service { $service = new Service();