I wanted to consume Navision 2016 soap web services from either PHP or jquery.
I have tried this solution PHP with Dynamics NAV webservices
I have the following code for soap PHP:
<?php
if (extension_loaded('soap'))
{
// Request parameters :
// Exemple is a Nav Code unit GetSalesPrices, method GetPrice(CodPCustomerNo, CodPItemNo)
$NavUsername = "superUser";
$NavAccessKey = "passworddrowssap";
$CodeunitMethod = "CallMethod";
$params = array(
"employeeNo" => "CUSTOMER_1",
"leaveType" => "ITEM_1",
);
// SOAP request header
$url = "http://DESKTOP-H5GFAKH:7047/DynamicsNAV100/WS/MyCompany/Codeunit/webportals";
$options = array(
'authentication' => SOAP_AUTHENTICATION_BASIC,
'login' => $NavUsername,
'password' => $NavAccessKey,
'trace' => 1,
'exception' => 0,
);
try
{
$client = new SoapClient(trim($url), $options);
$soap_response = $client->__soapCall($CodeunitMethod, array('parameters' => $params));
echo "SOAP REQUEST SUCESS :";
var_dump($soap_response);
}
catch (SoapFault $soapFault)
{
echo "SOAP REQUEST FAILED :<br>";
var_dump($soapFault);
echo "Request :<br>" . htmlentities($soap_client->__getLastRequest()) . "<br>";
echo "Response :<br>" . htmlentities($soap_client->__getLastResponse()) . "<br>";
}
}
else
{
echo "Php SOAP extention is not available. Please enable/install it to handle SOAP communication.";
}
?>
With this I get:
SOAP-ERROR: Parsing WSDL: Couldn't load from
'http://DESKTOP-H5GFAKH:7047/DynamicsNAV100/WS/MyCompany/Codeunit/webportals'
: failed to load external entity
For starters, you can use POSTMAN and you can get the code that you should use. Having said that, see my code below. You don't have to use SoapClient, just use cURL in PHP. Make sure to use Basic Auth authentication in Navision. The below example is of a request to NAV to get a data from a NAV list
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://URL:PORT/WebService/WS/COMPANY%20NAME/Page/WebService",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS =>"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\">\n<Body>\n<Read xmlns=\"urn:microsoft-dynamics-schemas/page/WebService\">\n<No>" .$entry_no. "</No>\n</Read>\n</Body>\n</Envelope>",
CURLOPT_HTTPHEADER => array(
"Content-Type: text/xml; charset=utf-8",
"SoapAction: urn:microsoft-dynamics-schemas/page/WebService",
"Authorization: Basic " .base64_encode('username:password'). ""
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
$xml = simplexml_load_string($response, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
$xml->registerXPathNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('xmlns', 'urn:microsoft-dynamics-schemas/page/webservice');
$xmlinfo = $xml->xpath('Soap:Body');
User Wizdler from Chrome Store or Firefox extensions to enable you parse the WSDL and generate the SOAP messages.
For jQuery, you can use POSTMAN to generate the required code or you should consider using AJAX
Related
Whenever I use Postman to make a soap post request, I get back the desired data. Using Guzzle, no data is returned. Im new to SOAP and using the resources online to go along.
I have omitted the variables for ease of read.
$xml = (
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:app="<ACTION-URL>">
<soapenv:Body>
<app:' . $functionName . '>
<request>'
. $requestBody .
'<authentication>
<username>'. $authObject->username .'</username>
<password>'. $authObject->password .'</password>
<user_id>'. $authObject->userId .'</user_id>
<dealer_id>'. $authObject->clientBranchId .'</dealer_id>
</authentication>
</request>
</app:' . $functionName . '>
</soapenv:Body>
</soapenv:Envelope>'
);
private function makeSOAPRequest($xml)
{
$client = new \GuzzleHttp\Client();
$options = [
'headers' => [
'Content-Type' => 'text/xml; charset=utf-8'
],
'body' => $xml,
'Authenticate' => [env('USERNAME'), env('PASSWORD')]
];
$url = env('ROSETTA_API');
$promise = $client->requestAsync('POST', $url, $options);
$response = $promise->wait();
$xml = simplexml_load_string($response->getBody(),'SimpleXMLElement',LIBXML_NOCDATA);
if ($xml) {
$json = json_encode($xml);
return json_decode($json, true);
}
return false;
}
Calling makeSOAPRequest(..), I get back false. Using the same xml data in Postman, data is returned. Is there anything I've missed in the request header?
Edit to use cURL
// Copied from Postman:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://<URL>",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $xml,
CURLOPT_HTTPHEADER => array(
"Cookie: PHPSESSID=6419f1d96025a4a2c4d454de33fc6820"
),
));
$response = curl_exec($curl);
curl_close($curl);
return $response; // xml data in string format.
cUrl does work but not Guzzle. How to return as json? When I use simplexml_load_string, it's empty.
Try to use below parameters in your curl:
CURLOPT_SSL_VERIFYPEER => 1
CURLOPT_POST => true
// IF NEEDED
CURLOPT_HTTPAUTH => CURLAUTH_ANY
// IF NEEDED
CURLOPT_USERPWD => $soapUser.":".$soapPassword)
For Checking Error After curl_exec and before curl_close
if( curl_errno($ch) ){
print_r(curl_error($curl));
}
In add these headers in your header if needed:
"accept" => "*/*",
// IF NEEDED
"accept-encoding" => "gzip, deflate"
Add your request code in try catch block:
try{
//request code
}
catch(Exception $e){
print_r($e->getCode());
print_r($e->getMessage());
}
We are unable to make the HTTP POST request call to fetch the results and note that autherization type is AWS signature authorization.
In Drupal -8, we have tried with 'AWS connector' module but can not find the exact service for the HTTP POST request with the AWS signature authorization.
Notes:
I got some info on this at drupalize.me site.
<code>
$client = \Drupal::httpClient();
$request = $client->get('https://api.github.com/user', [
'auth' => ['username','password']
]);
$response = $request->getBody();
(Ref: https://drupalize.me/blog/201512/speak-http-drupal-httpclient)
</code>
The auth is for above is basic authentication. But I need for “AWS Signature”
We have tried the below curl code and not able to get the any result. Its showing the white blank screen without any errors.
<code>
$startTimestamp = time();
$amz = gmdate('Ymd\THis\Z', $startTimestamp);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api-runtime.us-east-1.amazonaws.com/endpoint",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\n\t\"campaignArn\":\"arn:aws:test:us-east-1:12456:campaign/test\",\n\t\"numResults\":2,\n\t\"userId\":\"400\"\n}",
CURLOPT_HTTPHEADER => array(
'"authorization: AWS4-HMAC-SHA256 Credential=**********/20191205/us-east-1/Test/aws4_request,
SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target,
Signature=' . $signature . '"',
'"cache-control: no-cache"',
'"content-type: application/json"',
'"host: test-runtime.us-east-1.amazonaws.com"',
'"x-amz-date:' . $amz . '"',
'"x-amz-target: getrecommendations"'
),
));
$result = curl_exec($curl);
if($result === false) {
echo "Error in cURL : " . curl_error($curl);
}
else {
echo 'no error'.$result;
}
Please check and share the valuable inputs / reference.
I have a question ..
My app gives me the following information:
HTTP + JSON
The following are sample HTTP requests and responses. The placeholders shown need to be replaced with actual values.
POST /json/reply/Zona
HTTP/1.1
Host: equatepro.azurewebsites.net
Content-Type: application/json
Content-Length: length
{"zonaId":0,"nombre":"String","creadoPor":"String","creadoFecha":"/Date(-62135596800000-0000)/","modificadoPor":"String","modificadoFecha":"/Date(-62135596800000-0000)/","estado":"String","nota":"String","borrar":false}
AND then
The following routes are available for this service:
POST /api/zonas
PUT /api/zonas/{zonaId}
enter image description here
enter image description here
I'm trying to communicate with my webservice using PUT method
My code
<?php
$pantalla="zonas";
%id =8;
$url= "http: //miapp.com /api/zonas/8".$pantalla ;
$url = $url ."/" . $id;
// complete url http://miapp.com/api/zonas/8
//build json
$ConstructorJson = array(
'ZonaId' => $Datos['txt_codigo'],
'Nombre' => $Datos['txt_Nombre'],
'CreadoPor' => $Datos['txt_CreadoPor'],
'CreadoFecha' => $Datos['txt_CreadoFecha'],
'ModificadoPor' => $Datos['txt_ModificadoPor'],
'ModificadoFecha' => $Datos['txt_ModificadoFecha'],
'Estado' => $Datos['cbo_Estado'],
'Nota' => $Datos['txt_Notas']
);
$json = json_encode($ConstructorJson);
$opts = array(
"http" => array(
"method" => "PUT",
"header" => "Accept: application/xml\r\n",
"content" => $json
)
);
$context = stream_context_create($opts);
$response = file_put_contents($url,'8',false,$context);
?>
Give me the following error
Warning: file_put_contents(http: //miapp .com/api/zonas/8): failed to open >stream: HTTP wrapper does not support writeable connections in C:\xampp\htdocs\Codigo2.0\models\zonas.model.php on line 34
and nothing happens.
I would rather connect using PHP curl.
$ConstructorJson = array(
'ZonaId' => $Datos['txt_codigo'],
'Nombre' => $Datos['txt_Nombre'],
'CreadoPor' => $Datos['txt_CreadoPor'],
'CreadoFecha' => $Datos['txt_CreadoFecha'],
'ModificadoPor' => $Datos['txt_ModificadoPor'],
'ModificadoFecha' => $Datos['txt_ModificadoFecha'],
'Estado' => $Datos['cbo_Estado'],
'Nota' => $Datos['txt_Notas']
);
$json = json_encode($ConstructorJson);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "http: //miapp.com/api/zonas/8/zonas",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => $json
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"Accept: application/xml\r\n",
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
HTTP wrapper does not support writeable connections - basically, PHP is telling you "Hey, you can't use this function to write to a file that lives on the internet. How do you expect me to write a file # http: //miapp .com/api/zonas/8? Not gonna happen".
I assume what you're trying to do is to send a PUT request # that location to update a zonas resource with ID 8.
Solution
Consider using a proper HTTP client that can send actual HTTP request methods and conform to the HTTP spec.
My personal favourite inside PHP is Guzzle -
http://docs.guzzlephp.org/en/stable/. Guzzle is a standalone package and can be downloaded from their site. You can use it in any PHP project - without or without a framework.
With Guzzle, you'd do something like the following:
$client = new GuzzleHttp\Client();
$json = json_encode($ConstructorJson);
$headers = [
"Accept" => "application/xml\r\n"
]
$request = new Request('PUT', $url, ['body' => $json, 'headers' => $headers]);
$client->send($request);
I finally solved the problem (thank you Kyle O'Brien)
Code
<?php
// web service url + tabla + id
$url = "mywebservice.com/zonas/8";
$Datos = $_POST;
//create a array with dates
$ConstructorJson = array(
'Nombre' => $Datos['txt_Nombre'],
'CreadoPor' => $Datos['txt_CreadoPor'],
'CreadoFecha' => $Datos['txt_CreadoFecha'],
'ModificadoPor' => $Datos['txt_ModificadoPor'],
'ModificadoFecha' => $Datos['txt_ModificadoFecha'],
'Estado' => $Datos['cbo_Estado'],
'Nota' => $Datos['txt_Notas']
);
//convert array to json
$json = json_encode($ConstructorJson);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => $json,
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Content-Type: application/json',
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
?>
I am trying to connect to an API which is based on JSON-RPC 2.0. As i am new to this im not sure if im coding this correctly because all I am recieving is an error.
Can anyone give me a brief explanation on how to connect to API in PHP?
<?php
header('Content-Type: application/json');
//check if you have curl loaded
if(!function_exists("curl_init")) die("cURL extension is not installed");
$url = 'xxxxxxxxx';
$data = array(
"operator_id" => "xxxx",
"login" => "xxxx",
"password" => "xxxx",
);
$curl_options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => 0,
CURLOPT_NOBODY => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_ENCODING => 'gzip,deflate',
CURLINFO_HEADER_OUT => true,
);
$ch = curl_init();
curl_setopt_array($ch, $curl_options);
$output = curl_exec($ch);
curl_close($ch);
$arr = json_decode($output,true);
echo ($output);
?>
The response i am recieving is this: {"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid request"},"id":null}
The response i should be recieving if successful login is: {"jsonrpc":"2.0","result":true,"error":null,"id":1,"ts":1368533487}
You're not sending a JSON-RPC request at all.
The request must be a JSON body, so you must json_encode the data before passing it to CURLOPT_POSTFIELDS.
The posted json must have the keys method, params, id, and jsonrpc (the last should be set to "2.0"). Your data would go into params. The id can be set to whatever, but without it you shouldn't get a response at all.
It is a quite simple format. See the specification at http://www.jsonrpc.org/specification
I am using the oauth library to use twitter API for sending the Direct Message to user using curl,but getting the "{"errors":[{"code":215,"message":"Bad Authentication data."}]}".
If i use terminal for curl then it works fine, but getting error while sending through PHP.
<pre>
<?php
error_reporting(1);
require("twitterOauth/autoload.php");
use Abraham\TwitterOAuth\TwitterOAuth;
$text = "Hello, How Are U?";
$headers = array(
'Authorization: OAuth oauth_consumer_key="OAuth oauth_consumer_key",
oauth_nonce="oauth_nonce",
oauth_signature="oauth_signature",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1439978004",
oauth_token="oauth_token",
oauth_version="1.0"'
);
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://api.twitter.com/1.1/direct_messages/new.json',
CURLOPT_POST => 1,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_POSTFIELDS => array(
'text' => urlencode($text),
'screen_name' => 'screen_name'
),$headers
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
print_r('Curl error: ' . curl_error($resp));
echo '<pre>'; print_r($resp); die;
// Close request to clear up some resources
curl_close($curl);
?>
</pre>