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,144 @@
<?php
declare(strict_types=1);
namespace App\Form\Service\Abstract;
use App\Form\Model\BookingDtoInterface;
use App\Form\Service\Contract\FieldConditionInterface;
use App\Form\Service\Contract\FieldStateProviderInterface;
use App\Form\Service\Trait\FormTraversalTrait;
/**
* Abstract base class for field state providers.
*
* This class contains common field state evaluation logic shared between
* different field state provider implementations. It provides the core
* functionality for evaluating field conditions and applying state modifications.
*/
abstract class AbstractFieldStateProvider implements FieldStateProviderInterface
{
use FormTraversalTrait;
/** @var array<string, array<string, FieldConditionInterface>> Field state conditions indexed by field name and state type */
protected array $fieldStateConditions = [];
public function __construct()
{
$this->registerFieldStateConditions();
}
/**
* Calculates the dynamic state for a specified field.
*
* Evaluates all configured conditions for a field and returns the appropriate
* state modifications. State conditions are organized by state type (readonly,
* disabled, etc.) and evaluated independently.
*
* @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 for condition evaluation
*
* @return array<string, mixed> Symfony form field options for state modifications
*/
public function getFieldState(string $fieldName, BookingDtoInterface $bookingDto, int $participantIndex, array $formData = []): array
{
if (!isset($this->fieldStateConditions[$fieldName])) {
return [];
}
$stateModifications = [];
$attributes = [];
foreach ($this->fieldStateConditions[$fieldName] as $stateType => $condition) {
if ($condition->evaluate($bookingDto, $participantIndex, $formData)) {
switch ($stateType) {
case 'readonly':
$attributes['readonly'] = true;
break;
case 'disabled':
$stateModifications['disabled'] = true;
break;
case 'required':
$stateModifications['required'] = true;
break;
case 'hidden':
$attributes['style'] = ($attributes['style'] ?? '').' display: none;';
break;
}
}
}
if (!empty($attributes)) {
$stateModifications['attr'] = $attributes;
}
return $stateModifications;
}
/**
* Checks whether a field has state conditions configured.
*
* @param string $fieldName The name of the field to check
*
* @return bool True if the field has state conditions configured
*/
public function hasStateConditions(string $fieldName): bool
{
return isset($this->fieldStateConditions[$fieldName]) && !empty($this->fieldStateConditions[$fieldName]);
}
/**
* Returns field names that trigger state re-evaluation for a given field.
*
* @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
{
if (!isset($this->fieldStateConditions[$fieldName])) {
return [];
}
$dependencies = [];
foreach ($this->fieldStateConditions[$fieldName] as $condition) {
$dependencies = array_merge($dependencies, $condition->getDependentFields());
}
return array_unique($dependencies);
}
/**
* Calculates field states for all configured fields at once.
*
* @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
{
$allStates = [];
foreach (array_keys($this->fieldStateConditions) as $fieldName) {
$fieldState = $this->getFieldState($fieldName, $bookingDto, $participantIndex, $formData);
if (!empty($fieldState)) {
$allStates[$fieldName] = $fieldState;
}
}
return $allStates;
}
/**
* Registers field state conditions during service initialization.
*
* This method must be implemented by concrete classes to define their
* specific field state conditions.
*/
abstract protected function registerFieldStateConditions(): void;
}