From 87861524f90fc1643830f09a187c07baf3b4c16c Mon Sep 17 00:00:00 2001 From: Toon Verwerft Date: Fri, 24 May 2024 16:06:41 +0200 Subject: [PATCH] Allow empty return types --- composer.json | 1 + .../MessageToMetadataTypesConverter.php | 49 +++++++++++++++---- .../Converter/Wsdl1ToMethodsConverter.php | 8 +-- src/Model/Definitions/Part.php | 2 +- src/Parser/Definitions/MessageParser.php | 16 ++++-- 5 files changed, 54 insertions(+), 22 deletions(-) diff --git a/composer.json b/composer.json index a8529b0..7774f2a 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "goetas-webservices/xsd-reader": "^0.4.1", "php-soap/engine": "^2.8", "php-soap/wsdl": "^1.4", + "php-soap/xml": "^1.6.0", "veewee/xml": "^2.6 || ^3.0", "azjezz/psl": "^2.4", "symfony/console": "^5.4 || ^6.0 || ^7.0" diff --git a/src/Metadata/Converter/Methods/Converter/MessageToMetadataTypesConverter.php b/src/Metadata/Converter/Methods/Converter/MessageToMetadataTypesConverter.php index 03c9001..0d42229 100644 --- a/src/Metadata/Converter/Methods/Converter/MessageToMetadataTypesConverter.php +++ b/src/Metadata/Converter/Methods/Converter/MessageToMetadataTypesConverter.php @@ -12,6 +12,7 @@ use Soap\WsdlReader\Model\Definitions\Namespaces; use Soap\WsdlReader\Model\Definitions\Part; use Soap\WsdlReader\Model\Definitions\QNamed; +use Soap\Xml\Xmlns; use function Psl\Dict\pull; final class MessageToMetadataTypesConverter @@ -29,13 +30,17 @@ public function __invoke(Message $message): array { return pull( $message->parts->items, - fn (Part $part): XsdType => $this->findXsdType($part->element), + fn (Part $part): XsdType => $this->findXsdType($part->element)->withXmlTargetNodeName($part->name), static fn (Part $message): string => $message->name ); } - private function findXsdType(QNamed $type): XsdType + private function findXsdType(?QNamed $type): XsdType { + if ($type === null) { + return $this->createAnyType(); + } + $namespace = $this->namespaces->lookupNamespaceByQname($type); try { @@ -44,14 +49,38 @@ private function findXsdType(QNamed $type): XsdType fn (): EngineType => $this->knownTypes->fetchFirstByName($type->localName), )->unwrap()->getXsdType(); } catch (MetadataException $e) { - // Proxy to simple/base type ... - return XsdType::guess($type->localName) - ->withXmlNamespaceName($type->prefix) - ->withXmlNamespace($namespace->unwrapOr('')) - ->withXmlTypeName($type->localName) - ->withMeta( - static fn (TypeMeta $meta): TypeMeta => $meta->withIsSimple(true) - ); + return $this->createSimpleTypeByQNamed($type); } } + + private function createSimpleTypeByQNamed(QNamed $type): XsdType + { + $namespace = $this->namespaces->lookupNamespaceByQname($type); + + return XsdType::guess($type->localName) + ->withXmlNamespaceName($type->prefix) + ->withXmlNamespace($namespace->unwrapOr('')) + ->withXmlTypeName($type->localName) + ->withMeta( + static fn (TypeMeta $meta): TypeMeta => $meta + ->withIsSimple(true) + ->withIsElement(true) + ); + } + + private function createAnyType(): XsdType + { + $namespace = Xmlns::xsd()->value(); + + return XsdType::guess('anyType') + ->withXmlTypeName('anyType') + ->withXmlNamespaceName($this->namespaces->lookupNameFromNamespace($namespace)->unwrapOr('')) + ->withXmlNamespace($namespace) + ->withXmlTypeName('anyType') + ->withMeta( + static fn (TypeMeta $meta): TypeMeta => $meta + ->withIsSimple(true) + ->withIsElement(true) + ); + } } diff --git a/src/Metadata/Converter/Wsdl1ToMethodsConverter.php b/src/Metadata/Converter/Wsdl1ToMethodsConverter.php index 0ad1929..5d7ae00 100644 --- a/src/Metadata/Converter/Wsdl1ToMethodsConverter.php +++ b/src/Metadata/Converter/Wsdl1ToMethodsConverter.php @@ -51,13 +51,7 @@ private function parseMethod(Wsdl1SelectedService $service, BindingOperation $bi $parameters = $inputMessage->map($convertMessageToTypesDict)->mapOr( static fn (array $types) => map_with_key( $types, - static fn (string $name, XsdType $type) => new Parameter( - $name, - // Make sure the target type encodes into an **element** that is **named like the parameter part**. - $type - ->withXmlTargetNodeName($name) - ->withMeta(static fn (TypeMeta $meta): TypeMeta => $meta->withIsElement(true)) - ) + static fn (string $name, XsdType $type) => new Parameter($name, $type) ), [] ); diff --git a/src/Model/Definitions/Part.php b/src/Model/Definitions/Part.php index 3070939..271a8d5 100644 --- a/src/Model/Definitions/Part.php +++ b/src/Model/Definitions/Part.php @@ -7,7 +7,7 @@ final class Part { public function __construct( public readonly string $name, - public readonly QNamed $element, + public readonly ?QNamed $element, ) { } } diff --git a/src/Parser/Definitions/MessageParser.php b/src/Parser/Definitions/MessageParser.php index 9d808a8..25720e1 100644 --- a/src/Parser/Definitions/MessageParser.php +++ b/src/Parser/Definitions/MessageParser.php @@ -24,10 +24,18 @@ public function __invoke(Document $wsdl, DOMElement $message): Message ...$xpath->query('./wsdl:part', $message) ->expectAllOfType(DOMElement::class) ->map( - static fn (DOMElement $part) => new Part( - name: $part->getAttribute('name'), - element: QNamed::parse($part->getAttribute('element') ?: $part->getAttribute('type')) - ) + static function (DOMElement $part) { + $element = match (true) { + $part->hasAttribute('element') => QNamed::parse($part->getAttribute('element')), + $part->hasAttribute('type') => QNamed::parse($part->getAttribute('type')), + default => null + }; + + return new Part( + name: $part->getAttribute('name'), + element: $element, + ); + } ) ) );