diff --git a/src/Encoder/Fault/Soap11FaultEncoder.php b/src/Encoder/Fault/Soap11FaultEncoder.php new file mode 100644 index 0000000..e10ccd7 --- /dev/null +++ b/src/Encoder/Fault/Soap11FaultEncoder.php @@ -0,0 +1,50 @@ + + */ +final class Soap11FaultEncoder implements XmlEncoder +{ + /** + * @return Iso + */ + public function iso(Context $context): Iso + { + return new Iso( + static fn (Soap11Fault $fault): string => throw new RuntimeException('not implemented yet'), + static fn (string $fault): Soap11Fault => throw new RuntimeException('not implemented yet') + ); + } +} + + +/* + * + * + + + + a:Microsoft.Dynamics.Nav.Service.WebServices.ServiceBrokerException + + Parameter languagecode in method CategoryList in service DumpServices is + null! + + + Parameter languagecode in method + CategoryList in service DumpServices is null! + + + + + + + */ diff --git a/src/Encoder/Fault/Soap12FaultEncoder.php b/src/Encoder/Fault/Soap12FaultEncoder.php new file mode 100644 index 0000000..cb63b1e --- /dev/null +++ b/src/Encoder/Fault/Soap12FaultEncoder.php @@ -0,0 +1,139 @@ + + */ +final class Soap12FaultEncoder implements XmlEncoder +{ + private const ENV_NAMESPACE = 'http://www.w3.org/2003/05/soap-envelope'; + + /** + * @return Iso + */ + public function iso(Context $context): Iso + { + return new Iso( + $this->to(...), + $this->from(...) + ); + } + + private function to(Soap12Fault $fault): string + { + return Writer::inMemory() + ->write(children([ + namespaced_element( + self::ENV_NAMESPACE, + 'env', + 'Fault', + children([ + prefixed_element( + 'env', + 'Code', + children([ + prefixed_element( + 'env', + 'Value', + value($fault->code) + ), + ...( + $fault->subCode + ? [ + prefixed_element( + 'env', + 'Subcode', + children([ + prefixed_element( + 'env', + 'Value', + value($fault->subCode) + ) + ]) + ) + ] + : [] + ), + + ]) + ), + prefixed_element( + 'env', + 'Reason', + children([ + prefixed_element( + 'env', + 'Text', + value($fault->reason) + ) + ]) + ), + ...( + $fault->node + ? [ + prefixed_element( + 'env', + 'Node', + value($fault->node) + ) + ] + : [] + ), + ...( + $fault->role + ? [ + prefixed_element( + 'env', + 'Role', + value($fault->role) + ) + ] + : [] + ), + ...($fault->detail ? [raw($fault->detail)] : []), + ]) + ) + ])) + ->map(memory_output()); + } + + /** + * @param non-empty-string $fault + */ + private function from(string $fault): Soap12Fault + { + $document = Document::fromXmlString($fault); + $documentElement = $document->locateDocumentElement(); + $xpath = $document->xpath(namespaces(['env' => $documentElement->namespaceURI])); + + $subCode = $xpath->query('//env:Code/env:Subcode/env:Value'); + $node = $xpath->query('//env:Node'); + $role = $xpath->query('//env:Role'); + $detail = $xpath->query('//env:Detail'); + + return new Soap12Fault( + code: $xpath->querySingle('//env:Code/env:Value')->textContent, + reason: $xpath->querySingle('//env:Reason/env:Text')->textContent, + subCode: $subCode->count() ? $subCode->first()->textContent : null, + node: $node->count() ? $node->first()->textContent : null, + role: $role->count() ? $role->first()->textContent : null, + detail: $detail->count() ? Document::fromXmlNode($detail->first())->stringifyDocumentElement() : null, + ); + } +} diff --git a/src/Exception/SoapFaultException.php b/src/Exception/SoapFaultException.php new file mode 100644 index 0000000..7b38afa --- /dev/null +++ b/src/Exception/SoapFaultException.php @@ -0,0 +1,28 @@ +fault->reason(), + $this->fault->code(), + ), + ); + } + + public function fault(): SoapFault + { + return $this->fault; + } +} diff --git a/src/Model/Soap11Fault.php b/src/Model/Soap11Fault.php new file mode 100644 index 0000000..c546ab8 --- /dev/null +++ b/src/Model/Soap11Fault.php @@ -0,0 +1,11 @@ +code; + } + + public function reason(): string + { + return $this->reason; + } + + public function detail(): ?string + { + return $this->detail; + } +} diff --git a/src/Model/SoapFault.php b/src/Model/SoapFault.php new file mode 100644 index 0000000..53c2e4e --- /dev/null +++ b/src/Model/SoapFault.php @@ -0,0 +1,13 @@ + $encoder = new Soap12FaultEncoder(), + 'context' => $context = self::createContext( + // Context is not important. + XsdType::guess('Fault') + ), + ]; + + yield 'required-fields-only' => [ + ...$baseConfig, + 'xml' => Document::configure( + trim_spaces(), + loader(xml_string_loader( + << + + env:Sender + + + Sender Timeout + + + EOXML + )) + )->stringifyDocumentElement(), + 'data' => new Soap12Fault( + code: 'env:Sender', + reason: 'Sender Timeout', + ), + ]; + yield 'subcode-and-details-example' => [ + ...$baseConfig, + 'xml' => Document::configure( + trim_spaces(), + loader(xml_string_loader( + << + + env:Sender + + m:MessageTimeout + + + + Sender Timeout + + P5M + + EOXML + )) + )->stringifyDocumentElement(), + 'data' => new Soap12Fault( + code: 'env:Sender', + subCode: 'm:MessageTimeout', + reason: 'Sender Timeout', + detail: trim(<<P5M + EOXML) + ), + ]; + yield 'full-example' => [ + ...$baseConfig, + 'xml' => Document::configure( + trim_spaces(), + loader(xml_string_loader( + << + + env:Sender + + m:MessageTimeout + + + + Sender Timeout + + urn:node + urn:role + P5M + + EOXML + )) + )->stringifyDocumentElement(), + 'data' => new Soap12Fault( + code: 'env:Sender', + subCode: 'm:MessageTimeout', + reason: 'Sender Timeout', + node: 'urn:node', + role: 'urn:role', + detail: trim(<<P5M + EOXML) + ), + ]; + } +}