Change format of the output XML , generated from PHP SoapClient? - php

I am trying to create this :
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<AccessKey xmlns="http://eatright/membership" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Value>67a4ef47-9ddf-471f-b6d0-0000c28d57d1</Value>
</AccessKey>
</s:Header>
<s:Body>
<WebUserLogin xmlns="http://eatright/membership">
<loginOrEmail>1083790</loginOrEmail>
<password>thomas</password>
</WebUserLogin>
</s:Body>
</s:Envelope>
I created this PHP code
class ChannelAdvisorAuth
{
public $AccessKey ;
public function __construct($key)
{
$this->AccessKey = $key;
}
}
$AccessKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$url = "http://ws.eatright.org/service/service.svc?wsdl";
$client = new SoapClient($url, array("trace" => 1, "exception" => 0));
$auth = new ChannelAdvisorAuth($AccessKey);
$header = new SoapHeader("AccessKey", "Value", $AccessKey, false);
$client->__setSoapHeaders($header);
$result = $client->ValidateAccessKey();
echo "REQUEST:\n" . $client->__getLastRequest() . "\n";
The output of the above PHP code is :
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://eatright/membership" xmlns:ns2="AccessKey">
<SOAP-ENV:Header>
<ns2:Value>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</ns2:Value>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:ValidateAccessKey/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How to change the PHP code to output the XML as requested by web service provider?
How to replace the "SOAP-ENV" to "S"?
Is there is a way to remove the NS1 and NS2? and also adjust the whole format of the XML to meet the requirements? thanks

You don't need to worry about SOAP-ENV, ns1 or ns2 - they are just prefixes referring to the namespaces. As long as the full namespaces are correct, it's going to be alright.
I think the SOAP header should be made like this:
$access_key = new stdClass();
$access_key->Value = 'XXX';
$hdr = new SoapHeader('http://eatright/membership', 'AccessKey', $access_key);
$client->__setSoapHeaders($hdr);
I don't see a purpose of xmlns:i in the first example - there are no elements having XSI attributes.
I'm not sure what to do with the body. In your first example, there is a call to the WebUserLogin operation, while in your PHP code you are trying to call ValidateAccessKey.
Have you tried reading the WSDL file which is pointed by $url

Ok I found the problem and I will add it here in case someone looking for same issue.
$access_key = new stdClass();
$access_key->Value = 'xxxxxxxxxxxxxxxxxxx';
// Create the SoapClient instance
$url = "http://ws.eatright.org/service/service.svc?wsdl";
$client = new SoapClient($url, array("trace" => 1, "exception" => 0));
$hdr = new SoapHeader('http://eatright/membership', 'AccessKey', $access_key);
$client->__setSoapHeaders($hdr);
$soapParameters = array('loginOrEmail ' => $username, 'password' => $password);
$login = new stdClass();
$login->loginOrEmail='LoginID';
$login->password='Password';
$result = $client->WebUserLogin($login);

Related

Soap request working in SoapUI but not in Wordpress plugin

I've been searching around for a solution to my problem, but to no avail. I'm trying to send a soap request through a Wordpress plugin using the following:
function soapRequest($soapUsername, $soapNonce, $soapDateTime, $soapPassword) {
$wsdl = 'http://www.beautyfort.com/api/wsdl/v2/wsdl.wsdl';
$trace = true;
$exceptions = false;
$client = new SoapClient($wsdl, array('trace' => $trace, 'exceptions' => $exceptions));
// Must be a stdClass (and not an array)
$auth = new stdClass();
$auth->Username = $soapUsername;
$auth->Nonce = $soapNonce;
$auth->Created = $soapDateTime;
$auth->Password = $soapPassword;
$header = new SoapHeader('http://www.beautyfort.com/api/', 'AuthHeader', $auth);
$client->__setSoapHeaders($header);
$xml_array['TestMode'] = 'true';
$xml_array['StockFileFormat'] = 'JSON';
$xml_array['SortBy'] = 'StockCode';
try {
$response = $client->GetStockFile($xml_array);
}
catch (Exception $e) {
log_me("Error!");
log_me($e -> getMessage());
log_me('Last response: '. $client->__getLastResponse());
}
log_me('Last request: '. $client->__getLastRequest());
log_me($response);
}
This produces the following request:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.beautyfort.com/api/">
<SOAP-ENV:Header>
<ns1:AuthHeader>
<ns1:Username>joetest</ns1:Username>
<ns1:Nonce>htflFfIKM4</ns1:Nonce>
<ns1:Created>2019-02-09T10:13:51.000Z</ns1:Created>
<ns1:Password>NGFjYTJiNzJmOWY2MzBmY2M2MjJkNjg1MDgyMWRjMzQxOGY1YTNjYQ==</ns1:Password>
</ns1:AuthHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:GetStockFileRequest>
<ns1:TestMode>true</ns1:TestMode>
<ns1:StockFileFormat>JSON</ns1:StockFileFormat>
<ns1:SortBy>StockCode</ns1:SortBy>
</ns1:GetStockFileRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And I get an invalid credentials error. I've also been testing in SoupUI and the following request works:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:api="http://www.beautyfort.com/api/">
<soapenv:Header>
<api:AuthHeader>
<api:Username>joetest</api:Username>
<api:Nonce>tJrsRlQt6i</api:Nonce>
<api:Created>2019-02-06T23:34:11.000Z</api:Created>
<api:Password>ZTBhMmE5OGY4YTNlZWIzZTE0ZTc2ZjZiZDBhM2RhMjJmNzAxNzYwZA==</api:Password>
</api:AuthHeader>
</soapenv:Header>
<soapenv:Body>
<api:GetStockFileRequest>
<api:TestMode>true</api:TestMode>
<api:StockFileFormat>JSON</api:StockFileFormat>
<!--Optional:-->
<api:FieldDelimiter>,</api:FieldDelimiter>
<!--Optional:-->
<api:StockFileFields>
<!--1 or more repetitions:-->
<api:StockFileField>StockCode</api:StockFileField>
<api:StockFileField>Category</api:StockFileField>
<api:StockFileField>Brand</api:StockFileField>
<api:StockFileField>Collection</api:StockFileField>
<api:StockFileField>Category</api:StockFileField>
</api:StockFileFields>
<api:SortBy>StockCode</api:SortBy>
</api:GetStockFileRequest>
</soapenv:Body>
</soapenv:Envelope>
Now the only differences I can see (apart from the optional fields) is the names of the namespace, and the use of the Xml tag at the top of the request. Both of these shouldn't matter right? I'd really appreciate your help on this as I've been scratching my head for ages.
Thank you in advance!
Your perfect just need to set UTC timezone and secret format like below:
base64 encoded(sha1(Nonce . Created . Secret))

