wip: dynamic services fields

This commit is contained in:
Björn Fromme committed 2026-03-16 11:59:09 +01:00
1 parent 7003c0d81b
commit 6bd483d768
21 files changed
+634 -39

No files matched your search

@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
namespace App\Form\Service\Condition;
use App\BusProNet\Model\Room;
use App\Form\Model\BookingDtoInterface;
use App\Form\Service\Contract\FieldConditionInterface;
/**
* Condition that evaluates whether a participant has selected a room with specific code(s).
*
* This condition checks if a participant has selected a room that matches any of the
* configured room codes. This allows for flexible room-based field visibility logic
* where different fields can be shown based on the selected room type.
*/
class RoomSelectionCondition implements FieldConditionInterface
{
private array $requiredRoomCodes;
/**
* Creates a new room selection condition for specified room codes.
*
* @param array<string> $requiredRoomCodes Room codes that should trigger this condition
*/
public function __construct(array $requiredRoomCodes)
{
$this->requiredRoomCodes = array_map('strtolower', $requiredRoomCodes);
}
/**
* Evaluates whether the participant has selected a room with one of the required codes.
*
* Checks both submitted form data and participant DTO data to determine
* if the selected room matches any of the configured room codes.
*
* @param BookingDtoInterface $bookingDto The current booking data (create or edit)
* @param int $participantIndex The index of the participant being evaluated
* @param array<string, mixed> $formData Current form data for condition evaluation
*
* @return bool True if room with matching code is selected, false otherwise
*/
public function evaluate(BookingDtoInterface $bookingDto, int $participantIndex, array $formData): bool
{
// First check submitted form data for room selection
if (isset($formData['participants'][$participantIndex]['assignedRoomId'])) {
$selectedRoomId = $formData['participants'][$participantIndex]['assignedRoomId'];
if (true === is_numeric($selectedRoomId)) {
$room = $this->findRoomById((int) $selectedRoomId, $bookingDto);
if (null !== $room && in_array(strtolower($room->code ?? ''), $this->requiredRoomCodes, true)) {
return true;
}
}
}
// Then check participant DTO data for existing room selection
$participant = $bookingDto->getParticipant($participantIndex);
if (null !== $participant && null !== $participant->assignedRoomId) {
$room = $this->findRoomById($participant->assignedRoomId, $bookingDto);
if (null !== $room && in_array(strtolower($room->code ?? ''), $this->requiredRoomCodes, true)) {
return true;
}
}
return false;
}
/**
* Returns field names that trigger re-evaluation of this condition.
*
* This condition depends on the assignedRoomId field, so any changes to room
* selection should trigger re-evaluation of dependent fields.
*
* @return string[] Array containing the field names that affect this condition
*/
public function getDependentFields(): array
{
return ['assignedRoomId'];
}
/**
* Returns a human-readable description of this condition.
*
* @return string A brief description of the condition logic
*/
public function getDescription(): string
{
$codes = implode(', ', $this->requiredRoomCodes);
return "Field visible when room with code(s) [{$codes}] is selected";
}
/**
* Finds a room by ID in the available travel rooms.
*
* @param int $roomId The room ID to find
* @param BookingDtoInterface $bookingDto The booking DTO containing travel data
*
* @return Room|null The found room or null if not found
*/
private function findRoomById(int $roomId, BookingDtoInterface $bookingDto): ?Room
{
foreach ($bookingDto->travel->rooms as $room) {
if ($room->id === $roomId) {
return $room;
}
}
return null;
}
}