Generate WSDL with a complex subtype using Laminas SOAP in laravel

262 Views Asked by At

i'm trying to figure how to generate multilevel wsdl using Laminas SOAP in my Laravel.. i did read the documentation and chatgpt too.. but im still confused how to set up, here's the link : https://docs.laminas.dev/laminas-soap/auto-discovery/

This is my controller code :

public function soap()
{
    $server = new Server(
        route('soap-wsdl'),
        [
            'actor' => route('soap-server'),
        ]
    );

    $this->populateServer($server);
    $server->setReturnResponse(true);

    $response = response($server->handle());
    $response->header('Content-Type', 'text/xml');

    return $response;
}

public function wsdl(Request $request)
{
    $wsdl = new AutoDiscover();

    $this->populateServer($wsdl);
    $wsdl->setUri(route('soap-server'))
        ->setServiceName('InaportWSDL');

    return response()->make($wsdl->toXml())
        ->header('Content-Type', 'application/xml');
}

private function populateServer($server)
{
    // Expose a class and its methods:
    $server->setClass(ResponseServices::class);
}

and this is my ResponseServices class (or Controller) :

class ResponseServices {
/**
 * @param string $user
 * @param string $password
 * @param array $detail
 */
public function entryRpkro($user, $password, $detail)
{
}

}

result using wizdler :

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
    <entryRpkro xmlns="http://localhost:8000/soap">
        <user>[string]</user>
        <password>[string]</password>
        <detail>[Array]</detail>
    </entryRpkro>
</Body>
</Envelope>

So i want to change this wsdl into this :

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
    <entryRpkro xmlns="http://localhost:8000/soap">
        <user>[string]</user>
        <password>[string]</password>
        <detail>
          <name>[string]</name>
          <age>[int]</age>
        </detail>
    </entryRpkro>
</Body>
</Envelope>
1

There are 1 best solutions below

0
Bean209 On

Try something like this: Create another file Details.php. Don't forget to set the namespace.

class Details
{
    /** @var string */
    public string $name = '';
    /** @var int */
    public string $age = '';
}

Change the above code to something like this:

class ResponseServices {
    /**
     * @param string $user
     * @param string $password
     * @param \FULL\NAMESPACE\PATH\Details $details
     */
    public function entryRpkro(string $user, string $password, Details $details)
    {
        // Now you can access $details->name or $details->age
    }
}

Keep in mind that you always need to use FQCN in the @param and @return Annotation in order to get the correct mapping with laminas. Maybe in the future you also want to adjust the complexTypeStrategy from laminas. So far ArrayOfTypeComplex has always worked best for me.