config = $this->resolveOptions($options); } /** * @throws ApiClientException */ public function getPersonalData(string $email, string $password): Notification|PersonalData { $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' => 'Adressdaten', 'email' => $email, 'passwort' => $password, ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ public function register(RegistrationData $registrationData): 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' => [ 'geschlecht' => $registrationData->gender, 'vorname' => $registrationData->firstName, 'name' => $registrationData->name, 'kommunikation' => [ 'email' => $registrationData->email, ], ], ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ public function resetPassword(string $email): 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' => 'Passwort_Anfrage', 'email' => $email, ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ public function updatePersonalData(string $email, string $password, PersonalData $personalData): Notification|PersonalData { $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' => 'Adressdaten_Ändern', 'email' => $email, 'passwort' => $password, 'idadresse' => $personalData->addressId, 'adressdaten' => $personalData->toPayload(), ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ public function updateNewsletterRegistration(string $email, string $password, PersonalData $personalData): Notification|PersonalData { $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' => 'Newsletter', 'email' => $email, 'passwort' => $password, 'idadresse' => $personalData->addressId, 'newsletter' => [ 'email' => $email, 'anmeldung' => $personalData->communication->newsletter ? 'True' : 'False', ], ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ public function getBookings(string $email, string $password): Notification|BaseData { $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' => 'Vorgänge', 'email' => $email, 'passwort' => $password, ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ public function getBooking(string $email, string $password, int $id): Notification|Booking { $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' => 'Vorgang_Details', 'email' => $email, 'passwort' => $password, 'idbuchung' => $id, ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } public function updateBooking(BookingData $formData, bool $dryRun = true): Notification|BookingUpdate { $mode = $dryRun ? 'Anfrage' : 'Buchung'; $payload = (new BookingDataProcessor())->createUpdateRequestPayload($formData); $data = [ 'user' => $this->config['bpn_username'], 'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], static::TYPE_BOOKING_UPDATE), 'satz' => ['@typ' => static::TYPE_BOOKING_UPDATE], 'buchungsart' => $mode, ...$payload, ]; return $this->sendRequest(static::TYPE_BOOKING_UPDATE, $data); } /** * @throws ApiClientException */ public function getMutableData(int $id): Notification|BaseData { $data = [ 'user' => $this->config['bpn_username'], 'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], static::TYPE_MUTABLE_DATA), 'satz' => ['@typ' => static::TYPE_MUTABLE_DATA], 'art' => 'Vorgang_Details', 'idreise' => $id, ]; return $this->sendRequest(static::TYPE_MUTABLE_DATA, $data); } /** * @throws ApiClientException */ public function getAvailabilities(int $id): Notification|BaseData { $data = [ 'user' => $this->config['bpn_username'], 'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], static::TYPE_AVAILABILITY), 'satz' => ['@typ' => static::TYPE_AVAILABILITY], 'idreise' => $id, ]; return $this->sendRequest(static::TYPE_AVAILABILITY, $data); } /** * @throws ApiClientException */ public function getCrmAttributes(string $email, string $password): Notification|CrmAttributes { $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' => 'SelektionCRM', 'email' => $email, 'passwort' => $password, ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ public function getBaseData(string $type): Notification|BaseData { $data = [ 'user' => $this->config['bpn_username'], 'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], $type), 'satz' => ['@typ' => $type], ]; return $this->sendRequest($type, $data); } /** * @return Notification|File|null * @throws ApiClientException */ public function getDocuments(string $email, string $password, int $id, string $type): mixed { $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' => $type, 'email' => $email, 'passwort' => $password, 'idbuchung' => $id, ]; return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); } /** * @throws ApiClientException */ private function sendRequest(string $type, array $data): mixed { $requestId = date(DATE_ATOM).uniqid(); $body = $this ->serializer ->serialize($data, 'xml', [ XmlEncoder::ROOT_NODE_NAME => 'anfrage', XmlEncoder::ENCODING => 'UTF-8', ]) ; if (true === $this->config['debug']) { $this->dumpXmlToFile('request', $requestId, $body); } try { $response = $this->httpClient->request('GET', $this->config['bpn_url'], [ 'query' => [ 'operation' => $body, ], 'verify_peer' => false, 'verify_host' => false, ]); $xml = $response->getContent(); if (true === $this->config['debug']) { $this->dumpXmlToFile('response', $requestId, $xml); } return $this->responseParser->parseXmlString($type, $xml); } catch (\Throwable $e) { } $this->logger->error('API error', ['error' => $e->getMessage()]); throw new ApiClientException($e->getMessage()); } private function dumpXmlToFile(string $type, string $requestId, string $body): void { if (false === file_exists($this->config['target_folder_dumps'])) { mkdir($this->config['target_folder_dumps']); } file_put_contents($this->config['target_folder_dumps'].'/'.$requestId.'_'.$type.'.xml', $body); } private function createKey(string $username, string $password, string $type): string { $date = (new \DateTimeImmutable())->format('Ymd'); return md5($username.$password.$date.$type); } private function resolveOptions(array $options): array { $optionsResolver = new OptionsResolver(); $optionsResolver->setRequired(['bpn_url', 'bpn_username', 'bpn_password']); $optionsResolver->setDefaults([ 'debug' => false, 'target_folder_dumps' => '/var/www/html/var/bpn', ]); return $optionsResolver->resolve($options); } }