chore: fix phpstan errors

This commit is contained in:
Björn Fromme committed 2026-04-16 16:27:35 +02:00
1 parent 4e925171b3
commit 0fcecc9c58
109 files changed
+510 -429

No files matched your search

@@ -36,10 +36,10 @@ abstract class AbstractFieldOptionsProvider implements FieldOptionsProviderInter
* 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 BookingDto $bookingDto The current booking data for context (create or edit)
* @param int $participantIndex The index of the participant being configured
* @param array $options Additional options to customize field behavior
* @param string $fieldName The name of the field to configure
* @param BookingDto $bookingDto The current booking data for context (create or edit)
* @param int $participantIndex The index of the participant being configured
* @param array<string, mixed> $options Additional options to customize field behavior
*
* @return array<string, mixed> Symfony form field options, or empty array if field not supported
*/
@@ -79,6 +79,7 @@ class BulkInsuranceBookingCondition implements FieldConditionInterface
/**
* Gets the bulk insurance booking flag value from form data or participant DTO.
*/
/** @param array<string, mixed> $formData */
private function getBulkInsuranceBookingValue(array $formData, object $applicant): bool
{
// First check form data (for fresh submissions)
@@ -168,6 +168,7 @@ class CompositeCondition implements FieldConditionInterface
* Returns false as soon as any condition evaluates to false,
* avoiding unnecessary evaluation of remaining conditions.
*/
/** @param array<string, mixed> $formData */
private function evaluateAnd(BookingDto $bookingDto, int $participantIndex, array $formData): bool
{
foreach ($this->conditions as $condition) {
@@ -185,6 +186,7 @@ class CompositeCondition implements FieldConditionInterface
* Returns true as soon as any condition evaluates to true,
* avoiding unnecessary evaluation of remaining conditions.
*/
/** @param array<string, mixed> $formData */
private function evaluateOr(BookingDto $bookingDto, int $participantIndex, array $formData): bool
{
foreach ($this->conditions as $condition) {
@@ -199,6 +201,7 @@ class CompositeCondition implements FieldConditionInterface
/**
* Evaluates NOT logic by inverting the result of the single condition.
*/
/** @param array<string, mixed> $formData */
private function evaluateNot(BookingDto $bookingDto, int $participantIndex, array $formData): bool
{
return !$this->conditions[0]->evaluate($bookingDto, $participantIndex, $formData);
@@ -219,6 +222,7 @@ class CompositeCondition implements FieldConditionInterface
/**
* Validates condition count based on operator requirements.
*/
/** @param list<mixed> $conditions */
private function validateConditionCount(string $operator, array $conditions): void
{
$conditionCount = count($conditions);
@@ -175,6 +175,7 @@ class FieldValueCondition implements FieldConditionInterface
/**
* Retrieves field value from form data or participant data.
*/
/** @param array<string, mixed> $formData */
private function getFieldValue(array $formData, int $participantIndex, BookingDto $bookingDto): mixed
{
// First check participant-specific form data
@@ -212,6 +213,7 @@ class FieldValueCondition implements FieldConditionInterface
/**
* Checks if field value is in array of expected values.
*/
/** @param list<mixed> $expectedValues */
private function compareIn(mixed $fieldValue, array $expectedValues): bool
{
foreach ($expectedValues as $expectedValue) {
@@ -28,10 +28,6 @@ class RentalInsuranceAvailableCondition implements FieldConditionInterface
*/
public function evaluate(BookingDto $bookingDto, int $participantIndex, array $formData): bool
{
if (null === $bookingDto->travel) {
return false;
}
$services = $bookingDto->travel->getAdditionalServicesBySubTypes(
Constants::TOKEN_RENTAL_INSURANCE,
true
@@ -49,12 +49,7 @@ class RentalSelectionCondition implements FieldConditionInterface
if (null !== $participant) {
$rentals = $participant->rentals;
if (false === empty($rentals)) {
// Check if any rental services are actually selected
foreach ($rentals as $rental) {
if ($rental instanceof Service) {
return true;
}
}
return true;
}
}
@@ -17,9 +17,9 @@ use App\Form\Service\Contract\FieldConditionInterface;
*/
class RoomSelectionCondition implements FieldConditionInterface
{
private const MATCH_MODE_EXACT = 'exact';
private const MATCH_MODE_PREFIX = 'prefix';
/** @var list<string> */
private array $requiredRoomCodes;
private string $matchMode;
@@ -161,6 +161,7 @@ class ServiceSubTypeCondition implements FieldConditionInterface
/**
* Retrieves service from form data or participant data.
*/
/** @param array<string, mixed> $formData */
private function getService(array $formData, int $participantIndex, BookingDto $bookingDto): ?Service
{
// First check participant-specific form data
@@ -185,6 +186,7 @@ class ServiceSubTypeCondition implements FieldConditionInterface
/**
* Checks if sub-type is in the expected array.
*/
/** @param string|list<string> $expectedSubTypes */
private function isSubTypeIn(string $actualSubType, string|array $expectedSubTypes): bool
{
if (is_string($expectedSubTypes)) {
@@ -214,6 +216,7 @@ class ServiceSubTypeCondition implements FieldConditionInterface
/**
* Validates expected sub-type based on operator requirements.
*/
/** @param string|list<string> $expectedSubType */
private function validateExpectedSubType(string $operator, string|array $expectedSubType): void
{
if (in_array($operator, [self::OPERATOR_IN, self::OPERATOR_NOT_IN], true) && !is_array($expectedSubType)) {
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace App\Form\Service\Condition;
use App\BusProNet\Model\Service;
use App\Form\Model\BookingDto;
use App\Form\Service\Contract\FieldConditionInterface;
@@ -39,7 +38,7 @@ class SkiPassSelectionCondition implements FieldConditionInterface
// First check submitted form data for skipass selection
if (isset($formData['participants'][$participantIndex]['skiPass'])) {
$selectedSkiPass = $formData['participants'][$participantIndex]['skiPass'];
if (null !== $selectedSkiPass && '' !== $selectedSkiPass) {
if ('' !== $selectedSkiPass) {
return true;
}
}
@@ -47,10 +46,7 @@ class SkiPassSelectionCondition implements FieldConditionInterface
// Then check participant DTO data for existing skipass selection
$participant = $bookingDto->getParticipant($participantIndex);
if (null !== $participant && null !== $participant->skiPass) {
// Check if skipass is actually a Service object
if ($participant->skiPass instanceof Service) {
return true;
}
return true;
}
return false;
@@ -41,10 +41,10 @@ interface FieldOptionsProviderInterface
* 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 BookingDto $bookingDto The current booking data for context (create or edit)
* @param int $participantIndex The index of the participant being configured
* @param array $options Additional options to customize field behavior
* @param string $fieldName The name of the field to configure
* @param BookingDto $bookingDto The current booking data for context (create or edit)
* @param int $participantIndex The index of the participant being configured
* @param array<string, mixed> $options Additional options to customize field behavior
*
* @return array<string, mixed> Symfony form field options, or empty array if field not supported
*/
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Form\Service\Contract;
use App\Form\Model\BookingDto;
use Symfony\Component\Form\FormInterface;
/**
* Interface for providing dynamic field state based on conditions.
@@ -30,6 +31,15 @@ use App\Form\Model\BookingDto;
*/
interface FieldStateProviderInterface
{
/**
* Gets the BookingDto from the root of the form tree.
*
* @param FormInterface<mixed> $form The form to start traversing from
*
* @return BookingDto|null The booking DTO or null if not found
*/
public function getBookingDtoFromForm(FormInterface $form): ?BookingDto;
/**
* Determines whether a field should be included in the form at all.
*
@@ -131,6 +131,10 @@ class ParticipantAdditionalServicesFieldHandler extends AbstractParticipantField
$participant->additionalServices = $validSelections;
}
/**
* @param array<int, Service> $availableServices
* @param list<Service> $validSelections
*/
private function updateAutoBookOptOutServices(
ParticipantDto $participant,
array $availableServices,
@@ -140,10 +144,6 @@ class ParticipantAdditionalServicesFieldHandler extends AbstractParticipantField
): void {
$currentlySelectedAutoBookIds = [];
foreach ($participant->additionalServices as $selectedService) {
if (false === $selectedService instanceof Service) {
continue;
}
if (null === $selectedService->id || true === $selectedService->mandatory || false === $selectedService->autoBook) {
continue;
}
@@ -186,12 +186,12 @@ class ParticipantAdditionalServicesFieldHandler extends AbstractParticipantField
* and the participant's age constraints. Services that are no longer available
* or appropriate for the participant's age are filtered out.
*
* @param array $selectedServices List of currently selected services
* @param array $availableServices List of all available additional services
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
* @param list<mixed> $selectedServices List of currently selected services
* @param array<int, Service> $availableServices List of all available additional services
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
*
* @return array Filtered array of valid service selections
* @return list<Service> Filtered array of valid service selections
*/
private function filterValidServiceSelections(
array $selectedServices,
@@ -220,10 +220,10 @@ class ParticipantAdditionalServicesFieldHandler extends AbstractParticipantField
* This method checks if a selected service exists in the available services
* and meets the age constraints for the current participant.
*
* @param mixed $selectedService The selected service to validate
* @param array $availableServices Array of available services
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
* @param mixed $selectedService The selected service to validate
* @param array<int, Service> $availableServices Array of available services
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
*
* @return bool True if the service is valid for the participant, false otherwise
*/
@@ -89,6 +89,10 @@ class ParticipantBoardFieldHandler extends AbstractParticipantFieldHandler
$participant->board = $validSelections;
}
/**
* @param array<int, Service> $availableBoard
* @param list<Service> $validSelections
*/
private function updateAutoBookOptOutBoard(
ParticipantDto $participant,
array $availableBoard,
@@ -98,10 +102,6 @@ class ParticipantBoardFieldHandler extends AbstractParticipantFieldHandler
): void {
$currentlySelectedAutoBookIds = [];
foreach ($participant->board as $selectedService) {
if (false === $selectedService instanceof Service) {
continue;
}
if (null === $selectedService->id || true === $selectedService->mandatory || false === $selectedService->autoBook) {
continue;
}
@@ -135,6 +135,12 @@ class ParticipantBoardFieldHandler extends AbstractParticipantFieldHandler
));
}
/**
* @param list<mixed> $selectedServices
* @param array<int, Service> $availableServices
*
* @return list<Service>
*/
private function filterValidServiceSelections(
array $selectedServices,
array $availableServices,
@@ -156,6 +162,9 @@ class ParticipantBoardFieldHandler extends AbstractParticipantFieldHandler
return $validSelections;
}
/**
* @param array<int, Service> $availableServices
*/
private function isServiceValidForParticipant(
mixed $selectedService,
array $availableServices,
@@ -114,12 +114,12 @@ class ParticipantCoursesFieldHandler extends AbstractParticipantFieldHandler
/**
* Filters course selections to keep only those valid for the participant's age.
*
* @param array $selectedServices List of currently selected courses
* @param array $availableServices List of all available courses
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
* @param list<mixed> $selectedServices List of currently selected courses
* @param array<int, Service> $availableServices List of all available courses
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
*
* @return array Filtered array of valid course selections
* @return list<Service> Filtered array of valid course selections
*/
private function filterValidServiceSelections(
array $selectedServices,
@@ -145,10 +145,10 @@ class ParticipantCoursesFieldHandler extends AbstractParticipantFieldHandler
/**
* Validates if a selected course is still valid for the participant.
*
* @param mixed $selectedService The selected course to validate
* @param array $availableServices Array of available courses
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
* @param mixed $selectedService The selected course to validate
* @param array<int, Service> $availableServices Array of available courses
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
*
* @return bool True if the course is valid for the participant, false otherwise
*/
@@ -100,9 +100,9 @@ class ParticipantDateOfBirthFieldHandler extends AbstractParticipantFieldHandler
if (true === is_array($value)) {
// Check if all required fields are present and valid
if (false === isset($value['year'], $value['month'], $value['day'])
|| '' === trim((string) ($value['year'] ?? ''))
|| '' === trim((string) ($value['month'] ?? ''))
|| '' === trim((string) ($value['day'] ?? ''))
|| '' === trim((string) $value['year'])
|| '' === trim((string) $value['month'])
|| '' === trim((string) $value['day'])
) {
return null;
}
@@ -511,7 +511,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
return [
'label' => 'Hinfahrt',
'choices' => $choices,
'choice_label' => fn (Service $service) => $service?->label,
'choice_label' => fn (Service $service) => $service->label,
'choice_value' => 'id',
'expanded' => true,
'multiple' => false,
@@ -551,7 +551,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
return [
'label' => 'Rückfahrt',
'choices' => $choices,
'choice_label' => fn (Service $service) => $service?->label,
'choice_label' => fn (Service $service) => $service->label,
'choice_value' => 'id',
'expanded' => true,
'multiple' => false,
@@ -622,7 +622,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
$hasOutboundBus = null !== $participant?->transportationOutbound
&& DirectionMapper::SUBTYPE_BUS_API === $participant->transportationOutbound->subType;
if ($hasOutboundBus && false === ($participant->differentDropOff ?? false)) {
if ($hasOutboundBus && false === $participant->differentDropOff) {
return [];
}
@@ -806,11 +806,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
* as the participant's selected skipass. This ensures rental equipment
* is only available for the exact duration of the skipass.
*
* @param array $rentals Array of rental Service objects to filter
* @param BookingDto $bookingDto The booking DTO containing participant data
* @param int $participantIndex Index of the participant to evaluate
* @param array<int, Service> $rentals Array of rental Service objects to filter
* @param BookingDto $bookingDto The booking DTO containing participant data
* @param int $participantIndex Index of the participant to evaluate
*
* @return array Filtered array of rentals matching skipass duration
* @return array<int, Service> Filtered array of rentals matching skipass duration
*/
private function filterRentalsBySkiPassDuration(array $rentals, BookingDto $bookingDto, int $participantIndex): array
{
@@ -914,8 +914,8 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
/**
* Checks if a service array contains a service with the given ID.
*
* @param array $services Array of Service objects
* @param int $serviceId Service ID to search for
* @param array<int, Service> $services Array of Service objects
* @param int $serviceId Service ID to search for
*
* @return bool True if the service is found in the array
*/
@@ -937,11 +937,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
* If no age evaluator is configured or participant has no birth date,
* returns empty array to be handled by field visibility conditions.
*
* @param array $services Array of Service objects to filter
* @param BookingDto $bookingDto The booking DTO containing participant data
* @param int $participantIndex Index of the participant to evaluate
* @param array<int, Service> $services Array of Service objects to filter
* @param BookingDto $bookingDto The booking DTO containing participant data
* @param int $participantIndex Index of the participant to evaluate
*
* @return array Filtered array of available services
* @return array<int, Service> Filtered array of available services
*/
private function filterServicesByAgeConstraints(array $services, BookingDto $bookingDto, int $participantIndex): array
{
@@ -1112,6 +1112,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
/**
* Gets the rental insurance description for help text.
*/
/** @param list<Service> $rentalInsuranceManagers */
private function getRentalInsuranceDescription(array $rentalInsuranceManagers): ?string
{
if (empty($rentalInsuranceManagers)) {
@@ -1131,7 +1132,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
* @param BookingDto $bookingDto The booking DTO containing travel and participant data
* @param int $participantIndex The index of the participant to get eligible insurances for
*
* @return array Array of eligible insurance objects filtered by age, family status, and other constraints
* @return list<Insurance> Array of eligible insurance objects filtered by age, family status, and other constraints
*/
private function getEligibleInsurances(BookingDto $bookingDto, int $participantIndex): array
{
@@ -1180,11 +1181,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
* got the discount to change their mind (e.g., select bus instead), making the discount available
* for others in the same booking session.
*
* @param array $services Transportation services from Travel model
* @param BookingDto $bookingDto Current booking DTO with participant selections
* @param int $participantIndex Current participant being processed
* @param array<int, Service> $services Transportation services from Travel model
* @param BookingDto $bookingDto Current booking DTO with participant selections
* @param int $participantIndex Current participant being processed
*
* @return array Filtered transportation choices with smart PKW option selection
* @return array<int, Service> Filtered transportation choices with smart PKW option selection
*/
private function filterTransportationChoices(array $services, BookingDto $bookingDto, int $participantIndex): array
{
@@ -128,6 +128,10 @@ class ParticipantRentalsFieldHandler extends AbstractParticipantFieldHandler
$participant->rentals = $validSelections;
}
/**
* @param array<int, Service> $availableRentals
* @param list<Service> $validSelections
*/
private function updateAutoBookOptOutRentals(
ParticipantDto $participant,
array $availableRentals,
@@ -137,10 +141,6 @@ class ParticipantRentalsFieldHandler extends AbstractParticipantFieldHandler
): void {
$currentlySelectedAutoBookIds = [];
foreach ($participant->rentals as $selectedService) {
if (false === $selectedService instanceof Service) {
continue;
}
if (null === $selectedService->id || true === $selectedService->mandatory || false === $selectedService->autoBook) {
continue;
}
@@ -174,6 +174,12 @@ class ParticipantRentalsFieldHandler extends AbstractParticipantFieldHandler
));
}
/**
* @param list<mixed> $selectedServices
* @param array<int, Service> $availableServices
*
* @return list<Service>
*/
private function filterValidServiceSelections(
array $selectedServices,
array $availableServices,
@@ -195,6 +201,9 @@ class ParticipantRentalsFieldHandler extends AbstractParticipantFieldHandler
return $validSelections;
}
/**
* @param array<int, Service> $availableServices
*/
private function isServiceValidForParticipant(
mixed $selectedService,
array $availableServices,
@@ -222,12 +231,12 @@ class ParticipantRentalsFieldHandler extends AbstractParticipantFieldHandler
* - rental.dateFrom === skipass.dateFrom
* - rental.dateTo === skipass.dateTo
*
* @param array $rentals All available rental services
* @param ParticipantDto $participant The participant with skipass selection
* @param array<int, Service> $rentals All available rental services
* @param ParticipantDto $participant The participant with skipass selection
*
* @return array Filtered rentals matching the skipass duration
* @return array<int, Service> Filtered rentals matching the skipass duration
*/
private function filterRentalsBySkiPassDuration(array $rentals, $participant): array
private function filterRentalsBySkiPassDuration(array $rentals, ParticipantDto $participant): array
{
$selectedSkiPass = $participant->skiPass;
@@ -129,6 +129,7 @@ class ParticipantSkiPassFieldHandler extends AbstractParticipantFieldHandler
$participant->skiPass = $validSelection;
}
/** @param array<int, Service> $availableSkipasses */
private function getSelectedAutoBookSkiPassId(
ParticipantDto $participant,
array $availableSkipasses,
@@ -184,10 +185,10 @@ class ParticipantSkiPassFieldHandler extends AbstractParticipantFieldHandler
* This method checks both age constraints (via birth year ranges) and
* date constraints (skipass dates must be within travel dates).
*
* @param mixed $selectedService The selected skipass to validate
* @param array $availableServices Array of available skipasses
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
* @param mixed $selectedService The selected skipass to validate
* @param array<int, Service> $availableServices Array of available skipasses
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
*
* @return bool True if the skipass is valid for the participant, false otherwise
*/
@@ -107,10 +107,10 @@ class ParticipantVegFieldHandler extends AbstractParticipantFieldHandler
*
* This method checks age constraints if they exist for the service.
*
* @param mixed $selectedService The selected veg option to validate
* @param array $availableServices Array of available veg options
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
* @param mixed $selectedService The selected veg option to validate
* @param array<int, Service> $availableServices Array of available veg options
* @param BookingDto $bookingDto The booking DTO for context
* @param int $participantIndex The participant index for age evaluation
*
* @return bool True if the option is valid for the participant, false otherwise
*/
@@ -26,7 +26,7 @@ trait FormTraversalTrait
* and extracts the BookingDto data. This is used as a fallback when
* BookingDto is not passed explicitly via form options.
*
* @param FormInterface $form The form to start traversing from
* @param FormInterface<mixed> $form The form to start traversing from
*
* @return BookingDto|null The booking DTO or null if not found
*/