Skip to content

Commit

Permalink
Merge pull request #20 from php-soap/multiple-attribute-elements
Browse files Browse the repository at this point in the history
Parse multiple attribute elements
  • Loading branch information
veewee authored Jan 15, 2024
2 parents e0ed480 + 094bda6 commit 1b1b8b0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
40 changes: 17 additions & 23 deletions src/Metadata/Converter/Types/Visitor/AttributeContainerVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeSingle;
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group;
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
use RuntimeException;
use Soap\Engine\Metadata\Collection\PropertyCollection;
use Soap\Engine\Metadata\Model\Property;
use Soap\Engine\Metadata\Model\TypeMeta;
use Soap\Engine\Metadata\Model\XsdType as EngineType;
use Soap\WsdlReader\Metadata\Converter\Types\Configurator;
use Soap\WsdlReader\Metadata\Converter\Types\TypesConverterContext;
use function Psl\Fun\pipe;
use function Psl\Iter\first;
use function Psl\Result\wrap;
use function Psl\Type\instance_of;
use function Psl\Vec\flat_map;
use function Psl\Vec\map;

final class AttributeContainerVisitor
{
Expand All @@ -33,31 +32,26 @@ public function __invoke(AttributeContainer $container, TypesConverterContext $c

private function parseElementType(AttributeContainer $container, TypesConverterContext $context): PropertyCollection
{
$element = wrap(static function () use ($container, $context) : Property {
$elements = wrap(static function () use ($container, $context) : PropertyCollection {
$type = instance_of(Type::class)->assert($container);
$properties = [...(new ComplexBaseTypeVisitor())($type, $context)];

if (count($properties) !== 1) {
throw new RuntimeException('Expected only 1 element to be available as the attribute containers base.');
}

return first($properties);
});

return $element->proceed(
static fn (Property $detected): PropertyCollection => new PropertyCollection(
new Property(
$detected->getType()->getMeta()->isElement()->mapOrElse(
static fn (): string => $detected->getName(),
static fn (): string => '_'
)->unwrap(),
$detected->getType()->withMeta(
static fn (TypeMeta $meta): TypeMeta => $meta->withIsElementValue(true)
return new PropertyCollection(
...map(
(new ComplexBaseTypeVisitor())($type, $context),
static fn (Property $property): Property => new Property(
$property->getType()->getMeta()->isElement()->mapOrElse(
static fn (): string => $property->getName(),
static fn (): string => '_'
)->unwrap(),
$property->getType()->withMeta(
static fn (TypeMeta $meta): TypeMeta => $meta->withIsElementValue(true)
)
)
)
),
static fn (): PropertyCollection => new PropertyCollection(),
);
);
});

return $elements->catch(static fn () => new PropertyCollection())->getResult();
}

private function parseAttributes(AttributeContainer $container, TypesConverterContext $context): PropertyCollection
Expand Down
30 changes: 30 additions & 0 deletions tests/PhpCompatibility/schema1009.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
SOAP XML Schema 66: Required Attribute
--FILE--
<?php
include __DIR__."/test_schema.inc";
$schema = <<<EOF
<complexType name="immobile">
<sequence>
<element name="indirizzo" type="string" maxOccurs="1" minOccurs="0"/>
<element name="numero" type="string" maxOccurs="1" minOccurs="0"/>
<element name="zona" type="string" maxOccurs="1" minOccurs="0"/>
</sequence>
<attribute name="id" type="string"/>
<attribute name="id-agenzia" type="int"/>
</complexType>
EOF;
test_schema($schema,'type="tns:testType"');
?>
--EXPECTF--
Methods:
> test(testType $testParam): void

Types:
> http://test-uri/:immobile {
?string $indirizzo
?string $numero
?string $zona
@?string $id
@?int $id-agenzia
}

0 comments on commit 1b1b8b0

Please sign in to comment.