wip: major refactoring

This commit is contained in:
Björn Fromme
2026-03-16 11:59:09 +01:00
parent d719b17aec
commit 11825191cf
32 changed files with 692 additions and 466 deletions
@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace App\Form\Service\Contract;
use App\Form\Model\BookingDtoInterface;
/**
* Interface for evaluating field state conditions.
*
* Field conditions determine whether a form field should be in a specific state
* (readonly, disabled, hidden) based on participant data, other field values,
* or business logic. Conditions are reusable components that can be combined
* to create complex field state rules.
*
* Key Responsibilities:
* - Evaluate condition logic based on current booking and participant context
* - Declare field dependencies that trigger re-evaluation
* - Support composition for complex conditional logic
* - Provide efficient condition evaluation with minimal performance impact
*/
interface FieldConditionInterface
{
/**
* Evaluates the condition based on current booking and form context.
*
* This method determines whether the condition is met given the current
* state of the booking, participant data, and submitted form values.
* The result is used to determine field state (enabled/disabled/readonly).
*
* @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 (may include partial submissions)
*
* @return bool True if the condition is met, false otherwise
*/
public function evaluate(BookingDtoInterface $bookingDto, int $participantIndex, array $formData): bool;
/**
* Returns field names that trigger re-evaluation of this condition.
*
* This method declares which form fields affect this condition's outcome.
* When any of these fields change (either through user input or other
* field handlers), the condition should be re-evaluated to determine
* if dependent field states need to be updated.
*
* @return string[] Array of field names that affect this condition
*/
public function getDependentFields(): array;
/**
* Returns a human-readable description of this condition.
*
* This method provides a description of what the condition checks,
* useful for debugging, logging, and developer documentation.
* Should be concise but descriptive enough to understand the logic.
*
* @return string A brief description of the condition logic
*/
public function getDescription(): string;
}
@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace App\Form\Service\Contract;
use App\Form\Model\BookingDtoInterface;
/**
* Interface for providing dynamic field options based on context.
*
* Field option providers generate context-aware Symfony form field options
* for dynamic fields that require their configuration to be calculated based
* on the current booking state, participant data, and business logic.
*
* Key Responsibilities:
* - Generate dynamic field options based on booking context
* - Support context-aware field configurations
* - Enable extensible field option generation
* - Provide lazy evaluation of field options
*
* Field options typically include:
* - 'label': The field label text
* - 'placeholder': Placeholder text for input fields
* - 'choices': Available choices for choice fields
* - 'choice_loader': Dynamic choice loader for complex choices
* - 'disabled': Whether the field should be disabled
* - 'required': Whether the field is required
* - 'attr': HTML attributes for the field
*/
interface FieldOptionsProviderInterface
{
/**
* Retrieves form field options for a specified dynamic field.
*
* This method looks up the appropriate option provider for the field
* and executes it with the current booking and participant context to
* generate dynamic field options.
*
* The returned array contains Symfony form field options that will be
* used when building the form field. These options are merged with any
* static options defined in the form type.
*
* @param string $fieldName The name of the field to configure
* @param BookingDtoInterface $bookingDto The current booking data for context (create or edit)
* @param int $participantIndex The index of the participant being configured
*
* @return array<string, mixed> Symfony form field options, or empty array if field not supported
*/
public function getFieldOptions(string $fieldName, BookingDtoInterface $bookingDto, int $participantIndex): array;
/**
* Checks whether a field has option provider support.
*
* This method allows form builders to determine if a field can be
* dynamically configured by this service. It's useful for deciding
* whether to use static field options or dynamic configuration.
*
* @param string $fieldName The name of the field to check
*
* @return bool True if the field has registered option providers, false otherwise
*/
public function hasFieldOptions(string $fieldName): bool;
}
@@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
namespace App\Form\Service\Contract;
use App\Form\Model\BookingDtoInterface;
/**
* Interface for providing dynamic field state based on conditions.
*
* Field state providers determine the runtime state of form fields (readonly,
* disabled, hidden) based on participant data, other field values, and business
* logic. This interface enables centralized field state management with support
* for complex conditional logic.
*
* Key Responsibilities:
* - Calculate field states based on current booking and form context
* - Support multiple state types (readonly, disabled, hidden, etc.)
* - Handle field interdependencies and conditional logic
* - Provide efficient state calculation with caching support
* - Enable dynamic field state updates during form processing
*
* State Types:
* - readonly: Field is visible but not editable
* - disabled: Field is visible but interaction is disabled
* - hidden: Field is not displayed in the form
* - required: Field becomes mandatory based on conditions
* - attr: Custom HTML attributes for advanced styling/behavior
*/
interface FieldStateProviderInterface
{
/**
* Calculates the dynamic state for a specified field.
*
* This method evaluates all configured conditions for a field and returns
* the appropriate state modifications that should be applied to the field.
* The returned array contains Symfony form field attributes that control
* field behavior and appearance.
*
* State attributes may include:
* - 'attr' => ['readonly' => true] - Make field readonly
* - 'disabled' => true - Disable field interaction
* - 'required' => false - Override field requirement
* - 'attr' => ['style' => 'display: none'] - Hide field
* - 'attr' => ['class' => 'conditional-field'] - Add CSS classes
*
* @param string $fieldName The name of the field to evaluate
* @param BookingDtoInterface $bookingDto The current booking data for context (create or edit)
* @param int $participantIndex The index of the participant being evaluated
* @param array<string, mixed> $formData Current form data (may include partial submissions)
*
* @return array<string, mixed> Symfony form field options for state modifications, empty if no changes needed
*/
public function getFieldState(string $fieldName, BookingDtoInterface $bookingDto, int $participantIndex, array $formData = []): array;
/**
* Checks whether a field has state conditions configured.
*
* This method allows form builders to determine if a field has dynamic
* state behavior configured. Fields without state conditions use their
* default static configuration, while fields with conditions require
* runtime state evaluation.
*
* @param string $fieldName The name of the field to check
*
* @return bool True if the field has state conditions configured, false otherwise
*/
public function hasStateConditions(string $fieldName): bool;
/**
* Returns field names that trigger state re-evaluation for a given field.
*
* This method identifies which form fields, when changed, should trigger
* re-evaluation of the specified field's state. This information is used
* for dependency tracking and efficient state updates during form processing.
*
* For example, if field 'serviceSelection' affects the state of field 'ageRestriction',
* then 'serviceSelection' should be returned as a dependency for 'ageRestriction'.
*
* @param string $fieldName The name of the field to get dependencies for
*
* @return string[] Array of field names that affect the specified field's state
*/
public function getFieldStateDependencies(string $fieldName): array;
/**
* Calculates field states for all configured fields at once.
*
* This method provides bulk state calculation for performance optimization
* when multiple field states need to be determined simultaneously. It's
* particularly useful during form building and bulk state updates.
*
* @param BookingDtoInterface $bookingDto The current booking data for context (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 array<string, array<string, mixed>> Field states indexed by field name
*/
public function getAllFieldStates(BookingDtoInterface $bookingDto, int $participantIndex, array $formData = []): array;
}
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace App\Form\Service\Contract;
use App\Form\Model\BookingDtoInterface;
/**
* Interface for handling dynamic participant form field processing and state modification.
*
* Participant field handlers are responsible for processing submitted form data
* for booking participants and updating the BookingCreateDto accordingly. They also
* support field state modification based on processed data and business logic.
* Handlers support dependency management to ensure fields are processed in the correct order.
*/
interface ParticipantFieldHandlerInterface
{
/**
* Returns the field name this handler processes.
*/
public function getFieldName(): string;
/**
* Returns field names this handler depends on.
*
* @return string[]
*/
public function getDependencies(): array;
/**
* Processes the participant field data from submitted form data and updates the DTO.
*
* @param array<string, mixed> $submittedData The submitted participant form data
* @param BookingDtoInterface $bookingDto The booking DTO to update (create or edit)
* @param int $participantIndex The participant index being processed
*/
public function processField(array $submittedData, BookingDtoInterface $bookingDto, int $participantIndex): void;
/**
* Determines if this handler should process the field based on submitted participant data.
*/
public function shouldProcess(array $submittedData, int $participantIndex): bool;
/**
* Returns field state modifications that should be applied after processing.
*
* This method allows handlers to dynamically modify the state of form fields
* based on the processed data. It's called after processField() and can be used
* to enable/disable/hide fields based on the handler's processing results.
*
* @param array<string, mixed> $submittedData The submitted participant form data
* @param BookingDtoInterface $bookingDto The booking DTO (potentially modified by processing)
* @param int $participantIndex The participant index being processed
*
* @return array<string, array<string, mixed>> Field state modifications indexed by field name
*/
public function getFieldStateModifications(array $submittedData, BookingDtoInterface $bookingDto, int $participantIndex): array;
/**
* Returns field names whose state is affected by this handler's processing.
*
* This method declares which form fields have their state modified by this handler.
* It's used for dependency tracking and determining when field states need to be
* recalculated during form processing.
*
* @return string[] Array of field names that this handler may modify the state of
*/
public function getAffectedFieldNames(): array;
}