How to add attributes to elements when making request with SoapClient - php

I need to make a SOAP call and a request shoul look like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="xxxxxx">
<soapenv:Header/>
<soapenv:Body>
<soap:getOptions>
<arg0 username="?" password="?">
<getOptionsBusinessData/>
</arg0>
</soap:getOptions>
</soapenv:Body>
</soapenv:Envelope>
Is that possible with PHP SoapClient?
Tried many things all of which resulted in java nullpoint exception. Now I'm trying
$xml_string = '<getOptions>
<arg0 username="xxxx" password="xxxx">
<getOptionsBusinessData/>
</arg0>
</getOptions>';
$client = new \SoapClient('https://example.com?wsdl');
$args = array(new \SoapVar($xml_string, XSD_ANYXML));
$res = $client->__soapCall('getOptions', $args);
return $res;
Got different kind of error SoapFault Cannot find dispatch method for {}getOptions. I'm stuck! How do I unstuck?

Do not pass xml string as parameter. SoapClient is supposed to generate the XML for you. Try following call:
$client = new \SoapClient('https://example.com?wsdl');
$res = $client->getOptions(array('username' => 'xxx', 'password' => 'xxx'));
return $res;

Related

SoapClient attributes on called function element

How can I add attributes to the XML node of the soap method I call via SoapClient?
Long story ->
I want to get an authentication token from Zimbra via the SOAP API (https://files.zimbra.com/docs/soap_api/8.6.0/api-reference/zimbraAdmin/Auth.html). I can do it when I build the soap xml by myself
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:zimbra" xmlns:urn1="urn:zimbraAdmin">
<soapenv:Header>
<urn:context />
</soapenv:Header>
<soapenv:Body>
<urn1:AuthRequest name="'. $user .'" password="'. $password .'" />
</soapenv:Body>
</soapenv:Envelope>
But I can't get the name and password attributes as attributes on the AuthRequest (the soap endpoint I am calling) when using SoapClient:
$soap = new SoapClient(ZIMBRA_WSDL, array('trace' => true));
$result = $soap->authRequest(
array(
new SoapParam(ZIMBRA_ADMIN, 'account'),
new SoapParam(ZIMBRA_PASSWORD, 'password')
)
);
It produces always new child elements for AuthRequest whatever I'm trying.
Anybody can help?
I tried lot of recommendations w/o any success.
The problem was that there are two methods authRequest in different namespaces. I've changed the WSDL url to only retrieve the zimbraAdmin endpoint and then SoapClient was able to fill the request correct via:
$result = $soap->authRequest(
array(
'name' => $user,
'password' => $password
)
);

Building array for consuming complex wsdl - PHP

I am having some issues, and yes, i am probably out of my league, but I do this for learning.
I am trying to consume a SOAP service, and i cannot, for the life of me build an array that the server accepts.
WSDL is visible here:
http://metrolive.telenor.no/kapaks-facade-soap-web/services/KapaksFacade70SoapWrapper/wsdl
I can do this and it works perfectly fine:
$tlf = new SoapVar(
array(
new SoapVar(
array(
'ns2:connectionNumber' => 12345678,
'ns2:connectionNumberType' => "T",
'ns2:requestedProduct' => "OA"
), SOAP_ENC_OBJECT, null, null, null, 'http://web.soap.v70.kapaks.facade.metro2.telenor.com'
)
), SOAP_ENC_OBJECT, null, null, null, 'http://dto.common.v70.kapaks.facade.metro2.telenor.com'
);
$client = new SoapClient($kapaks_wsdl, $wsdl_options);
$result = $client->validateProductSoap($tlf);
This produces this xml: (From wireshark)
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org /soap/envelope/"
xmlns:ns1="http://web.soap.v70.kapaks.facade.metro2.telenor.com"
xmlns:ns2="http://dto.common.v70.kapaks.facade.metro2.telenor.com">
<SOAP-ENV:Header/><SOAP-ENV:Body><ns1:validateProductSoap><ns1:BOGUS>
<ns2:connectionNumber>12345678</ns2:connectionNumber>
<ns2:connectionNumberType>T</ns2:connectionNumberType>
<ns2:requestedProduct>OA</ns2:requestedProduct></ns1:BOGUS>
</ns1:validateProductSoap></SOAP-ENV:Body></SOAP-ENV:Envelope>
But, i need to request properties from the "address" node(Is it node?). I can not figure out how to map this into the array, i have been at this for days...
This XML works in curl: (Straigt from SoaP-UI)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:web="http://web.soap.v70.kapaks.facade.metro2.telenor.com"
xmlns:dto="http://dto.common.v70.kapaks.facade.metro2.telenor.com">
<soapenv:Header/>
<soapenv:Body>
<web:validateProductSoap>
<web:arg_0_0>
<dto:address>
<dto:houseLetter>A</dto:houseLetter>
<dto:houseNumber>12</dto:houseNumber>
<dto:municipalityNumber>0000</dto:municipalityNumber>
<dto:streetCodeType>V</dto:streetCodeType>
<dto:streetName>Street</dto:streetName>
</dto:address>
<dto:requestedProduct>OA</dto:requestedProduct>
</web:arg_0_0>
</web:validateProductSoap>
</soapenv:Body>
</soapenv:Envelope>
The curl approach gives me an xml response, but i need the array/object that soapclient produces, to be able to pass it to the front-end view.
How can i produce a soapclient request that will request what is inside the address tag? Or make an array/object that is identical to what soapclient delivers?
I made a workaround. At this point i don't care how its done, just that it is done. Still, if someone has the answer on how to do it the correct way, i would like to see it.
I am using nusoap thats is updated for newer php (https://github.com/econea/nusoap) , and i send raw xml with that.
function adresse($kmune1,$street1,$hnum1,$hletter1)
{
require '..\vendor\econea\nusoap\src\nusoap.php';
$endpoint = "http://user:pw#metrolive.telenor.no:80/kapaks-facade-soap-web/services/KapaksFacade70SoapWrapper";
$client2 = new nusoap_client($endpoint, false);
$client2->soap_defencoding = 'UTF-8';
$client2->decode_utf8 = false;
$XMLrequest = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://web.soap.v70.kapaks.facade.metro2.telenor.com" xmlns:dto="http://dto.common.v70.kapaks.facade.metro2.telenor.com">
<soapenv:Header/>
<soapenv:Body>
<web:validateProductSoap>
<web:arg_0_0>
<dto:address>
<dto:houseLetter>'.$hletter1.'</dto:houseLetter>
<dto:houseNumber>'.$hnum1.'</dto:houseNumber>
<dto:municipalityNumber>'.$kmune1.'</dto:municipalityNumber>
<dto:streetCodeType>V</dto:streetCodeType>
<dto:streetName>'.$street1.'</dto:streetName>
</dto:address>
<dto:requestedProduct>OA</dto:requestedProduct>
</web:arg_0_0>
</web:validateProductSoap>
</soapenv:Body>
</soapenv:Envelope>';
$result = $client2->send($XMLrequest, $endpoint, null);
$result=json_decode(json_encode($result));
return $result;
}

How to remove the “ser” prefix from SOAP request attributes in PHP

I'm trying to remove the 'ser' attribute from the following SOAP request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://localhost/server">
<soapenv:Header/>
<soapenv:Body>
<ser:eRoamingChargeDetailRecord>
<SessionID>?</SessionID>
</ser:eRoamingChargeDetailRecord>
</soapenv:Body>
</soapenv:Envelope>
I'd like it to look like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="localhost/blah">
<soapenv:Header/>
<soapenv:Body>
<eRoamingChargeDetailRecord xmlns:ns2="localhost/blah" xmlns="localhost/blah">
<SessionID>?</SessionID>
</eRoamingChargeDetailRecord>
</soapenv:Body>
</soapenv:Envelope>
However, when I remove this prefix manually, the server returns the following error:
Procedure 'eRoamingChargeDetailRecord' not present
The SOAP server is set up in PHP like so:
if (isset($_GET['wsdl'])) {
ini_set('soap.wsdl_cache_enabled', 0);
$soapAutoDiscover = new \Zend\Soap\AutoDiscover(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence());
$soapAutoDiscover->setBindingStyle(array('style' => 'document'));
$soapAutoDiscover->setOperationBodyStyle(array('use' => 'literal'));
$soapAutoDiscover->setClass('\\App\\Helpers\\Soap\\SoapFunctions');
$soapAutoDiscover->setUri('http://localhost/server');
$soapAutoDiscover->handle();
} else {
$soap = new \Zend\Soap\Server('http://localhost/server?wsdl', array("soap_version" => SOAP_1_1));
$soap->setObject(new \Zend\Soap\Server\DocumentLiteralWrapper(new \App\Helpers\Soap\SoapFunctions()));
$soap->handle();
}
}
And the function is:
/**
* This method takes ...
*
* #param string $SessionID
* #return string
*/
public function eRoamingChargeDetailRecord($SessionID) {
return "hello2 {$SessionID}";
}
How can I remove this ser prefix?
I've found similar questions on SO, but these are related to Java

Connecting to SOAP server with PHP

I am new to Soap and WSDLs. I am trying to replicate this example transaction using Soap in PHP.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:open="http://example.com/">
<soapenv:Header/>
<soapenv:Body>
<open:processEvent>
<authenticationToken>
<userName>1</userName>
<password>password1234</password>
</authenticationToken>
<sourceThirdPartyId>1</sourceThirdPartyId>
<dealerEndpointId>4</dealerEndpointId>
<eventType>GetAdvisorConfig</eventType>
<payload></payload>
<payloadVersion>STAR-5.5.4</payloadVersion>
</open:processEvent>
</soapenv:Body>
</soapenv:Envelope>
So far I am able to make a connection to the soap server, but am unsure how to insert the required variables.
$soapClient = new SoapClient("https://example.com?wsdl", array('soap_version' => SOAP_1_2,'trace' => 1 ));
echo("\nDumping client object functions:\n");
var_dump($soapClient->__getFunctions());
$response = $soapClient->__soapCall("processEvent",array("processEvent"=>"GetAdvisorConfig"));
echo("\nReturning value of __soapCall() call: ".$response);

SoapClient calling webservice

I am trying to call a SOAP based webservice. Following is the WSDL for my webservice
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:var="some_namespace">
<soapenv:Header/>
<soapenv:Body>
<var:SomeServiceRequest name="xxx" school="yyy" format="pdf" senderName1="aaa" />
</soapenv:Body>
</soapenv:Envelope>
Now I have tried all the possibilities to call this webservice using the SoapClient class in PHP. I am always getting 'Invalid XML' in response.
Following is the way seems the most obvious but I dont understand why its not working:
$soapclient = new SoapClient($this->getWSDLUrl(), array('trace' =>true,
'soap_version' => SOAP_1_2,
));
$headerbody = array('UsernameToken'=>array('Username'=>'someusername',
Password'=>'somepassword'));
$header = new SoapHeader('https://xxx/SoapConnector','Security',$headerbody);
$soapclient->__setSoapHeaders($header);
$oResponse = $soapclient->SomeService(array('name'=>'asd', 'school'=>'sdf','format'=>'asdf'));

Categories