Skip to content

Commit 873a4be

Browse files
committed
Enhance property meta with container meta
1 parent f4ebc7b commit 873a4be

3 files changed

Lines changed: 105 additions & 1 deletion

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Soap\WsdlReader\Metadata\Converter\Types\Configurator;
4+
5+
use Closure;
6+
use GoetasWebservices\XML\XSDReader\Schema\Element\InterfaceSetMinMax;
7+
use Soap\Engine\Metadata\Collection\PropertyCollection;
8+
use Soap\Engine\Metadata\Model\Property;
9+
use Soap\Engine\Metadata\Model\TypeMeta;
10+
use Soap\Engine\Metadata\Model\XsdType;
11+
use Soap\WsdlReader\Metadata\Converter\Types\TypesConverterContext;
12+
use function Psl\Fun\pipe;
13+
use function Psl\Vec\map;
14+
15+
final readonly class ElementContainerConfigurator
16+
{
17+
public function __invoke(PropertyCollection $properties, mixed $xsdType, TypesConverterContext $context): PropertyCollection
18+
{
19+
$configure = pipe(
20+
fn (PropertyCollection $properties): PropertyCollection => $this->overwriteMinMaxSettings($properties, $xsdType),
21+
);
22+
23+
return $configure($properties);
24+
}
25+
26+
/**
27+
* @param Closure(XsdType): XsdType $mapper
28+
*/
29+
private function mapPropertyTypes(PropertyCollection $properties, Closure $mapper): PropertyCollection
30+
{
31+
return new PropertyCollection(
32+
...map(
33+
$properties,
34+
static fn (Property $property): Property => new Property(
35+
$property->getName(),
36+
$mapper($property->getType())
37+
)
38+
)
39+
);
40+
}
41+
42+
private function overwriteMinMaxSettings(PropertyCollection $properties, mixed $xsdType): PropertyCollection
43+
{
44+
if (!$xsdType instanceof InterfaceSetMinMax) {
45+
return $properties;
46+
}
47+
48+
$groupMin = $xsdType->getMin();
49+
$groupMax = $xsdType->getMax();
50+
51+
return $this->mapPropertyTypes($properties, static function (XsdType $type) use ($groupMin, $groupMax): XsdType {
52+
$meta = $type->getMeta();
53+
$min = $groupMin === 0 ? 0 : $meta->minOccurs()->unwrapOr($groupMax);
54+
$max = $groupMax === -1 ? -1 : $meta->maxOccurs()->unwrapOr($groupMax);
55+
56+
$isNullable = $meta->isNullable()->unwrapOr(false) || ($min === 0 && $max === 1);
57+
$isList = $meta->isList()->unwrapOr(false) || ($min > 1 || $max === -1);
58+
59+
return $type
60+
->withBaseType($isList ? 'array' : $type->getBaseType())
61+
->withMeta(
62+
static fn (TypeMeta $meta): TypeMeta => $meta
63+
->withMinOccurs($groupMin)
64+
->withMaxOccurs($groupMax)
65+
->withIsNullable($isNullable)
66+
->withIsList($isList)
67+
->withIsRepeatingElement($isList)
68+
);
69+
});
70+
}
71+
}

src/Metadata/Converter/Types/Visitor/ElementContainerVisitor.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ public function __invoke(ElementContainer $container, TypesConverterContext $con
3232
private function parseElementItem(ElementItem $element, TypesConverterContext $context): PropertyCollection
3333
{
3434
if ($element instanceof Group || $element instanceof Choice || $element instanceof Sequence) {
35-
return $this->__invoke($element, $context);
35+
$configure = pipe(
36+
static fn (PropertyCollection $properties) => (new Configurator\ElementContainerConfigurator())($properties, $element, $context),
37+
);
38+
39+
return $configure($this->__invoke($element, $context));
3640
}
3741

3842
$typeName = (new ElementTypeNameDetector())($element, $context->parent()->unwrap());
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
SOAP XML Schema 1015: Group ref with minOccurs / MaxOccurs
3+
--FILE--
4+
<?php
5+
include __DIR__."/test_schema.inc";
6+
$schema = <<<EOF
7+
<complexType name="storeCardResult">
8+
<sequence>
9+
<group minOccurs="0" ref="tns:securityDetailsGroup"/>
10+
</sequence>
11+
</complexType>
12+
<group name="securityDetailsGroup">
13+
<sequence>
14+
<element name="foo" type="string"/>
15+
<element name="bar" type="string"/>
16+
</sequence>
17+
</group>
18+
EOF;
19+
test_schema($schema,'type="tns:Element"');
20+
?>
21+
--EXPECT--
22+
Methods:
23+
> test(Element $testParam): void
24+
25+
Types:
26+
> http://test-uri/:storeCardResult {
27+
?string $foo
28+
?string $bar
29+
}

0 commit comments

Comments
 (0)