Working PHP code for Apple-news to create article - php

UPDATE: Below code works for me. Hope it helps someone to figure out their problem.
After having several errors, it helped going back and looking at all possible error codes on Apple News Developer site.
Look at specific error numbers in your code and decide what might be wrong with it.
Follow the examples on the Apple News Developer site. Even though they are vague they do contain crucial information!
//set the timezone
date_default_timezone_set('UTC');
//get json to be sent
$raw = file_get_contents('article.json');
$eol = "\r\n";
$data = '';
$bound= '535e329ca936f79a19ac9a251f7d48f7';
$data='--'.$bound.$eol.
"Content-Type: application/json" . $eol.
"Content-Disposition: form-data; name=metadata" . $eol. $eol.
'{
"data": {
"isCandidateToBeFeatured": "false",
"isSponsored": false,
"isPreview": true
}
}' .$eol.
'--'.$bound.$eol.
"Content-Type: application/json" . $eol.
"Content-Disposition: form-data; filename=article.json; name=article.json".$eol.$eol.
$raw.$eol.
'--'.$bound.'--'.$eol.$eol;
//set variables
$http_method = 'POST';
$date = gmdate('Y-m-d\TH:i:s\Z');
$key = 'xxx';
$url = 'https://news-api.apple.com/channels/xxx/articles';
$secret = 'xxx';
//cannonical request
$canonical_request = $http_method . $url . $date. 'multipart/form-data; boundary=535e329ca936f79a19ac9a251f7d48f7' . $data;
//Signature
$secretKey = base64_decode($secret);
$hash = hash_hmac('sha256', $canonical_request, $secretKey, true);
$signature = base64_encode($hash);
$authHeader = "HHMAC; key=$key; signature=$signature; date=$date;";
$headers = array();
$headers[] = "Authorization: $authHeader";
$headers[] = "Accept: application/json";
$headers[] = "Content-Type: multipart/form-data; boundary=535e329ca936f79a19ac9a251f7d48f7";
$headers[] = "Content-Length: ".strlen($data);
//curl options
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
//get result
$server_output = curl_exec ($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo $status;
curl_close ($ch);
print_r(json_decode($server_output));

Your content type header should be Content-Type: application/json but the content type for authorization is just the value `application/json'.
Try to use that in the canonical request instead of the full header.

Your Content-type header is missing, add it like this:
$headers[] = $Content_Type;

Related

'CURLE_URL_MALFORMAT' but all the syntax seems to be ok

I have an issue with a cUrl. Recently, I have found that the problem is in the syntax of the curl, because when I dump the request I want to execute and put it in PostMan it works, but the function inside my code doesn't and returns 3: 'CURLE_URL_MALFORMAT'. For information my curl version is 7.79.1
I have tried some different approaches with CURLOPT_RETURNTRANSFER, CURLOPT_POST and etc, but it does not work...
Here is my function:
private function cUrl_CreateContactFastFood($merchant_token, $arr)
{
$status = "active";
$Contact_name = $arr["customerName"];
$Contact_email = '';
if($Contact_email=='') {
$Contact_email= 'FastFoodCustomer#ttt.com';
}
$Contact_phone = $arr["phoneNumber"];
$Contact_address = $arr["endAddressResolved"];
$url = 'http://dostavka-bg.com/api_services/insert_contact';
$curl_params = '?keys=f74192da825962d3b1c2b2aa616ab68b&merchant_token='.$merchant_token.'&name='.$Contact_name.'&email='.$Contact_email.'&phone='.$Contact_phone.'&address='.$Contact_address.'&status='.$status;
$ch = curl_init();
$headers = array(
'Accept: */*',
'User-Agent: ',
'Accept-Encoding: gzip, deflate, br',
'Host: dostavka-bg.com',
'Connection: keep-alive'
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, $url.$curl_params);
$data = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
}
Here is the solved problem:
private function cUrl_CreateContactFastFood($merchant_token, $arr)
{
$status = "active";
$Contact_name = $arr["customerName"];
$Contact_email = '';//$arr["customer"]["invoicing_details"]["company_address"];
if($Contact_email==''){
$Contact_email= 'FastFoodCustomer#ttt.com';
}
$Contact_phone = $arr["phoneNumber"];
$Contact_address = $arr["endAddressResolved"];
$url = 'http://dostavka-bg.com/api_services/insert_contact';
$curl_params = '?keys=f74192da825962d3b1c2b2aa616ab68b&merchant_token='.urlencode($merchant_token).'&name='.urlencode($Contact_name).
'&email='.urlencode($Contact_email).'&phone='.urlencode($Contact_phone).'&address='.urlencode($Contact_address).'&status='.urlencode($status);
$ch = curl_init();
$headers = array(
'Accept: */*',
'User-Agent: ',
'Accept-Encoding: gzip, deflate, br',
'Host: dostavka-bg.com',
'Connection: keep-alive'
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, $url.$curl_params);
curl_setopt($ch, CURLOPT_POST, 1);
$data = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
$info = curl_version();
curl_close($ch);
return true;
}
The URL you're passing includes several query string parameters, only some of which are shown in your example, but some of which probably include punctuation or other characters which aren't allowed in URLs. Those need to be correctly encoded by either:
Calling urlencode or rawurlencode on each parameter as you build up the query string.
Using http_build_query to format it all for you, rather than manually concatenating the parts.

PHP and Shopify API connection

I'm trying to learn the shopify api for a project. Tried a few pasted codes on their forum, adapting my code to theirs.
The documentation says to do the authentication this way, by providing the following:
https://{username}:{password}#{shop}.myshopify.com/admin/api/{api-version}/{resource}.json
{username} — The API key that you generated
{password} — The API password
{shop} - The name that you entered for your development store
{api-version} — The supported API version you want to use
{resource} — A resource endpoint from the REST admin API
I'm trying to do a GET request on all the orders made on the store.
/ info
$API_KEY = '75c89bf******ea919ce****7702';
$PASSWORD = '2061******82d2802**f***9403';
$STORE_URL = '*****-na-***-c***.myshopify.com';
$AUTHORIZATION = base64_encode($API_KEY . ':' . $PASSWORD);
$url = 'https://' . $API_KEY . ':' . $PASSWORD . '#' . $STORE_URL . '/admin/api/2020-01/orders.json';
$header = array();
$header[] = 'Accept: application/json';
$header[] = 'Content-Type: application/json';
$header[] = 'Authorization: Basic ' . $AUTHORIZATION;
$session = curl_init();
//options
curl_setopt($session, CURLOPT_URL, $url);
curl_setopt($session, CURLOPT_HTTPHEADER, $header);
curl_setopt($session, CURLOPT_GET, 1);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
//exec
$response = curl_exec($session);
curl_close($session);
print_r($response);
// error
if($response === false)
{
print_r('Curl error: ');
}
The code doesn't work at all, without any error code, completly blank, with only the first project echo showing.
I verified my API keys and they are working, I can insert them manually into chrome.
You don't need the header for authorization. Your code should like:
$API_KEY = '75c89bf******ea919ce****7702';
$PASSWORD = '2061******82d2802ff***9403';
$STORE_URL = 'porcao-na-sua-casa.myshopify.com';
$url = 'https://' . $API_KEY . ':' . $PASSWORD . '#' . $STORE_URL . '/admin/api/2020-01/orders.json';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$headers = array();
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE) //can check status code, requst successfully processed if return 200
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
Found the problem when I ran in terminal, did not install php-curl on this machine.
#Kshitij solution worked, just like mine, when curl was properly installed.
// Provide the required parameters like store url , endpoint etc.
function shopifyApiCall($STORE_URL ,$query = [], $endpoint, $API_KEY, $PASSWORD){
//API_Key : your API key, you can get it from your APP setup.
//Password : Your Access Token
$url = 'https://' . $API_KEY . ':' . $PASSWORD . '#' . $STORE_URL . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt ($ch, CURLOPT_POSTFIELDS, json_encode($query));
$headers = array();
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$error_number = curl_errno($ch);
$error_message = curl_error($ch);
curl_close($ch);
// Return an error is cURL has a problem
if ($error_number) {
return $error_message;
} else {
// No error, return Shopify's response by parsing out the body and the headers
$response = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
// Convert headers into an array
$headers = array();
$header_data = explode("\n",$response[0]);
$headers['status'] = $header_data[0]; // Does not contain a key, have to explicitly set
array_shift($header_data); // Remove status, we've already set it above
foreach($header_data as $part) {
$h = explode(":", $part);
$headers[trim($h[0])] = trim($h[1]);
}
// Return headers and Shopify's response
//return array('headers' => $headers, 'response' => $response[1]);changed headers
return array('headers' => $header_data, 'response' => $response[1]);
}
}

Converting command cURL to PHP - Stuck with passing POSTFIELD data

In an attempt to replicate the following cURL:
curl -X POST --header 'Content-Type: multipart/form-data' --header 'Accept: application/json' --header 'Authorization: Bearer XXXXXXXXXX-XXXXXXXXXXX' 'https://XXXXXXXXX.XXX.com/api/v3/assets/76c860cd184ae4adfa105d46135c9b27.json' -F 'name=fileupdate99.pdf' -F 'description=curlviaphp'
The purpose of the call is to update the two fields (name & description) at this specific end point.
I used https://incarnate.github.io/curl-to-php/ to get the bulk of the conversion. However, I appear to be stuck on passing the data.
From what I can tell, it looks like the -F flag is expected (also used to upload files) and I can't make a swap to -d (I tried running call in the command line and -d wasn't accepted).
<?php
$subdomain = "XXXXXXXX";
$name = "fileupdate4.pdf";
$description = "curlviaphp";
$auth = "XXXXXXXXXX-XXXXXXXXXXX";
$asset = "76c860cd184ae4adfa105d46135c9b27";
$ch = curl_init();
$curlurl = "https://" . $subdomain . ".XXX.com/api/v3/assets/" . $asset . ".json' ";
$variables = array(
"name" => $name,
"description" => $description,
);
curl_setopt($ch, CURLOPT_URL, $curlurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $variables);
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = "Content-Type: multipart/form-data";
$headers[] = "Accept: application/json";
$headers[] = "Authorization: Bearer " . $auth;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo "Error:" . curl_error($ch);
}
curl_close($ch);
echo $result;
?>
When I execute, the code runs and I get a blank page (no return and no change on the receiving end).
What am I missing?

cURL POST Request with Authorization

I'm trying to use cURL POST to get some data from an endpoint:
Here is what the documentation says to authenticate and get data:
"...uses a combination of OAuth2 grant_types and JWT tokens
To authorize, use this code:
curl -X POST \
'http://api.example.com/v1/api/auth/login?grant_type=client_id' \
-H 'Authorization: Basic cHVibGljX2tleTpwddl2YXRJX2xleQzd'
"
Based on the info above, I built this code for the request:
$handle = curl_init('http://api.example.com/v1/api/auth/login?
grant_type=client_id');
$header = array();
$header[] = 'Content-Type: application/json';
$header[] = 'Authorization: Basic DdJfd1Bxx2NxMkYwNjzzdl9mejJZIFKVQlBc';
curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $header);
$resp = curl_exec($handle);
var_dump($resp);
When I execute the code, it runs in an endless loop and eventually times out.
Is the format of the code correct or is it a problem with the authorization key I provided? The key is a Base64 representation.
Thanks!
UPDATE: I've tried the following also:
$header[] = 'Content-Type: application/json';
$header[] = 'Authorization: Basic adfsidfosfosfodsofs';
$content = "grant_type=client_id";
$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
maybe try this:
$handle = curl_init('http://api.example.com/v1/api/auth/login?grant_type=client_id');
$header = array();
$header[] = 'Content-Type: application/json';
$header[] = 'Authorization: Basic DdJfd1Bxx2NxMkYwNjzzdl9mejJZIFKVQlBc';
curl_setopt($handle, CURLOPT_HTTPHEADER, $header);
$resp = curl_exec($handle);
var_dump(curl_error($handle));

Force service to return json instead of default html

I want to be able to code in php the equivalent to this curl command:
curl -F out=json --form-string 'content=<!DOCTYPE html><html><head><title>check it</title></head><body></body></html>' http://validator.w3.org/nu/
This curl command returns json as expected.
Maybe I am missing something from their documentation here:
https://github.com/validator/validator/wiki/Service:-Input:-POST-body and https://github.com/validator/validator/wiki/Service%3A-HTTP-interface
The problem that I have now is that the web service returns html instead of json.
Although I am setting the header accept to json it does not work. I also tried to set both accept and Content-Type but this triggers an error from the web service saying non valid input. Here is the code that I need your help with:
$html = "<!DOCTYPE html><html><head><title>test</title></head><body></body></html>";
$endPoint = "http://validator.w3.org/nu/";
$timeout = 5000;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endPoint);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, $timeout);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json'));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
curl_setopt($ch,CURLOPT_POSTFIELDS, array('content' => $html, 'out' => 'json'));
$output = curl_exec($ch);
if(curl_errno($ch))
{
echo curl_error($ch);
}
curl_close($ch);
error_log(__FILE__. ": " . __LINE__ . ": " . var_export($output, true));
echo $output;
After reading Ignacio question I am updating with this information from w3c documentation page:
In their documentation they say the html string should be sent in http body and in their java library they are using this:
String response = null;
String source = "your html here";
HttpResponse<String> uniResponse = Unirest.post("http://localhost:8080/vnu")
.header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36")
.header("Content-Type", "text/html; charset=UTF-8")
.queryString("out", "gnu")
.body(source)
.asString();
response = uniResponse.getBody();
Could this be a hint for you? Just to let you know I tried both
http://validator.w3.org/nu/?out=json
and
http://validator.w3.org/nu/
endpoints (as value of $endPoint variable in php script above).
To get the result that you are looking for, you have to send your data as multipart/form-data (you can take a look on the validator page or the request sent by curl to see that data is sent as multipart/form-data ), for that take this example :
$url = 'http://validator.w3.org/nu/';
$html = '<!DOCTYPE html><html><head><title>test</title></head><body></body></html>';
$boundary = 'your-boundary';
$body = '--' . $boundary . "\r\n";
// set the "out" as "json"
$body .= 'Content-Disposition: form-data; name="out"' . "\r\n" . "\r\n";
$body .= 'json' . "\r\n";
$body .= "--" . $boundary ."\r\n";
// set the "content"
$body .= 'Content-Disposition: form-data; name="content"' . "\r\n" . "\r\n";
$body .= $html . "\r\n";
$body .= "--" . $boundary . "--" . "\r\n" . "\r\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data; boundary='.$boundary));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
echo curl_exec($ch);
curl_close($ch);
Then you'll get something like this :
{
"messages": [{
"type": "info",
"message": "The Content-Type was “text/html”. Using the HTML parser."
}, {
"type": "info",
"message": "Using the schema for HTML with SVG 1.1, MathML 3.0, RDFa 1.1, and ITS 2.0 support."
}],
"source": {
"type": "text/html",
"encoding": "utf-8",
"code": "<!DOCTYPE html><html><head><title>test</title></head><body></body></html>"
}
}
Hope that can help.

Categories