feat: replace date field for participant's birthday

This commit is contained in:
Björn Fromme
2026-03-16 11:59:11 +01:00
parent 8436124cbc
commit 8f274bbb44
2 changed files with 54 additions and 8 deletions
+9 -2
View File
@@ -166,9 +166,16 @@ class BookingParticipantType extends AbstractType
], $getFieldState('lastName'))) ], $getFieldState('lastName')))
->add('dateOfBirth', BirthdayType::class, $this->mergeFieldState([ ->add('dateOfBirth', BirthdayType::class, $this->mergeFieldState([
'label' => 'Geburtsdatum', 'label' => 'Geburtsdatum',
'html5' => true, 'widget' => 'text',
'widget' => 'single_text',
'input' => 'datetime_immutable', 'input' => 'datetime_immutable',
'attr' => [
'class' => 'flex items-center space-x-2',
],
'placeholder' => [
'year' => 'Jahr',
'month' => 'Monat',
'day' => 'Tag',
],
], $getFieldState('dateOfBirth'))) ], $getFieldState('dateOfBirth')))
->add('gender', ChoiceType::class, $this->mergeFieldState([ ->add('gender', ChoiceType::class, $this->mergeFieldState([
'label' => 'Geschlecht', 'label' => 'Geschlecht',
@@ -76,7 +76,14 @@ class ParticipantDateOfBirthFieldHandler extends AbstractParticipantFieldHandler
* Normalizes a date value from form submission to DateTimeImmutable or null. * Normalizes a date value from form submission to DateTimeImmutable or null.
* *
* This method handles the conversion of form date values to proper DateTimeImmutable * This method handles the conversion of form date values to proper DateTimeImmutable
* objects. It gracefully handles empty strings, null values, and invalid date formats. * objects. It gracefully handles empty strings, null values, invalid date formats,
* and array input from multi-field date widgets (BirthdayType).
*
* Supported input formats:
* - Array: ['year' => int, 'month' => int, 'day' => int] from BirthdayType
* - DateTimeInterface: Already converted DateTime objects
* - String: ISO date strings or any format parseable by DateTimeImmutable
* - Null/empty: No date selected
* *
* @param mixed $value The raw value from form submission * @param mixed $value The raw value from form submission
* *
@@ -84,18 +91,50 @@ class ParticipantDateOfBirthFieldHandler extends AbstractParticipantFieldHandler
*/ */
private function normalizeDateValue(mixed $value): ?\DateTimeImmutable private function normalizeDateValue(mixed $value): ?\DateTimeImmutable
{ {
// Handle null or empty string (no date selected) // Handle null first
if (null === $value || '' === trim((string) $value)) { if (null === $value) {
return null; return null;
} }
// Handle array input from multi-field date widget (BirthdayType)
if (true === is_array($value)) {
// Check if all required fields are present and valid
if (false === isset($value['year'], $value['month'], $value['day'])
|| '' === trim((string) ($value['year'] ?? ''))
|| '' === trim((string) ($value['month'] ?? ''))
|| '' === trim((string) ($value['day'] ?? ''))
) {
return null;
}
try {
// Create date string in ISO format (YYYY-MM-DD)
$dateString = sprintf(
'%04d-%02d-%02d',
(int) $value['year'],
(int) $value['month'],
(int) $value['day']
);
return new \DateTimeImmutable($dateString);
} catch (\Exception $e) {
// Invalid date components (e.g., Feb 31, invalid year)
return null;
}
}
// If already a DateTimeInterface, convert to DateTimeImmutable // If already a DateTimeInterface, convert to DateTimeImmutable
if ($value instanceof \DateTimeInterface) { if ($value instanceof \DateTimeInterface) {
return \DateTimeImmutable::createFromInterface($value); return \DateTimeImmutable::createFromInterface($value);
} }
// Try to parse string date // Handle string date (including empty string check)
if (is_string($value)) { if (true === is_string($value)) {
// Empty string means no date selected
if ('' === trim($value)) {
return null;
}
try { try {
return new \DateTimeImmutable($value); return new \DateTimeImmutable($value);
} catch (\Exception $e) { } catch (\Exception $e) {