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

+26
View File
@@ -7,6 +7,7 @@ use App\BusProNet\Exception\ApiClientException;
use App\BusProNet\Exception\ImmediateConnectionCloseException;
use App\BusProNet\Exception\ResponseParserException;
use App\BusProNet\Exception\TimeoutException;
use App\BusProNet\Model\Agency;
use App\BusProNet\Model\BaseData;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\BookingResponse;
@@ -49,11 +50,13 @@ class ApiClient
public const TYPE_PURCHASE_VOUCHER = 'GUTSCHEINPRUEFUNGEINLOESUNG';
public const TYPE_PROMO_VOUCHER = 'AKTIONSGUTSCHEIN';
/** @var array<string, mixed> */
private array $config;
private float $operationStartTime;
private int $selectedPort;
private int $requestCounter = 0;
/** @param array<string, mixed> $options */
public function __construct(
private readonly SerializerInterface $serializer,
private readonly ApiResponseParser $responseParser,
@@ -613,6 +616,10 @@ class ApiClient
/**
* @throws ApiClientException
*/
/**
* @param array<string, mixed> $data
* @param array<string, mixed> $additionalArgs
*/
private function sendRequest(string $type, array $data, array $additionalArgs = [], bool $debug = false): mixed
{
return $this->executeWithRetry(fn () => $this->doSendRequest($type, $data, $additionalArgs, $debug), $type);
@@ -621,6 +628,7 @@ class ApiClient
/**
* @throws ApiClientException
*/
/** @param array<string, mixed> $data */
private function sendRequestRaw(array $data): string
{
return $this->executeWithRetry(fn () => $this->doSendRequestRaw($data));
@@ -676,6 +684,10 @@ class ApiClient
* @throws ApiClientException
* @throws ImmediateConnectionCloseException
*/
/**
* @param array<string, mixed> $data
* @param array<string, mixed> $additionalArgs
*/
private function doSendRequest(string $type, array $data, array $additionalArgs = [], bool $debug = false): mixed
{
$requestId = $this->getRequestId();
@@ -733,6 +745,8 @@ class ApiClient
}
/**
* @param array<string, mixed> $data
*
* @throws ApiClientException
* @throws ImmediateConnectionCloseException
*/
@@ -794,6 +808,8 @@ class ApiClient
}
/**
* @return resource
*
* @throws ApiClientException
* @throws TimeoutException
*/
@@ -857,6 +873,8 @@ class ApiClient
}
/**
* @param resource $socket
*
* @throws TimeoutException
*/
private function send($socket, string $data): void
@@ -875,6 +893,8 @@ class ApiClient
}
/**
* @param resource $socket
*
* @throws TimeoutException
* @throws ImmediateConnectionCloseException
*/
@@ -937,11 +957,17 @@ class ApiClient
return $response;
}
/** @param resource $socket */
private function disconnect($socket): void
{
@fclose($socket);
}
/**
* @param array<string, mixed> $options
*
* @return array<string, mixed>
*/
private function resolveOptions(array $options): array
{
$optionsResolver = new OptionsResolver();
@@ -73,14 +73,12 @@ class BookingDataProcessor
if (0 === $index) {
// Copy address if first participant has no street (indicating empty/incomplete address)
// This allows applicant and first participant to be different people with different addresses
if (null !== $booking->applicant->address) {
$isEmpty = null === $participantData->address
|| null === $participantData->address->street
|| '' === trim($participantData->address->street);
$isEmpty = null === $participantData->address
|| null === $participantData->address->street
|| '' === trim($participantData->address->street);
if ($isEmpty) {
$participantData->address = clone $booking->applicant->address;
}
if ($isEmpty) {
$participantData->address = clone $booking->applicant->address;
}
// Copy body dimensions from applicant if not present in participant
@@ -284,7 +282,7 @@ class BookingDataProcessor
*
* @param BookingDto|null $formData The booking edit form data containing updated participant and service selections
*
* @return array The structured payload array ready for BusProNet API submission
* @return array<string, mixed> The structured payload array ready for BusProNet API submission
*/
public function createUpdateRequestPayload(?BookingDto $formData): array
{
@@ -345,7 +343,7 @@ class BookingDataProcessor
* @param BookingDto $bookingDto The booking creation form data
* @param string $bookingType Either 'Anfrage' (inquiry) or 'Buchung' (final booking)
*
* @return array The structured payload array for BusProNet API submission
* @return array<string, mixed> The structured payload array for BusProNet API submission
*/
public function createBookingRequestPayload(BookingDto $bookingDto, string $bookingType): array
{
@@ -7,6 +7,7 @@ namespace App\BusProNet\DataProcessor;
use App\BusProNet\Constants;
use App\BusProNet\Model\Booking;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
/**
* Builds API payload structures for BusProNet booking requests.
@@ -30,7 +31,7 @@ class BookingPayloadBuilder
*
* @param Booking $bookingData The booking data object
*
* @return array The base payload structure
* @return array<string, mixed> The base payload structure
*/
public function buildBasePayload(Booking $bookingData): array
{
@@ -66,8 +67,8 @@ class BookingPayloadBuilder
*
* Bank account information is required for direct debit payments.
*
* @param array $payload The payload array to modify
* @param Booking $bookingData The booking data object
* @param array<string, mixed> $payload The payload array to modify
* @param Booking $bookingData The booking data object
*/
public function addBankAccountToPayload(array &$payload, Booking $bookingData): void
{
@@ -86,9 +87,9 @@ class BookingPayloadBuilder
*
* Includes status, personal data, and wishes (room remarks, license plate) for each participant.
*
* @param array $payload The payload array to modify
* @param Booking $bookingData The booking data object
* @param array $participantDtos The participant DTOs from the form (for wishes data)
* @param array<string, mixed> $payload The payload array to modify
* @param Booking $bookingData The booking data object
* @param array<int, ParticipantDto> $participantDtos The participant DTOs from the form (for wishes data)
*/
public function buildParticipantPayload(array &$payload, Booking $bookingData, array $participantDtos): void
{
@@ -141,8 +142,8 @@ class BookingPayloadBuilder
* Includes additional services, transportation services, and accommodation details
* with participant mappings and quantities.
*
* @param array $payload The payload array to modify
* @param Booking $bookingData The booking data object
* @param array<string, mixed> $payload The payload array to modify
* @param Booking $bookingData The booking data object
*/
public function buildServicesPayload(array &$payload, Booking $bookingData): void
{
@@ -198,8 +199,8 @@ class BookingPayloadBuilder
*
* Only included in payload if there are actual pickup assignments for bus transportation.
*
* @param array $payload The payload array to modify
* @param Booking $bookingData The booking data object
* @param array<string, mixed> $payload The payload array to modify
* @param Booking $bookingData The booking data object
*/
public function buildPickupPayload(array &$payload, Booking $bookingData): void
{
@@ -223,8 +224,8 @@ class BookingPayloadBuilder
*
* Only included in payload if there are actual drop-off assignments for bus transportation.
*
* @param array $payload The payload array to modify
* @param Booking $bookingData The booking data object
* @param array<string, mixed> $payload The payload array to modify
* @param Booking $bookingData The booking data object
*/
public function buildDropOffPayload(array &$payload, Booking $bookingData): void
{
@@ -249,7 +250,7 @@ class BookingPayloadBuilder
* @param BookingDto $bookingDto The booking creation form data
* @param string $bookingType Either 'Anfrage' (inquiry) or 'Buchung' (final booking)
*
* @return array The structured payload array for BusProNet API submission
* @return array<string, mixed> The structured payload array for BusProNet API submission
*/
public function buildCreatePayload(BookingDto $bookingDto, string $bookingType): array
{
@@ -439,11 +440,11 @@ class BookingPayloadBuilder
* Generic helper method that converts service ID => participant IDs mappings
* into XML payload structure.
*
* @param array $payload The payload array to modify
* @param string $sectionKey The section key (e.g., 'beförderungen', 'versicherungen')
* @param string $itemKey The item key (e.g., 'beförderung', 'versicherung')
* @param string $idAttributeName The ID attribute name (e.g., '@idleistung', '@idversicherung')
* @param array $serviceMap Map of service ID to participant IDs
* @param array<string, mixed> $payload The payload array to modify
* @param string $sectionKey The section key (e.g., 'beförderungen', 'versicherungen')
* @param string $itemKey The item key (e.g., 'beförderung', 'versicherung')
* @param string $idAttributeName The ID attribute name (e.g., '@idleistung', '@idversicherung')
* @param array<int|string, int[]> $serviceMap Map of service ID to participant IDs
*/
public function addServicesFromMap(
array &$payload,
@@ -475,9 +476,9 @@ class BookingPayloadBuilder
* - abreise (departure date)
* - anzahl (number of rooms of this type booked)
*
* @param array $payload The payload array to modify
* @param array $roomMap Map of room ID to participant IDs
* @param BookingDto $bookingDto The booking data for accessing room details and quantities
* @param array<string, mixed> $payload The payload array to modify
* @param array<int|string, int[]> $roomMap Map of room ID to participant IDs
* @param BookingDto $bookingDto The booking data for accessing room details and quantities
*/
public function addRoomMappingsToPayload(array &$payload, array $roomMap, BookingDto $bookingDto): void
{
@@ -520,8 +521,8 @@ class BookingPayloadBuilder
/**
* Adds purchase vouchers to the payload.
*
* @param array $payload The payload array to modify
* @param BookingDto $bookingDto The booking data
* @param array<string, mixed> $payload The payload array to modify
* @param BookingDto $bookingDto The booking data
*/
public function addPurchaseVouchersToPayload(array &$payload, BookingDto $bookingDto): void
{
@@ -6,7 +6,6 @@ namespace App\BusProNet\DataProcessor;
use App\BusProNet\Model\Address;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\Communication;
use App\BusProNet\Model\PersonalData;
use App\Form\Model\ParticipantDto;
@@ -86,9 +85,6 @@ class PersonalDataSynchronizer
}
if ($participant->email || $participant->mobile) {
if (null === $bookingData->participants[$participant->index]->communication) {
$bookingData->participants[$participant->index]->communication = new Communication();
}
$bookingData->participants[$participant->index]->communication->email = $participant->email;
$bookingData->participants[$participant->index]->communication->mobile = $participant->mobile;
}
@@ -127,10 +123,6 @@ class PersonalDataSynchronizer
$applicant->dateOfBirth = new \DateTimeImmutable('-20 years');
}
if (null === $applicant->communication) {
$applicant->communication = new Communication();
}
if (null === $applicant->communication->mobile || '' === $applicant->communication->mobile) {
$applicant->communication->mobile = '12345';
}
@@ -20,7 +20,7 @@ class ServiceMappingCollector
*
* Groups participants by their assigned room ID.
*
* @return array<string, array<int>> Map of room ID to participant IDs
* @return array<int, list<int>> Map of room ID to participant IDs
*/
public function collectRoomMappings(BookingDto $bookingDto): array
{
@@ -14,6 +14,7 @@ class CountryDataProvider
{
}
/** @return array<string, Country> */
public function getAll(): array
{
try {
+1
View File
@@ -10,6 +10,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
/** @extends AbstractType<string> */
class CountryType extends AbstractType
{
public function __construct(private readonly CountryDataProvider $countries)
@@ -12,6 +12,7 @@ namespace App\BusProNet\Model;
*/
class AgeConstraintResult
{
/** @param array<string, mixed> $metadata */
public function __construct(
public readonly string $type,
public readonly ?int $ageFrom = null,
+2 -1
View File
@@ -12,6 +12,7 @@ namespace App\BusProNet\Model;
*/
class BaseData
{
/** @param array<array-key, mixed> $items */
public function __construct(private readonly array $items)
{
}
@@ -19,7 +20,7 @@ class BaseData
/**
* Retrieves all items in the base data collection.
*
* @return array The complete items array
* @return array<array-key, mixed> The complete items array
*/
public function getItems(): array
{
+1 -1
View File
@@ -220,7 +220,7 @@ class Booking
public function getInsuranceForParticipant(int $participantIndex): ?Insurance
{
foreach ($this->insurances as $insurance) {
if (in_array($participantIndex, $insurance->mapping ?? [], true)) {
if (in_array($participantIndex, $insurance->mapping, true)) {
return $insurance;
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ class CrmSelectionGroup
* Maps BusPro IDs of CRM selection groups representing
* included services.
*
* @var array<string, string>
* @var array<int, string>
*/
public static array $includedServicesMapping = [
7 => 'Skipass',
-115
View File
@@ -1,115 +0,0 @@
<?php
declare(strict_types=1);
namespace App\BusProNet\Model;
/**
* Represents error codes and messages for the BusProNet API.
*
* This class provides a static mapping of error codes to their corresponding
* German error messages for consistent error handling across the application.
* Error codes range from 100-999 and cover various API scenarios.
*/
class Error
{
/**
* @var array<int, string>
*/
private static array $errors = [
100 => 'Anfrageknoten fehlt',
101 => 'Satzknoten fehlt in Anfrageknoten',
102 => 'Ungültiger Satztyp [#1#]',
103 => 'User fehlt',
104 => 'User fehlerhaft',
105 => 'Key fehlt',
106 => 'Key fehlerhaft',
200 => 'Keine Einträge vorhanden',
201 => 'Keine Partner zur Auswahl gefunden',
202 => 'Keinen Partner mit der ID [#1#] gefunden',
203 => 'Ungültiger Termin',
300 => 'IDReise fehlt',
301 => 'Reise nicht gefunden',
302 => 'IDLeistung (Hin & Rück) fehlt',
303 => 'IDLeistung passt nicht zu IDReise',
304 => 'Es konnte nicht für alle Teilnehmer ein Sitzplatz ermittelt werden',
305 => 'Anzahl Personen fehlt',
306 => 'Leistungen mit ID #1# nicht gefunden',
307 => 'Leistungen mit ID #1# passen nicht zur Reise mit ID #2#',
308 => 'Keine Zahlungsarten gefunden',
400 => 'IDPartner fehlt',
401 => 'Partner nicht gefunden',
402 => 'Bis-Termin fehlt',
403 => 'Keine Unterbringungsleistungen gefunden',
500 => 'Art fehlt',
501 => 'Reise- und Buchungszeitraum fehlen',
502 => 'Keine Kunden gefunden',
600 => 'Keine Gutscheine gefunden',
601 => 'Gutschein-IDs fehlen',
602 => 'Gutscheine mit ID #1# nicht gefunden',
610 => 'Buchungsart fehlt',
611 => 'Buchungsart falsch',
612 => 'Gutscheinart fehlt',
613 => 'Gutscheinart falsch',
614 => 'Gutscheinstamm-ID fehlt',
615 => 'Gutschein (Stamm) mit ID #1# nicht gefunden',
616 => 'Kapazität beim Gutschein #1# nicht ausreichend',
617 => 'Rechnungsempfänger fehlt',
618 => 'Zahlungsart fehlt',
619 => 'Agentur-ID fehlt',
620 => 'Agentur mit ID #1# nicht gefunden',
650 => '#1#',
700 => 'Keine Agenturen gefunden',
701 => 'Agentur mit ID #1# nicht gefunden',
800 => 'Produkt-ID fehlt',
801 => 'Produkt mit ID #1# nicht gefunden',
805 => 'Es wurden keine Produkte gefunden',
810 => 'Stammdaten (#1#) nicht gefunden',
900 => 'Buchungsart fehlt',
901 => 'Buchungsart falsch',
902 => 'Status fehlt',
903 => 'Status falsch',
904 => 'Agentur-ID fehlt',
905 => 'Agentur mit ID #1# nicht gefunden',
906 => 'Reise-ID fehlt',
907 => 'Reise mit ID #1# nicht gefunden',
908 => 'Reise mit ID #1# ist storniert',
909 => 'Beförderungen fehlen',
910 => 'Leistung mit ID #1# gehört nicht zur Reise',
911 => 'Leistung mit ID #1# gehört nicht zum Produkt',
912 => 'Beförderungsleistung für die #1# fehlt',
913 => 'Unterbringungen fehlen',
914 => 'Partner-ID fehlt',
915 => 'Partner mit ID #1# nicht gefunden',
916 => 'Ferienziel-Unterbringungen fehlen',
917 => 'Ferienziel: Zimmer-IDZ fehlt',
918 => 'Ferienziel: Kategorie fehlt',
919 => 'Ferienziel: Verpflegungs-ID fehlt',
920 => 'Ferienziel: Anreise fehlt',
921 => 'Ferienziel: Anreise passt nicht zur Beförderungsleistung (Hinfahrt)',
922 => 'Ferienziel: Abreise fehlt',
923 => 'Ferienziel: Abreise passt nicht zur Beförderungsleistung (Rückfahrt)',
924 => 'Ferienziel: Keine Preise zu den Daten gefunden',
925 => 'Ferienziel: Preis zu den Daten nicht gefunden',
930 => 'Zustiege fehlen',
931 => 'Zustieg mit ID #1# nicht gefunden',
932 => 'Zustieg mit ID #1# bei Leistung #2# nicht freigegeben',
933 => 'Sitzplan mit ID #1# bei Leistung #2# nicht freigegeben',
935 => 'Versicherung mit ID #1# nicht gefunden',
940 => 'Zahlungsart fehlt',
941 => 'Zahlungsart-ID fehlt',
942 => 'Zahlungsart mit ID #1# nicht gültig',
950 => 'Anmelder fehlt',
951 => 'Teilnehmerliste fehlt',
952 => 'Teilnehmer-ID fehlt',
960 => 'Preisfehler: Struct #1# / Obj #2#',
961 => 'Buchung konnte nicht gespeichert werden',
980 => 'Reise ist fürs Internet gesperrt',
981 => 'Reise ist nicht mehr buchbar (#1#)',
982 => 'Optionsbuchungen nicht zugelassen',
983 => 'Anfragebuchung nicht zugelassen',
984 => 'Leistung mit ID #1# nicht fürs Internet buchbar',
985 => 'Zustieg mit ID #1# nicht fürs Internet buchbar',
999 => 'Systemfehler: #1#',
];
}
+2
View File
@@ -56,7 +56,9 @@ class PersonalData
#[Assert\Valid(groups: ['personal_data'])]
public Communication $communication;
/** @var list<string> */
public array $roles = [];
/** @var list<string> */
public array $hotelCodes = [];
public function __construct()
+1
View File
@@ -45,6 +45,7 @@ class Pickup
#[Groups(['api:single', 'snapshot'])]
public ?float $priceInbound = null;
/** @var list<int> */
#[Groups(['api:booking'])]
public array $mapping = [];
+2
View File
@@ -64,6 +64,7 @@ class Room
#[Groups(['booking'])]
public ?string $board = null;
/** @var list<int> */
#[Groups(['booking'])]
public array $mapping = [];
@@ -73,6 +74,7 @@ class Room
#[Groups(['booking'])]
public ?float $totalPrice = null;
/** @var array<int, float|null> */
#[Groups(['booking'])]
public array $individualPrice = [];
+3
View File
@@ -55,6 +55,7 @@ class Service
#[Groups(['booking'])]
public ?int $totalCount = null;
/** @var list<int> */
#[Groups(['api:single', 'snapshot'])]
public array $mapping = [];
@@ -64,6 +65,7 @@ class Service
#[Groups(['api:single', 'snapshot'])]
public ?float $totalPrice = null;
/** @var array<int, float|null> */
#[Groups(['api:single', 'snapshot'])]
public array $individualPrice = [];
@@ -91,6 +93,7 @@ class Service
#[Groups(['api:single', 'api:list', 'snapshot'])]
public ?string $ageConstraintType = null;
/** @var array<string, mixed>|null */
#[Groups(['api:single'])]
public ?array $ageConstraintMetadata = null;
+2
View File
@@ -13,7 +13,9 @@ namespace App\BusProNet\Model;
class Surcharge
{
public ?string $label = null;
/** @var list<int> */
public array $mapping = [];
public ?float $totalPrice = null;
/** @var array<int, float|null> */
public array $individualPrice = [];
}
+1 -1
View File
@@ -203,7 +203,7 @@ class Travel
* Maps selection group IDs to their corresponding services based on
* the predefined included services mapping.
*
* @return array<int, Service> The included services from selection groups
* @return array<int, CrmSelectionGroup> The included services from selection groups
*/
public function getIncludedServices(): array
{
@@ -47,7 +47,7 @@ class ChaperonServiceStatusRule implements BookingStatusRuleInterface
foreach ($arrayServices as $services) {
foreach ($services as $service) {
if ($service instanceof Service && true === $this->containsSearchTerm($service->label)) {
if (true === $this->containsSearchTerm($service->label)) {
return true;
}
}
+2 -2
View File
@@ -28,9 +28,9 @@ trait SortByPriceTrait
* collections in the application. Items are sorted from lowest to highest price,
* with null prices being treated as zero (appearing first).
*
* @param array $items Array of objects with a price property to sort
* @param array<array-key, object> $items Array of objects with a price property to sort
*
* @return array The sorted array of objects (ascending by price)
* @return array<array-key, object> The sorted array of objects (ascending by price)
*/
protected function sortByPrice(array $items): array
{
@@ -7,6 +7,7 @@ use Carbon\Exceptions\InvalidFormatException;
trait TypeConversionTrait
{
/** @return list<string> */
protected function stringToArray(?string $string, string $separator = ','): array
{
if (true === empty($string)) {
+1
View File
@@ -11,6 +11,7 @@ use Symfony\Contracts\Cache\ItemInterface;
class HotelLoader extends AbstractLoader
{
/** @return array<int, Hotel> */
public function loadAll(?string $filename = 'hotel.xml'): array
{
try {
@@ -22,6 +22,7 @@ class InsuranceLoader extends AbstractLoader
parent::__construct($cache, $xmlExport);
}
/** @return array<string|int, Insurance> */
public function loadAll(?string $filename = 'versicherungen.xml'): array
{
try {
+6
View File
@@ -10,6 +10,7 @@ use Symfony\Contracts\Cache\ItemInterface;
class PickupLoader extends AbstractLoader
{
/** @return array<int|string, Pickup> */
public function loadAll(?string $filename = 'zustiege.xml'): array
{
try {
@@ -65,6 +66,11 @@ class PickupLoader extends AbstractLoader
$travel->dropOffs = $this->patchAndOrderDropOffs($travel->dropOffs, $travel->pickups);
}
/**
* @param array<int, Pickup> $pickups
*
* @return array<int, Pickup>
*/
private function patchAndSortPickups(array $pickups): array
{
$this->enrichPickupDetails($pickups);
+3 -2
View File
@@ -51,7 +51,7 @@ class TravelLoader extends AbstractLoader
* including ID, code, label, dates, and associated hotels. The mapping is
* cached for 3 hours to improve performance.
*
* @return array<int, array> Mapping of travel IDs to their metadata and file paths
* @return array<int, array<string, mixed>> Mapping of travel IDs to their metadata and file paths
*/
public function generateFilesMap(): array
{
@@ -74,7 +74,7 @@ class TravelLoader extends AbstractLoader
$travelDataNodes = $crawler->filterXPath('//reisen/reise/termin');
$travelDataNodes->each(function (Crawler $node) use (&$mapping, $hotels, $file) {
$travelId = $node->attr('idbuspro');
$travelId = (int) $node->attr('idbuspro');
$mapping[$travelId] = [
'id' => $travelId,
@@ -173,6 +173,7 @@ class TravelLoader extends AbstractLoader
*
* @throws TravelNotFoundException When travel ID is not found
* @throws HotelNotInTravelException When hotel ID exists but not for this travel
* @throws \RuntimeException When cached mapping generation fails unexpectedly
*/
public function loadById(int $dateId, ?int $hotelId = null, ?string $filename = null): Travel
{
@@ -39,6 +39,7 @@ abstract class AbstractParser
return 0 < $node->count() && $this->stringToBool($node->text());
}
/** @return list<string> */
protected function getArrayValue(Crawler $node, string $separator = ','): array
{
if (0 === $node->count()) {
@@ -53,6 +53,7 @@ class AgeConstraintParserRegistry
return $this->mergeConstraintResults($results, $constraintData);
}
/** @param list<AgeConstraintResult> $results */
private function mergeConstraintResults(array $results, string $rawData): AgeConstraintResult
{
if (empty($results)) {
@@ -11,6 +11,7 @@ class ApiResponseParser extends AbstractParser
/**
* @throws ResponseParserException
*/
/** @param array<string, mixed> $additionalArgs */
public function parseXmlString(string $type, string $xml, array $additionalArgs = []): mixed
{
$crawler = new Crawler($xml);
@@ -15,6 +15,7 @@ use Symfony\Component\DomCrawler\Crawler;
*/
class BookingInsurancesParser extends AbstractParser
{
/** @return array<string, Insurance> */
public function parse(Crawler $result): array
{
$insurances = [];
@@ -112,6 +112,7 @@ class BookingParser extends AbstractParser
return $booking;
}
/** @return array<int, PersonalData> */
private function parseParticipants(Crawler $node): array
{
$participants = [];
@@ -27,7 +27,7 @@ class CrmAttributesResponseParser
$result
->filterXPath('//selektionsmerkmale/selektionsgruppe')
->each(function (Crawler $node) use (&$groups, &$roles, &$hotelCode) {
->each(function (Crawler $node) use (&$groups, &$roles) {
$group = new CrmSelectionGroup();
$group->id = (int) $node->attr('id');
$group->label = $node->attr('bezeichnung');
@@ -47,14 +47,14 @@ class CrmAttributesResponseParser
$roles[] = 'ROLE_HOUSE_MANAGER';
$hotelCodes[] = $matches[1];
}
if (static::BPN_CRM_ID_ADMIN === $attribute->id && true === $attribute->selected) {
if (self::BPN_CRM_ID_ADMIN === $attribute->id && true === $attribute->selected) {
$roles[] = 'ROLE_ADMIN';
$roles[] = 'ROLE_HOUSE_MANAGER';
}
if (static::BPN_CRM_ID_MANAGER === $attribute->id && true === $attribute->selected) {
if (self::BPN_CRM_ID_MANAGER === $attribute->id && true === $attribute->selected) {
$roles[] = 'ROLE_MANAGER';
}
if (static::BPN_CRM_ID_TEAMER === $attribute->id && true === $attribute->selected) {
if (self::BPN_CRM_ID_TEAMER === $attribute->id && true === $attribute->selected) {
$roles[] = 'ROLE_TEAMER';
}
@@ -90,7 +90,7 @@ class CrmAttributesResponseParser
;
if (true === in_array('ROLE_ADMIN', $roles, true)) {
$hotelCodes[] = static::BPN_DEFAULT_HOTEL_CODE;
$hotelCodes[] = self::BPN_DEFAULT_HOTEL_CODE;
}
$response = new CrmAttributes();
@@ -58,6 +58,7 @@ class DocumentsParser
return base64_decode($pdfData);
}
/** @return array{string, string} */
private function getFileInfo(Crawler $node): array
{
$pdfData = $this->decode($node->filterXPath('.//pdf'));
+11 -11
View File
@@ -37,7 +37,7 @@ class InsuranceParser extends AbstractParser
// Parse all individual insurances for reference lookup
$insurance = $this->parseInsuranceNode($node, false);
if (null !== $insurance && null !== $insurance->id) {
if (null !== $insurance->id) {
// Set complementary flag from XML attribute
$insurance->complementary = $isComplementary;
@@ -53,7 +53,7 @@ class InsuranceParser extends AbstractParser
$xmlContent->filterXPath('//versicherungspakete/versicherungspaket')
->each(function (Crawler $node) use (&$insurances, $individualInsurances) {
$insurance = $this->parseInsuranceNode($node, true, $individualInsurances);
if (null !== $insurance && null !== $insurance->id) {
if (null !== $insurance->id) {
// Parse contained insurance IDs
$insurance->containedInsuranceIds = $this->parseContainedInsuranceIds($node);
@@ -75,8 +75,8 @@ class InsuranceParser extends AbstractParser
/**
* Determines if a package contains any family insurances.
*
* @param Crawler $packageNode The package XML node
* @param array<int, Insurance> $individualInsurances Parsed individual insurances for reference
* @param Crawler $packageNode The package XML node
* @param array<string, Insurance> $individualInsurances Parsed individual insurances for reference
*
* @return bool True if any contained insurance is a family insurance
*/
@@ -96,13 +96,13 @@ class InsuranceParser extends AbstractParser
/**
* Parses a single insurance or package node.
*
* @param Crawler $node The XML node to parse
* @param bool $isPackage Whether this is a package node
* @param array<int, Insurance> $individualInsurances Individual insurances for package family detection
* @param Crawler $node The XML node to parse
* @param bool $isPackage Whether this is a package node
* @param array<string, Insurance> $individualInsurances Individual insurances for package family detection
*
* @return Insurance|null The parsed insurance object
* @return Insurance The parsed insurance object
*/
private function parseInsuranceNode(Crawler $node, bool $isPackage, array $individualInsurances = []): ?Insurance
private function parseInsuranceNode(Crawler $node, bool $isPackage, array $individualInsurances = []): Insurance
{
$insurance = new Insurance();
$insurance->package = $isPackage;
@@ -159,7 +159,7 @@ class InsuranceParser extends AbstractParser
*
* @param Crawler $xmlContent The XML content to scan
*
* @return array<int> Array of referenced insurance IDs
* @return list<string> Array of referenced insurance IDs
*/
private function collectReferencedInsuranceIds(Crawler $xmlContent): array
{
@@ -180,7 +180,7 @@ class InsuranceParser extends AbstractParser
*
* @param Crawler $node The package XML node
*
* @return array<int> Array of contained insurance IDs (always int, as they reference individual insurances)
* @return list<string> Array of contained insurance IDs
*/
private function parseContainedInsuranceIds(Crawler $node): array
{
@@ -7,6 +7,7 @@ use Symfony\Component\DomCrawler\Crawler;
class PickupsParser extends AbstractParser
{
/** @return array<int, Pickup> */
public function parse(Crawler $result): array
{
$pickups = [];
+1
View File
@@ -7,6 +7,7 @@ use Symfony\Component\DomCrawler\Crawler;
class RoomsParser extends AbstractParser
{
/** @return array<int, Room> */
public function parse(Crawler $result): array
{
$rooms = [];
@@ -8,6 +8,7 @@ use Symfony\Component\DomCrawler\Crawler;
class ServicesParser extends AbstractParser
{
/** @return array<int, Service> */
public function parse(Crawler $result, string $category, string $source): array
{
$services = [];
@@ -7,6 +7,7 @@ use Symfony\Component\DomCrawler\Crawler;
class SurchargesParser extends AbstractParser
{
/** @return list<Surcharge> */
public function parse(Crawler $result): array
{
$surcharges = [];