WsdlToPhp / PackageGenerator

Generates a PHP SDK based on a WSDL, simple and powerful, WSDL to PHP
https://providr.io
MIT License
428 stars 73 forks source link

Attributes from extended StructType classes #318

Closed agmattzarb closed 2 months ago

agmattzarb commented 3 months ago

I've used the PackageGenerator to generate the classes to connect to a 3rd party SOAP service, but seem to be having issues with the generated XML. Seems to be regarding extended classes. Not sure what I'm doing wrong, or if I should have used some specific options when generating the classes.

What I get in my generated classes is (methods removed for readability):

/**
 * This class stands for Post ServiceType
 * @subpackage Services
 */
class Post extends AbstractSoapClientBase
{
    /**
     * Method to call the operation originally named postMessage
     * @uses AbstractSoapClientBase::getSoapClient()
     * @uses AbstractSoapClientBase::setResult()
     * @uses AbstractSoapClientBase::saveLastError()
     * @param \EAPI\StructType\PostMessage $parameters
     * @return \EAPI\StructType\PostMessageResponse|bool
     */
    public function postMessage(\EAPI\StructType\PostMessage $parameters)
    {
        try {
            $this->setResult($resultPostMessage = $this->getSoapClient()->__soapCall('postMessage', [
                $parameters,
            ], [], [], $this->outputHeaders));

            return $resultPostMessage;
        } catch (SoapFault $soapFault) {
            $this->saveLastError(__METHOD__, $soapFault);

            return false;
        }
    }
}

class PostMessage extends AbstractStructBase
{

    public function __construct(?string $mainMemberCode = null, ?\EAPI\StructType\ErosMessage $erosMessage = null)
    {
        $this
            ->setMainMemberCode($mainMemberCode)
            ->setErosMessage($erosMessage);
    }
}

abstract class ErosMessage extends AbstractStructBase
{

    public function __construct(?string $correlationReference = null, ?string $externalReferenceNumber = null, ?string $operator = null, ?string $receivingMemberCode = null, ?string $sendingMemberCode = null, ?string $service = null)
    {
        $this
            ->setCorrelationReference($correlationReference)
            ->setExternalReferenceNumber($externalReferenceNumber)
            ->setOperator($operator)
            ->setReceivingMemberCode($receivingMemberCode)
            ->setSendingMemberCode($sendingMemberCode)
            ->setService($service);
    }

}

class OrderMessage extends ErosMessage
{

    public function __construct(?int $originalOrderSequenceNumber = null, ?string $originalOrderReferenceNumber = null, ?string $cardMessage = null, ?string $conventionMessage = null, ?string $deliveryDate = null, ?string $deliveryDetails = null)
    {
        $this
            ->setOriginalOrderSequenceNumber($originalOrderSequenceNumber)
            ->setOriginalOrderReferenceNumber($originalOrderReferenceNumber)
            ->setCardMessage($cardMessage)
            ->setConventionMessage($conventionMessage)
            ->setDeliveryDate($deliveryDate)
            ->setDeliveryDetails($deliveryDetails);
    }

}

My code to create and post a new message to the SOAP service is:

$message = new OrderMessage($originalOrderSequenceNumber, $originalOrderReferenceNumber, $cardMessage, $conventionMessage, $deliveryDate, $deliveryDetails);

$message->setCorrelationReference($correlationReference);
$message->setExternalReferenceNumber($externalReferenceNumber);
$message->setOperator($operator);
$message->setReceivingMemberCode($receivingMemberCode);
$message->setSendingMemberCode($this->mainMemberCode);
$message->setService($this->service);

$params = new PostMessage($this->mainMemberCode, $message);
$post = new Post($this->options);
$post->setLocation($this->wsdl);
$result = $post->postMessage($params);

When retrieving the last request, this results in:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://eapi.ftd.com/message/service/v1/" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <ns1:postMessage>
      <ns1:mainMemberCode>90-0002BJ</ns1:mainMemberCode>
      <ns1:erosMessage>
        <ns1:correlationReference>135718162</ns1:correlationReference>
        <ns1:externalReferenceNumber>135718162/orderMessage</ns1:externalReferenceNumber>
        <ns1:operator>System</ns1:operator>
        <ns1:receivingMemberCode>53-0886AA</ns1:receivingMemberCode>
        <ns1:sendingMemberCode>90-0002BJ</ns1:sendingMemberCode>
        <ns1:service>FTD</ns1:service>
      </ns1:erosMessage>
    </ns1:postMessage>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

However, the vendor specs and wsdl say it should look like this:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://eapi.ftd.com/message/service/v1/">
  <SOAP-ENV:Header/>
   <soapenv:Body>
      <v1:postMessage>
         <v1:mainMemberCode>?????</v1:mainMemberCode>
         <v1:erosMessage xsi:type="v1:orderMessage" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <v1:correlationReference>?????</v1:correlationReference>
            <v1:externalReferenceNumber>?????</v1:externalReferenceNumber>
            <v1:operator>??????</v1:operator>
            <v1:receivingMemberCode>?????</v1:receivingMemberCode>
            <v1:sendingMemberCode>?????</v1:sendingMemberCode>
            <v1:service>FTD</v1:service>
            <v1:cardMessage>?????</v1:cardMessage>
            <v1:conventionMessage>?????</v1:conventionMessage>
            <v1:deliveryDate>?????</v1:deliveryDate>
            <v1:deliveryDetails>?????!</v1:deliveryDetails>
         </v1:erosMessage>
      </v1:postMessage>
   </soapenv:Body>
</soapenv:Envelope>

I can't figure out why the attributes for the PostMessage class show up in the XML but the attributes for the extended class OrderMessage do not.

I also see the erosMessage in the XML has an xsi:type="v1:orderMessage". Is there something I need to do for that to encode?