7

I am trying to simply send RAW xml to a webservice via PHP and SoapClient. The problem is when I encode my XML it changes the order of elements in the XML that is converted to an associative array.

// Initialize the Soap Client:
$this->_transactionServicesClient = new SoapClient($soapWSDLUrl);

How or what would be the best way to send the following XML as a string to my SoapClient?

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.micros.com/pos/les/TransactionServices">
    <SOAP-ENV:Body>
        <ns1:PostTransaction>
            <ns1:REQ>
                <ns1:RequestHeader>
                    <ns1:InterfaceVersion>3.0.7</ns1:InterfaceVersion>
                    <ns1:ClientName>TRANS_SERVICES</ns1:ClientName>
                </ns1:RequestHeader>    
                <ns1:CheckDetailEntries>
                    <ns1:MenuItem>
                        <ns1:ReferenceEntry>Pizza4</ns1:ReferenceEntry>
                        <ns1:Count>1</ns1:Count>
                        <ns1:Price>10.00</ns1:Price>
                        <ns1:ItemNumber>112001</ns1:ItemNumber>
                        <ns1:PriceLevel>1</ns1:PriceLevel>
                        <ns1:Seat xsi:nil="true"/>
                    </ns1:MenuItem>
                </ns1:CheckDetailEntries>
                <ns1:CheckHeaderRequest>
                    <ns1:CheckId>03:21:05.050505</ns1:CheckId>
                    <ns1:GuestCount>1</ns1:GuestCount>
                    <ns1:GuestInformation>
                    <ns1:ID>001</ns1:ID>
                    <ns1:FirstName>xxx</ns1:FirstName>
                    <ns1:LastName>xxx</ns1:LastName>
                    <ns1:Address1>xxx Rd</ns1:Address1>
                    <ns1:Address2>xx</ns1:Address2>
                    <ns1:Address3>xx</ns1:Address3>
                    <ns1:PhoneNum>xx</ns1:PhoneNum>
                    <ns1:UserText1>None</ns1:UserText1>
                    <ns1:UserText2>None</ns1:UserText2>
                    <ns1:UserText3>None</ns1:UserText3>
                    <ns1:GUID></ns1:GUID></ns1:GuestInformation>
                </ns1:CheckHeaderRequest>
                <ns1:OrderTypeNumber>1</ns1:OrderTypeNumber>
            </ns1:REQ>
        </ns1:PostTransaction>
    </SOAP-ENV:Body>        
</SOAP-ENV:Envelope>

Update/Resolution: Here is the code I used to extend the SOAP Client and send my raw Soap Envelope: My answer below

Community
  • 1
  • 1
Fostah
  • 2,947
  • 4
  • 56
  • 78
  • I'm confused - are you sending that XML to the SOAP service and it's not getting parsed or you have XML that you want to send inside the SOAP message? – enygma Mar 07 '12 at 20:31
  • I have XML I want to send in the soap message. When I send the data encoded in an associative array, the nodes loose their original order which breaks the request. An example: Inside CheckDetailEntries you can have MenuItem or Condiment tags. But to associate Condiments to MenuItems they must be in a certain order which is lost when I encode the XML. So I just need to send XML string to the method PostTransaction to process. – Fostah Mar 07 '12 at 21:15
  • Is there another way you could associate them? Relying on the order of the incoming XML seems a little fragile to me... – enygma Mar 07 '12 at 21:18
  • Unfortunately thats how this Micros TransactionServices works. All Condiments must follow the MenuItem that they are associated to. – Fostah Mar 07 '12 at 21:22

2 Answers2

6

Update/Resolution: Here is the code I used to extend the SOAP Client and send my raw Soap Envelope

Here is how I extended SoapClient:

<?php
class MySoapClient extends SoapClient {

    function __construct($wsdl, $options) {
        parent::__construct($wsdl, $options);
        $this->server = new SoapServer($wsdl, $options);
    }
    public function __doRequest($request, $location, $action, $version) 
    { 
        $result = parent::__doRequest($request, $location, $action, $version); 
        return $result; 
    } 
    function __myDoRequest($array,$op) { 
        $request = $array;
        $location = 'http://xxxxx:xxxx/TransactionServices/TransactionServices6.asmx';
        $action = 'http://www.micros.com/pos/les/TransactionServices/'.$op;
        $version = '1';
        $result =$this->__doRequest($request, $location, $action, $version);
        return $result;
    } 
}

// To invoke my new custom method with my Soap Envelope already prepared.
$soapClient = new MySoapClient("http://xxxx:xxxx/TransactionServices/TransactionServices6.asmx?WSDL", array("trace" => 1)); 
$PostTransaction = $soapClient->__myDoRequest($orderRequest,$op); 
?>

Also posted on pastie.org: http://pastie.org/3687935 before I turned this into the answer.

hakre
  • 193,403
  • 52
  • 435
  • 836
Fostah
  • 2,947
  • 4
  • 56
  • 78
4

For testing purposes, you can subclass SoapClient and override the __doRequest method - it receives the generated XML and you can pre-process it.

But better find what's going wrong with the XML encoding. You can use SoapVar and SoapParam instances to specify the exact way given object has to be represented. Those saved my life when namespaces had to be given

Maxim Krizhanovsky
  • 26,265
  • 5
  • 59
  • 89
  • What is happening is when my XML is being encoded to an associative array, it looses the order of the elements inside CheckDetailEntries. In my XML I have MenuItem,Condiment,MenuItem,Condiment. But when the XML is converted, it groups the [MenuItems][0] and [MenuItems][1] which then when decoded makes the order MenuItem,MenuItem,Condiment,Condiment which causes both condiments to be associated with the last MenuItem. I will look into SoapVar and SoapParam. Thanks! – Fostah Mar 07 '12 at 21:19
  • Would it be possible to send _soapCall with the function name and instead of sending arguments as an array can I send it an XML string instead? I can't figure out how to do it. Thanks! – Fostah Mar 08 '12 at 00:07
  • @Fostah as you've accepted answer obviously it helped you to debug / correct the program, but would you mind to post exactly what was the cause of the incorrect XML? – Maxim Krizhanovsky Mar 28 '12 at 20:15
  • 1
    I ended up extending my SoapClient and creating my own _doRequest method to allow me to send a formed Soap Envelope directly. Here is the working result http://pastie.org/3687935 – Fostah Mar 28 '12 at 21:21