99 lines
3.4 KiB
PHP
99 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller\Booking\Traits;
|
|
|
|
/**
|
|
* Provides participant validation error extraction for card-based booking flows.
|
|
*
|
|
* Shared between CreateStep2Controller and EditController to identify which
|
|
* participants have validation errors that should be displayed on their cards.
|
|
*/
|
|
trait ParticipantValidationTrait
|
|
{
|
|
/**
|
|
* Extracts participant validation errors from form.
|
|
*
|
|
* Returns two arrays:
|
|
* - errorIndices: Array of participant indices with errors (e.g., [0, 2, 5])
|
|
* - errorMessages: Map of participant index to error messages (e.g., [0 => ['E-Mail: ...', 'Vorname: ...']])
|
|
*
|
|
* @return array{errorIndices: array<int>, errorMessages: array<int, array<string>>}
|
|
*/
|
|
private function extractParticipantValidationErrors($form): array
|
|
{
|
|
$errorIndices = [];
|
|
$errorMessages = [];
|
|
$errors = $form->getErrors(true); // Get all errors recursively
|
|
|
|
foreach ($errors as $error) {
|
|
$propertyPath = $error->getCause()?->getPropertyPath();
|
|
if (null === $propertyPath) {
|
|
continue;
|
|
}
|
|
|
|
// Property paths from BookingDto validation look like "participants[0].email"
|
|
// Note: Using more flexible regex to capture field path after index
|
|
if (preg_match('/participants\[(\d+)\]\.?(.*)/', (string) $propertyPath, $matches)) {
|
|
$index = (int) $matches[1];
|
|
$fieldPath = $matches[2] ?? '';
|
|
$message = $error->getMessage();
|
|
|
|
// Mark this participant as having errors
|
|
$errorIndices[$index] = true;
|
|
|
|
// Initialize error messages array for this participant if needed
|
|
if (false === isset($errorMessages[$index])) {
|
|
$errorMessages[$index] = [];
|
|
}
|
|
|
|
// Add formatted error message
|
|
$errorMessages[$index][] = $this->formatErrorMessage($fieldPath, $message);
|
|
}
|
|
}
|
|
|
|
return [
|
|
'errorIndices' => array_keys($errorIndices),
|
|
'errorMessages' => $errorMessages,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Formats an error message with field context.
|
|
*
|
|
* @param string $fieldPath The field path that has the error (may be empty or nested)
|
|
* @param string $message The error message
|
|
*
|
|
* @return string Formatted error message
|
|
*/
|
|
private function formatErrorMessage(string $fieldPath, string $message): string
|
|
{
|
|
// If no field path, return just the message (error is on participant level)
|
|
if ('' === trim($fieldPath)) {
|
|
return $message;
|
|
}
|
|
|
|
// Extract the first part of the path for nested fields (e.g., "address.street" -> "address")
|
|
$fieldName = explode('.', $fieldPath)[0];
|
|
|
|
// Field name translations for better user understanding
|
|
$fieldLabels = [
|
|
'email' => 'E-Mail',
|
|
'firstName' => 'Vorname',
|
|
'lastName' => 'Nachname',
|
|
'dateOfBirth' => 'Geburtsdatum',
|
|
'assignedRoomId' => 'Zimmer',
|
|
'skiPass' => 'Skipass',
|
|
'transportationOutbound' => 'Anreise',
|
|
'transportationInbound' => 'Rückreise',
|
|
'mobile' => 'Mobilnummer',
|
|
'address' => 'Adresse',
|
|
];
|
|
|
|
$fieldLabel = $fieldLabels[$fieldName] ?? $fieldName;
|
|
|
|
return sprintf('%s: %s', $fieldLabel, $message);
|
|
}
|
|
}
|