From b9dfeb2d3ea074368d86eab3aef8c54bf9410b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Wed, 10 Dec 2025 18:00:51 +0100 Subject: [PATCH] feat: backport contact form api endpoint --- api.http | 16 ++++++ src/BusProNet/ApiClient.php | 18 +++++++ src/BusProNet/Model/ContactFormResponse.php | 13 +++++ src/BusProNet/Model/ContactFormSubmission.php | 15 ++++++ src/BusProNet/Model/PersonalData.php | 19 +++++++ src/BusProNet/XmlParser/ApiResponseParser.php | 2 + .../XmlParser/ContactFormResponseParser.php | 24 +++++++++ src/Controller/Api/ContactFormController.php | 53 +++++++++++++++++++ 8 files changed, 160 insertions(+) create mode 100644 src/BusProNet/Model/ContactFormResponse.php create mode 100644 src/BusProNet/Model/ContactFormSubmission.php create mode 100644 src/BusProNet/XmlParser/ContactFormResponseParser.php create mode 100644 src/Controller/Api/ContactFormController.php diff --git a/api.http b/api.http index feafa86..740f8f6 100644 --- a/api.http +++ b/api.http @@ -53,3 +53,19 @@ GET {{base_url}}/api/travels/DWWWE211125 Accept: application/json Authorization: Bearer {{$auth.token("oauth2_api")}} +### API contact form +POST {{base_url}}/api/contactform +Accept: application/json +Content-Type: application/json +Authorization: Bearer {{$auth.token("oauth2_api")}} + +{ + "lastName": "Duschen", + "firstName": "Isolde", + "gender": "f", + "street": "Fooroad 1", + "zipCode": "12345", + "city": "Bartown", + "email": "foo@example.com", + "phone": "12345" +} diff --git a/src/BusProNet/ApiClient.php b/src/BusProNet/ApiClient.php index ea644ce..fd1db9b 100644 --- a/src/BusProNet/ApiClient.php +++ b/src/BusProNet/ApiClient.php @@ -8,6 +8,7 @@ use App\BusProNet\Exception\ResponseParserException; use App\BusProNet\Model\BaseData; use App\BusProNet\Model\Booking; use App\BusProNet\Model\BookingUpdate; +use App\BusProNet\Model\ContactFormResponse; use App\BusProNet\Model\CrmAttributes; use App\BusProNet\Model\Notification; use App\BusProNet\Model\PersonalData; @@ -62,6 +63,23 @@ class ApiClient return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } + /** + * @throws ApiClientException + */ + public function createAddress(PersonalData $personalData, bool $debug = false): ContactFormResponse|Notification + { + $data = [ + 'user' => $this->config['bpn_username'], + 'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], static::TYPE_CUSTOMER_DATA), + 'satz' => ['@typ' => static::TYPE_CUSTOMER_DATA], + 'art' => 'Adresse_Neu', + 'adressdaten' => $personalData->toPayload(), + 'ohnemailversand' => 'True', + ]; + + return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data, [], $debug); + } + /** * @throws ApiClientException */ diff --git a/src/BusProNet/Model/ContactFormResponse.php b/src/BusProNet/Model/ContactFormResponse.php new file mode 100644 index 0000000..12080da --- /dev/null +++ b/src/BusProNet/Model/ContactFormResponse.php @@ -0,0 +1,13 @@ +communication = new Communication(); } + public static function fromContactFormSubmission(ContactFormSubmission $dto): self + { + $gender = null !== $dto->gender ? strtoupper($dto->gender) : null; + if ('F' === $gender) { + $gender = 'W'; + } + $instance = new self(); + $instance->name = $dto->lastName; + $instance->firstName = $dto->firstName; + $instance->gender = $gender; + $instance->address->street = $dto->street; + $instance->address->postCode = $dto->zipCode; + $instance->address->city = $dto->city; + $instance->communication->email = $dto->email; + $instance->communication->phone = $dto->phone; + + return $instance; + } + public function toPayload(): array { // Ensure date of birth is populated diff --git a/src/BusProNet/XmlParser/ApiResponseParser.php b/src/BusProNet/XmlParser/ApiResponseParser.php index b65385a..e826298 100644 --- a/src/BusProNet/XmlParser/ApiResponseParser.php +++ b/src/BusProNet/XmlParser/ApiResponseParser.php @@ -36,6 +36,8 @@ class ApiResponseParser extends AbstractParser case 'Adressdaten_Ändern': case 'Newsletter': return (new PersonalDataParser())->parse($resultNode); + case 'Adresse_Neu': + return (new ContactFormResponseParser())->parse($resultNode); case 'SelektionCRM': case 'SelektionCRM_Ändern': return (new CrmAttributesResponseParser())->parse($resultNode); diff --git a/src/BusProNet/XmlParser/ContactFormResponseParser.php b/src/BusProNet/XmlParser/ContactFormResponseParser.php new file mode 100644 index 0000000..e67bacd --- /dev/null +++ b/src/BusProNet/XmlParser/ContactFormResponseParser.php @@ -0,0 +1,24 @@ +filterXPath('//idadresse')->text(); + $personId = (int) $node->filterXPath('//idperson')->text(); + $isNewRecord = $this->getBoolValue($node->filterXPath('//neuanlage')); + + return new ContactFormResponse( + addressId: $addressId, + personId: $personId, + isNewRecord: $isNewRecord, + ); + } +} diff --git a/src/Controller/Api/ContactFormController.php b/src/Controller/Api/ContactFormController.php new file mode 100644 index 0000000..addcf9d --- /dev/null +++ b/src/Controller/Api/ContactFormController.php @@ -0,0 +1,53 @@ +apiClient->createAddress($personalData); + + if ($result instanceof Notification) { + return new JsonResponse([ + 'success' => false, + 'message' => $result->message, + ], Response::HTTP_CONFLICT); + } + + return $this->json([ + 'success' => true, + 'addressId' => $result->addressId, + 'personId' => $result->personId, + 'isNewRecord' => $result->isNewRecord, + ], Response::HTTP_CREATED); + } catch (ApiClientException $e) { + return new JsonResponse([ + 'success' => false, + 'message' => $e->getMessage(), + ], Response::HTTP_BAD_REQUEST); + } + } +}