SoapClient attributes on called function element - php

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
)
);

Related

PHP - SOAP API authentication

I encounter some problems when I try to call a method of api with authentication.
$auth = (object) array(
'user'=>'username',
'password'=>'password',
'company'=> 'companyname'
);
$url = 'https://webservices.gocadservices.com/NVS?wsdl';
$soap = new SoapClient('https://webservices.gocadservices.com/NVS?wsdl',$auth);
echo $soap->nop();
I get an error : The user parameter is empty or missing.
My question : How can I send a request xml like this :
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<xs:nvheader xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:nvcommand>
<xs:user>
username
</xs:user>
<xs:password>
mot de passe
</xs:password>
<xs:company>
companyname
</xs:company>
</xs:nvcommand>
</xs:nvheader>
</soapenv:Header>
</soapenv:Envelope>
I must have this structure so that the API SOAP will work.
Thanks.
You need to set a SOAP Header for this to work:
$nvcommand = (object)[
'user' => 'username',
'password' => 'password',
'company' => 'company'];
$authHeader = new SoapHeader('namespace','nvcommand', $nvcommand);
$soapClient = new SoapClient('http://localhost:44333/SoapService.com?wsdl', $soapOptions);
$soapClient->__setSoapHeaders($authHeader);
$return = $soapClient->__soapCall('HelloWorld',[]);
This will send a SOAP Header
<env:Header>
<ns2:nvcommand>
<user>username</user>
<password>password</password>
<company>company</company>
</ns2:nvcommand>
</env:Header>
along with the Request. The options array in the SoapClient ctor isnt used to pass auth information. Please refer to
https://www.php.net/manual/de/soapclient.construct.php

How to add attributes to elements when making request with SoapClient

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;

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;
}

SOAP Request using PHP SoapClient

I need to send the following SOAP request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dat="http://touricoholidays.com/WSDestinations/2008/08/DataContracts">
<soapenv:Header>
<dat:LoginHeader>
<dat:username>myUserName</dat:username>
<dat:password>myPassword</dat:password>
<dat:culture>en_US</dat:culture>
<dat:version>8</dat:version>
</dat:LoginHeader>
</soapenv:Header>
<soapenv:Body>
<dat:GetDestination>
<dat:Destination>
<dat:Continent>Europe</dat:Continent>
<dat:Country>Spain</dat:Country>
<dat:State></dat:State>
<dat:City>Madrid</dat:City>
<dat:Providers>
<dat:ProviderType>Default</dat:ProviderType>
</dat:Providers>
</dat:Destination>
</dat:GetDestination>
</soapenv:Body>
</soapenv:Envelope>
I am trying to achieve this using PHP's built in SoapClient Class. When I run the following code it says "Login failure please check user name and password." But I am very much sure that both the username and password are correct as the same values are being used in other applications.
I think the problem is in the code below. Could you please tell me what is the mistake ?
try{
$client = new SoapClient($soap_url, array("trace" => 1));
$ns = 'http://touricoholidays.com/WSDestinations/2008/08/DataContracts';
$auth = array(
'username' => 'myUserName',
'password' => 'myPassword',
'culture' => 'en_US',
'version' => '8',
);
$header = new SoapHeader($ns, 'LoginHeader', $auth);
$client->__setSoapHeaders($header);
$res = $client->__soapCall("GetDestination", array());
var_dump($res);
}
catch(Exception $e)
{
echo $e->getMessage();
}
you should definitively use a WSDL to php generator that still uses the native SoapClient class such as the PackageGenerator project. It simply generates the PHP SDK according to the WSDL. Then you only have to use the generated classes to construct and send your request. The response is then an object using the generated classes.

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