diff --git a/composer.json b/composer.json index 49d34b1..69de947 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ ], "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "azjezz/psl": "^2.5" + "azjezz/psl": "^2.5", + "php-soap/xml": "^1.6.0" }, "autoload-dev": { "psr-4": { diff --git a/src/Metadata/Model/TypeMeta.php b/src/Metadata/Model/TypeMeta.php index 7058c17..0e3c5e1 100644 --- a/src/Metadata/Model/TypeMeta.php +++ b/src/Metadata/Model/TypeMeta.php @@ -68,6 +68,11 @@ final class TypeMeta */ private $isList; + /** + * @var bool|null + */ + private $isRepeatingElement; + /** * @var bool|null */ @@ -123,6 +128,20 @@ final class TypeMeta */ private $isQualified; + /** + * The soap-enc array-type information + * + * @var array{type: non-empty-string, itemType: non-empty-string, namespace: non-empty-string}|null + */ + private $arrayType; + + /** + * The name of the internal array nodes for soap-enc arrays + * + * @var string|null + */ + private $arrayNodeName; + /** * @return Option */ @@ -295,6 +314,22 @@ public function withIsList(?bool $isList): self return $new; } + /** + * @return Option + */ + public function isRepeatingElement(): Option + { + return from_nullable($this->isRepeatingElement); + } + + public function withIsRepeatingElement(?bool $isRepeatingElement): self + { + $new = clone $this; + $new->isRepeatingElement = $isRepeatingElement; + + return $new; + } + /** * @return Option */ @@ -484,4 +519,45 @@ public function withIsQualified(?bool $qualified): self return $new; } + + /** + * @return Option + */ + public function arrayType(): Option + { + return from_nullable($this->arrayType); + } + + /** + * @throws CoercionException + */ + public function withArrayType(?array $arrayType): self + { + $new = clone $this; + $new->arrayType = optional( + shape([ + 'type' => non_empty_string(), + 'itemType' => non_empty_string(), + 'namespace' => non_empty_string(), + ], true) + )->coerce($arrayType); + + return $new; + } + + /** + * @return Option + */ + public function arrayNodeName(): Option + { + return from_nullable($this->arrayNodeName); + } + + public function withArrayNodeName(?string $arrayNodeName): self + { + $new = clone $this; + $new->arrayNodeName = $arrayNodeName; + + return $new; + } } diff --git a/src/Metadata/Model/XsdType.php b/src/Metadata/Model/XsdType.php index d3f7e7c..dc6ad46 100644 --- a/src/Metadata/Model/XsdType.php +++ b/src/Metadata/Model/XsdType.php @@ -4,6 +4,8 @@ namespace Soap\Engine\Metadata\Model; +use Soap\Xml\Xmlns; + final class XsdType { /** @@ -75,6 +77,19 @@ public static function guess(string $name): self ->withBaseType(self::convertBaseType($name, '')); } + public static function any(): self + { + return self::guess('anyType') + ->withXmlTypeName('anyType') + ->withXmlNamespace(Xmlns::xsd()->value()) + ->withMeta( + static fn (TypeMeta $meta): TypeMeta => $meta + ->withIsSimple(true) + ->withIsNullable(true) + ->withIsNil(true) + ); + } + /** * @return array */ @@ -86,6 +101,7 @@ public static function fetchAllKnownBaseTypeMappings(): array 'anyuri' => 'string', 'anyxml' => 'string', 'anysimpletype' => 'mixed', + 'array' => 'array', 'base64binary' => 'string', 'byte' => 'integer', 'decimal' => 'float', diff --git a/tests/Unit/Metadata/Model/XsdTypeTest.php b/tests/Unit/Metadata/Model/XsdTypeTest.php index 698376b..bc356cb 100644 --- a/tests/Unit/Metadata/Model/XsdTypeTest.php +++ b/tests/Unit/Metadata/Model/XsdTypeTest.php @@ -59,7 +59,7 @@ public function test_it_can_add_known_base_type_and_move_actual_type_to_member_t static::assertSame('myType', $new->getName()); static::assertSame($baseType, $new->getBaseType()); static::assertSame($baseType, $new->getBaseTypeOrFallbackToName()); - static::assertSame([$typeName], $new->getMemberTypes()); + static::assertSame($typeName === $baseType ? [] : [$typeName], $new->getMemberTypes()); } }