SOAP-ERROR: Encoding: object has no 'ACCION' property

I have a PHP script which calls a web service created in SAP, I already validated it with soapui5 and it works fine, but PHP throws the following message:
SOAP-ERROR: Encoding: object has no 'ACCION' property
PHP code :
$url = 'https://www.ceramicaitalia.com/wssap/zwebservice1.wsdl';
$client = new SoapClient($url);
echo PHP_EOL;
$xmlr = new SimpleXMLElement("<ZWS_WEBSERVICE1></ZWS_WEBSERVICE1>");
$xmlr->addChild('login', '***');
$xmlr->addChild('password', '******');
$xmlr->addChild('ACCION', '/');
$params = new stdClass();
$params->xml = $xmlr->asXML();
$client->ZWS_WEBSERVICE1($params);
$result = $client->ZWS_WEBSERVICE1('RTA');
print_r($result);
Test in soapui5 :
Request :
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:urn="urn:sap-com:document:sap:rfc:functions">
<soap:Header/>
<soap:Body>
<urn:ZWS_WEBSERVICE1>
<ACCION>/</ACCION>
</urn:ZWS_WEBSERVICE1>
</soap:Body>
</soap:Envelope>
Response :
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header/>
<env:Body>
<n0:ZWS_WEBSERVICE1Response xmlns:n0="urn:sap-com:document:sap:rfc:functions">
<RTA>1.5</RTA>
</n0:ZWS_WEBSERVICE1Response>
</env:Body>
</env:Envelope>
You don't need to set root element. You can to xml as array param. Library will auto set matched elements. If you have multiple element with same name but different namespace you can check SoapVar. Working sample is below.
<?php
$url = 'https://www.ceramicaitalia.com/wssap/zwebservice1.wsdl';
$client = new SoapClient($url, ['trace' => true]);
$params = ['ACCION' => '/'];
$client->ZWS_WEBSERVICE1($params);
$result = $client->ZWS_WEBSERVICE1('RTA');
print_r($result);
?>

How to set this soap header on a SOAP CALL PHP?

<SOAP-ENV:Header>
<Seguridad>
<usuario>0000000000</usuario>
<password>9FDBDE265822755C50dHD5D33B61580736ECB94978BC40DDD2D4220CB63FE7E</password>
<fechaSistema>02/01/2015</fechaSistema>
</Seguridad>
</SOAP-ENV:Header>
I need to add this header to the soap call, but, the examples that I found need some namespace, and result so different of this.
I used NuSoap.php
$wsdl = "https://www.convolmiscelaneapruebas.pemex.com/ServiciosCVWEB/ServicioEnviaCONVOLService/ServicioEnviaCONVOLService.wsdl";
$client = new nusoap_client($wsdl,TRUE);
$header =
"<Seguridad>
<usuario>0001250000</usuario>
<password>4e671bf08913dn8k09d6359262117c8e67a5507b165f727288a487040bf2a1780</password>
<fechaSistema>02/01/2015</fechaSistema>
</Seguridad>";
$operation = array('arg0' => '2012-08-25',
'arg1' => '11:48:46',
'arg2'=>'12095866a6l9b7dbcd44640189c57hlZ5918192739040eb52ba5b==',
'arg3'=>'ZmU5866axMzc3ZDQyJmdAyZjM2YTc57Db7dbcd446401YTM1Mg3Ng=='
);
$client->setHeaders($header);
$res = $client->call('enviaCONVOL',$operation);

