How to generate a multilevel WSDL using Laminas SOAP

728 views Asked by At

I'm trying to figure out how to generate a multilevel XML using Laminas SOAP Autodiscover but I'm unable to do it.

I read the documentation but can not find a way to do it. Here's the link https://docs.laminas.dev/laminas-soap/auto-discovery/

Here is the output of what I need:

<Header>
 <item1>?</item1>
 <item2>?</item2>
<Line>
 <item3>?</item3>
 <item4>?</item4>
</Line>
</Header>

But I can not find a way to tell the AutoDiscover that a head (Header tag, that will contain a few tags and a child tag called Line). The only WSDL that is generated is by removing the Header and the Line from the function.

Class Soap
{
 public function test($item1,$item2,$item3,$item4) {
 return;
}
}

$serverUrl = "http://localhost/api.php";
$options = [
    'uri' => $serverUrl,
];
$server = new \Laminas\Soap\Server(null, $options);

if (isset($_GET['wsdl'])) {
    $soapAutoDiscover = new \Laminas\Soap\AutoDiscover(new \Laminas\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence());
    $soapAutoDiscover->setBindingStyle(array('style' => 'document'));
    $soapAutoDiscover->setOperationBodyStyle(array('use' => 'literal'));
    $soapAutoDiscover->setClass('Soap');
    $soapAutoDiscover->setUri($serverUrl);
    
    header("Content-Type: text/xml");
    echo $soapAutoDiscover->generate()->toXml();
} else {
    $soap = new \Laminas\Soap\Server($serverUrl . '?wsdl');
    $soap->setObject(new \Laminas\Soap\Server\DocumentLiteralWrapper(new Soap()));
    $soap->handle();
}

This will output just an WSDL with the four items:

<xsd:element name="test">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="item1" type="xsd:anyType"/>
<xsd:element name="item2" type="xsd:anyType"/>
<xsd:element name="item3" type="xsd:anyType"/>
<xsd:element name="item4" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

Any help will be appreciated.

1

There are 1 answers

0
Stefano On

Premise: I'm not a SOAP or Laminas expert but I'm currently working on a project with these. I know it's an old question but I came across this while searching for something different.

A method like this should output a result like the one you mentioned:

     /**
     * Test
     * @param string $item1
     * @param string $item2
     * @param string $item3
     * @param string $item4
     * @return mixed
     */
    function test($item1,$item2,$item3,$item4) {
        // create output
        $output = new stdClass();
        
        // define Header
        $header = new stdClass();
        $header->item1 = $item1;
        $header->item2 = $item2;
        
        // define Line
        $line = new stdClass();
        $line->item3 = $item3;
        $line->item4 = $item4;
        
        // assembling output
        $output->Header = $header;
        $output->Header->Line = $line;
       
        return $output;
    }

WSDL will be like:

[...]
<message name="testIn">
<part name="item1" type="xsd:string"/>
<part name="item2" type="xsd:string"/>
<part name="item3" type="xsd:string"/>
<part name="item4" type="xsd:string"/>
</message>
<message name="testOut">
<part name="return" type="xsd:anyType"/>
</message>
[...]

Request:

<x:Envelope
    xmlns:x="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ser="http://localhost/soap/server.php?wsdl">
    <x:Header/>
    <x:Body>
        <ser:test>
            <ser:item1>a</ser:item1>
            <ser:item2>b</ser:item2>
            <ser:item3>c</ser:item3>
            <ser:item4>d</ser:item4>
        </ser:test>
    </x:Body>
</x:Envelope>

Response:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="http://localhost/soap/server.php?wsdl"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:testResponse>
            <return xsi:type="SOAP-ENC:Struct">
                <Header xsi:type="SOAP-ENC:Struct">
                    <item1 xsi:type="xsd:string">a</item1>
                    <item2 xsi:type="xsd:string">b</item2>
                    <Line xsi:type="SOAP-ENC:Struct">
                        <item3 xsi:type="xsd:string">c</item3>
                        <item4 xsi:type="xsd:string">d</item4>
                    </Line>
                </Header>
            </return>
        </ns1:testResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>