Files
myep/src/BusProNet/XmlParser/ApiResponseParser.php
T

114 lines
5.5 KiB
PHP

<?php
namespace App\BusProNet\XmlParser;
use App\BusProNet\Exception\ResponseParserException;
use App\BusProNet\MessageType;
use App\BusProNet\XmlCrawlerFactory;
class ApiResponseParser extends AbstractParser
{
public function __construct(
private readonly TravelParser $travelParser,
) {
}
/**
* @param array<string, mixed> $additionalArgs
*
* @throws ResponseParserException
*/
public function parseXmlString(MessageType $type, string $xml, array $additionalArgs = []): mixed
{
$crawler = XmlCrawlerFactory::create($xml);
if (0 === $crawler->count()) {
throw new ResponseParserException('Unable to parse XML response: '.XmlCrawlerFactory::diagnose($xml));
}
// The type in the XML wins, to catch error responses. BusPro may send one we don't know.
$typeAttribute = $this->getStringOrNullValue($crawler->filterXPath('//ergebnis/satz/@typ'));
$responseType = null === $typeAttribute ? $type : MessageType::tryFrom($typeAttribute);
if (null === $responseType) {
throw new ResponseParserException(sprintf('Unrecognised BusProNet response type "%s"', $typeAttribute));
}
$resultNode = $crawler->filterXPath('//ergebnis');
try {
switch ($responseType) {
case MessageType::Notification:
return (new NotificationParser())->parse($crawler);
case MessageType::CustomerData:
$subType = $this->getStringOrNullValue($resultNode->filterXPath('//art'));
if (null === $subType || '' === $subType) {
throw new ResponseParserException('Unable to determine customer data subtype from XML response');
}
switch ($subType) {
case 'Adressdaten':
case 'Newsletter':
return (new PersonalDataParser())->parse($resultNode);
case 'Adressdaten_Ändern':
return (new PersonalDataUpdateParser())->parse($resultNode);
case 'Adresse_Neu':
return (new ContactFormResponseParser())->parse($resultNode);
case 'SelektionCRM':
case 'SelektionCRM_Ändern':
return (new CrmAttributesResponseParser())->parse($resultNode);
case 'Vorgänge':
return (new BookingsParser())->parse($resultNode);
case 'Vorgang_Details':
return (new BookingParser())->parse($resultNode);
case 'Dokumentdruck':
return (new DocumentsParser())->parseDocuments($resultNode);
case 'Vorgangdruck':
return (new DocumentsParser())->parseConfirmation($resultNode);
}
throw new ResponseParserException(sprintf('Unrecognised customer data subtype "%s"', $subType));
case MessageType::Countries:
return (new CountriesParser())->parse($resultNode);
case MessageType::MutableData:
return (new MutableDataParser())->parse($resultNode);
case MessageType::Availability:
return (new AvailabilitiesParser())->parseServices($resultNode);
case MessageType::AvailabilityExtended:
return (new ExtendedAvailabilitiesParser())->parseServices($resultNode);
case MessageType::AvailabilityHotel:
return (new AvailabilitiesParser())->parseRooms($resultNode);
case MessageType::BookingUpdate:
return (new BookingUpdateParser())->parse($resultNode);
case MessageType::Booking:
return (new BookingResponseParser())->parse($resultNode);
case MessageType::Products:
return (new ProductsParser())->parse($resultNode);
case MessageType::ProductData:
$travelNode = $crawler->filterXPath('//reise/termin');
if (0 === $travelNode->count()) {
throw new ResponseParserException('No travel data node found in product data response');
}
return $this->travelParser->parse($travelNode->first(), ...$additionalArgs);
case MessageType::Agencies:
return (new AgencyParser())->parse($resultNode);
case MessageType::PurchaseVoucher:
return (new PurchaseVoucherParser())->parse($resultNode);
case MessageType::PromoVoucher:
return (new PromoVoucherParser())->parse($resultNode);
case MessageType::VoucherTemplates:
return (new VoucherTemplatesParser())->parse($resultNode);
case MessageType::VoucherPaymentMethods:
return (new VoucherPaymentMethodsParser())->parse($resultNode);
case MessageType::VoucherPreview:
return (new VoucherPreviewParser())->parse($resultNode);
case MessageType::VoucherSale:
return (new VoucherSaleResponseParser())->parse($resultNode);
}
} catch (\InvalidArgumentException $e) {
throw new ResponseParserException('Invalid XML response structure: '.$e->getMessage(), 0, $e);
}
}
}