apiConfig = $apiConfig; $this->logger = $logger; } /** * Make a SOAP API call. * * @param MethodInterface $method * * @throws PostAtException * * @return mixed */ public function call(MethodInterface $method) { $body = $method->getBody(); $body = $this->appendConfiguration($body); try { $client = new \SoapClient($this->apiConfig->getSoapUrl()); } catch (\SoapFault $exception) { $this->logger->error('Cannot connect to the Post.at SOAP API.', ['exception' => $exception]); // The exception thrown above would be too technical for the end // user, so use a more user-friendly message instead. throw new PostAtException( 'Configuration of the Post.at module is invalid. Please verify the configuration.' ); } $response = $client->__soapCall($this->getClassName($method), [$body]); if ($response->errorCode !== null) { // A user-friendly error such as "This package type is not available for the chosen target country". throw new PostAtException("{$response->errorCode} - {$response->errorMessage}"); } return $response; } /** * Appends SOAP body entries that are required for every request. * * - clientID: DebitorID * - orgUnitID: OrganisationID; unique for a customerID * - orgUnitGuid: Unique GUID of the customerID * * For some reason the location of these entries is different within the SOAP * body structure depending on which API method is used. This function attempts * to cover all use cases. * * @param array $body * * @return array $body */ private function appendConfiguration(array $body): array { if (isset($body['row'])) { $body['row']['ClientID'] = $this->apiConfig->getClientId(); $body['row']['OrgUnitID'] = $this->apiConfig->getOrgUnitId(); $body['row']['OrgUnitGuid'] = $this->apiConfig->getOrgUnitGuid(); return $body; } if (isset($body['addresses'])) { // TODO Add this once one of the address API methods gets implemented. } // In simple requests the entries are at the root of the body. $body['clientID'] = $this->apiConfig->getClientId(); $body['orgUnitID'] = $this->apiConfig->getOrgUnitId(); $body['orgUnitGuid'] = $this->apiConfig->getOrgUnitGuid(); return $body; } /** * Gets the short name of the class (the part without the namespace). * * @param $method * * @throws \ReflectionException * * @return string */ private function getClassName($method): string { return (new \ReflectionClass($method))->getShortName(); } }