participant; $bookingContext = $value->bookingContext; // Determine if strict validation applies if (true === $this->shouldApplyStrictValidation($bookingContext)) { $this->enforceStrictValidation($participant); } // Relaxed validation: no required checks, format validation handled by existing constraints } /** * Determines whether strict validation should be applied. * * Strict validation applies when: * 1. In create mode (new booking), OR * 2. In edit mode AND applicant is not mutable (booking has restrictions) * * @param BookingDto $bookingContext The booking context * * @return bool True if strict validation should apply */ private function shouldApplyStrictValidation(BookingDto $bookingContext): bool { $mode = $bookingContext->getMode(); // Create mode: always strict if (BookingDto::MODE_CREATE === $mode) { return true; } // Edit mode: check applicant mutability $applicant = $bookingContext->participants[0] ?? null; if (null === $applicant) { return true; // Fail-safe: if no applicant, apply strict validation } // Strict validation if applicant is not mutable return false === $applicant->mutable; } /** * Enforces strict validation: all required fields must be filled. * * Validates: * - Personal data: firstName, lastName, dateOfBirth, email * - Address: street, postCode, city, country * - Services: skiPass, transportationOutbound, transportationInbound, insurance * * @param ParticipantDto $participant The participant to validate */ private function enforceStrictValidation(ParticipantDto $participant): void { // Skip validation for canceled participants if (true === $participant->isCanceled()) { return; } // Personal data validation $this->validateRequired($participant->firstName, 'participant.firstName', 'Bitte angeben'); $this->validateRequired($participant->lastName, 'participant.lastName', 'Bitte angeben'); $this->validateRequired($participant->email, 'participant.email', 'Bitte angeben'); if (null === $participant->dateOfBirth) { $this->context->buildViolation('Bitte angeben') ->atPath('participant.dateOfBirth') ->addViolation(); } // Address validation only for applicant (index 0) if (0 === $participant->index) { if (null !== $participant->address) { $this->validateRequired($participant->address->street, 'participant.address.street', 'Bitte angeben'); $this->validateRequired($participant->address->postCode, 'participant.address.postCode', 'Bitte angeben'); $this->validateRequired($participant->address->city, 'participant.address.city', 'Bitte angeben'); $this->validateRequired($participant->address->country, 'participant.address.country', 'Bitte angeben'); } else { $this->context->buildViolation('Bitte angeben') ->atPath('participant.address') ->addViolation(); } } // Service validation if (null === $participant->skiPass) { $this->context->buildViolation('Bitte auswählen') ->atPath('participant.skiPass') ->addViolation(); } if (null === $participant->transportationOutbound) { $this->context->buildViolation('Bitte auswählen') ->atPath('participant.transportationOutbound') ->addViolation(); } if (null === $participant->transportationInbound) { $this->context->buildViolation('Bitte auswählen') ->atPath('participant.transportationInbound') ->addViolation(); } if (null === $participant->insurance) { $this->context->buildViolation('Bitte auswählen') ->atPath('participant.insurance') ->addViolation(); } } /** * Validates that a field is not empty (null or blank string). * * @param mixed $value The field value to check * @param string $path The property path for the violation * @param string $message The violation message */ private function validateRequired(mixed $value, string $path, string $message): void { if (null === $value || '' === trim((string) $value)) { $this->context->buildViolation($message) ->atPath($path) ->addViolation(); } } }