How do I make this exact soap call?

To start off with, I am a beginner at soap.
I am trying to make a soap call to a service and was given a working sample that comes from talend. What I need is to make a similar call in PHP.
The output from talend is as follows, (extracted from the HTTP request)
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<root>
<request>
<username>a#a.com</username>
<password>md5sumlookalike</password>
<webservice>GetCust</webservice>
<refid>12343321</refid>
<message>reserv#123</message>
</request>
</root>
</soap:Body>
</soap:Envelope>
So I wrote a little bit of PHP as it works as a scripting language as well for where it will be called from. Trying to understand how to make a soap call I came up with this bit.
<?php
// Yes I know about the diffrent port issue here. So I wgeted and stored it for use next to script
# $soapClient = new SoapClient("http://123.123.123.123:8088/services", array("trace" => true));
$soapClient = new SoapClient("wsdl", array("trace" => true));
$error = 0;
try {
$info = $soapClient->__soapCall("invoke",
array
(
new SoapParam("a#a.com", "username"),
new SoapParam("md5sumish", "password"),
new SoapParam("GetCust", "webservice"),
new SoapParam("1234321", "refid"),
new SoapParam("reserv#123", "message")
)
);
} catch (SoapFault $fault) {
$error = 1;
echo 'ERROR: '.$fault->faultcode.'-'.$fault->faultstring;
}
if ($error == 0) {
print_r($output_headers);
echo 'maybe it worked\n';
unset($soapClient);
}
?>
I end up seeing the following in the HTTP request via wireshark. The server just does not know what to do with this and does not respond. I am unsure what/where I need to go from here.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://talend.org/esb/service/job">
<SOAP-ENV:Body>
<ns1:invokeInput>a#a.com</ns1:invokeInput>
<password>md5sumish</password>
<webservice>GetCust</webservice>
<refid>1234321</refid>
<message>reserv#123</message>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
So I have to ask is how to get rid of the ns1:invokeInput and make it username. Along with bring the rest of the format into line so the request looks like the output from talend?
Here is a working little script I did in php to call a talend tutorial service exported as soap:
//....
if (sizeof($_POST) > 0) {
$name = $_POST['name'];
$city = $_POST['city'];
$client = new SoapClient("http://192.168.32.205:8080/DirectoryService/services/DirectoryService?wsdl", array( 'trace' => 1));
$result = $client->runJob(array(
'--context_param',
'Name=' . $_POST['name'],
'--context_param',
'City=' . $_POST['city']
));
}
//...
Talend seems to be very "basic" regarding how parameters are given.
With this code it was working fine.

Using complex structure with SOAP

The problem is that I cannot succeed to send an array of class through SOAP to a specific web service that I cannot change his structure.
Here below you'll see the schema of the Soap function:
http://www.elyotech.com/share/yoni/forum/developpeznet-soap.jpg
Here you'll find the code I'm corresponding to it:
$s = new soapclient($URL_WEBSERVICE,array('wsdl'=>true,"trace"=>true));
$params = new stdClass();
$params->loginInfo = new stdClass();
$params->loginInfo->UserName = 'username';
$params->loginInfo->Password = 'password';
$params->loginInfo->LanguageCode = 'en';
$params->reservation = new stdClass();
$params->reservation->EmailRecipient2 = 'yonia#yopmail.com';
$params->reservation->EmailRecipient3 = 'yonia2#yopmail.com';
$params->reservation->FirstName = 'Yoni'
foreach($extras as $id=>$extra)
{
$params->Extras[$id]= new stdClass();
$params->Extras[$id]->SelectedExtra = new stdClass();
$params->Extras[$id]->ExtensionData = new stdClass();
$params->Extras[$id]->SelectedExtra->Amount = 1;
$params->Extras[$id]->SelectedExtra->ID = $extra;
}
Here is the SOAP request that is sent:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:CreateReservation>
<ns1:loginInfo>
<ns1:UserName>monusername</ns1:UserName>
<ns1:Password>monpass</ns1:Password>
<ns1:LanguageCode>en</ns1:LanguageCode>
</ns1:loginInfo>
<ns1:reservation>
<ns1:EmailRecipient2>yonia#yopmail.com</ns1:EmailRecipient2>
<ns1:EmailRecipient3>yonia2#yopmail.com</ns1:EmailRecipient3>
<ns1:FirstName>Yoni</ns1:FirstName>
</ns1:reservation>
</ns1:CreateReservation>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
In this Soap request, I cannot find the Extras array of objects.
Do you have any idea of how I should create my object in order to send it correctly?

Categories