I am currently building a routine that needs to download files from one specific Dropbox folder , send them to another server and then move them to another folder on Dropbox.
I am using the /files/move_batch API endpoint for Dropbox to do so.
Here are the params sent to the API to move multiples files (well I'm only trying to move one file right now as it's still not working) :
$params = array(
'headers' => array(
'method' => 'POST',
'content-type' => 'application/json; charset=utf-8',
),
'body' => json_encode(array(
'entries' => array(
'from_path' => self::$files[0],
'to_path' => '/Applications/Archives/' . substr(self::$files[0], strrpos(self::$files[0], '/') + 1),
),
'autorename' => true,
)),
);
But I keep getting the same error message :
Error in call to API function "files/move_batch": request body: entries: expected list, got dict
I don't know what the API means by a list or how it should be formated.
The entries value should be a list of dict, one per file you want to move, each one containing both a from_path and a to_path. Your code is supplying the entries value to be a single dict though. (In PHP you can make both lists and dicts using the array keyword.)
It's easier to see and work with when you break it into pieces. Here's a working sample that does that.
<?php
$fileop1 = array(
'from_path' => "/test_39995261/a/1.txt",
'to_path' => "/test_39995261/b/1.txt"
);
$fileop2 = array(
'from_path' => "/test_39995261/a/2.txt",
'to_path' => "/test_39995261/b/2.txt"
);
$parameters = array(
'entries' => array($fileop1, $fileop2),
'autorename' => true,
);
$headers = array('Authorization: Bearer <ACCESS_TOKEN>',
'Content-Type: application/json');
$curlOptions = array(
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($parameters),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_VERBOSE => true
);
$ch = curl_init('https://api.dropboxapi.com/2/files/move_batch');
curl_setopt_array($ch, $curlOptions);
$response = curl_exec($ch);
echo $response;
curl_close($ch);
?>
To move just one file using this batch endpoint, you would change that line to something like:
'entries' => array($fileop1),
Related
So i need to gain access to a web service containing some json, but to do so I was told to make use of PHP POST method to first log into the web service. I was giving an array with 3 types/values.
{
"Username":"user",
"password":"1234",
"LoginClient":"user"
}
I have been searching all day for a solution, but have come up short :(.
Any advice or push into a right direction would be much appreciated.
Hope I have explained this clearly enough.
you could do as follows:
$url = 'http://yourDomain.net/api/auth/';
$data = array('Username' => 'user', 'password' => '1234', 'LoginClient' => 'user');
$opts = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
)
);
$context = stream_context_create($opts); //Creates and returns a stream context with any options supplied in options preset.
$response = file_get_contents($url, false, $context);
var_dump($response);
Or you could read about CURL as another option to make POST requests.
I want to update a video using google api v3 and i get the error 400 Bad Request.
This is my code.
$url = 'https://www.googleapis.com/youtube/v3/videos?part=snippet&videoId='.$_GET['videoId'].'&access_token='.Session::get('access_token');
$params = array(
"id"=> $_GET['videoId'],
"kind"=> "youtube#video",
'snippet' => array(
"title"=> "I'm being changed.",
"categoryId"=> "10",
"tags"=> array(
"humanities",
"Harpham",
"BYU"
),
'description' => 'test!'
)
);
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'PUT',
'content' => http_build_query($params),
),
);
$context = stream_context_create($options);
$result = json_decode(file_get_contents($url, false, $context));
I think since you don't set all parameters inside snippet, that's giving an error. What you can do is, first getting that video with videos->list, then updating the field you are interested in and sending back the update request with the whole object back.
Here's an example also utilizing php client library: https://github.com/youtube/api-samples/blob/master/php/update_video.php
I am troubleshooting some problems with POSTing to a remote site, specifically the remote host never returns any data (empty string).
Before I try to troubleshoot anything else, I want to make sure the calling code is actually correct. The code is:
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: application/xml",
'timeout' => 60.0,
'ignore_errors' => true, # return body even if HTTP status != 200
'content' => $send_xml
)));
$response = trim(file_get_contents($this->bulk_service_url, false, $context));
All my questions belong to the "header" option and it's values, and how to correctly format it and write it. The PHP documentation, discussion below it and even stackoverflow research yield very inconsistent results.
1) do I have to include the Content-Length header, and if not, will PHP calculate it correctly? The documentation does not include it, but I've seen many people include it manually, is it then respected or overwritten by PHP?
2) do I have to pass the header option as a string, or an associative array? Manual says string, majority pass it as a string, but this comment says that if PHP was compiled with --with-curlwrappers option, you have to pass it as an array. This is very inconsistent behavior.
3) when passing as a string, do I have to include terminating \r\n characters? Especially when specifying just one header. Manual does not provide such an example, first comment on manual page does include it, second one does not, again, no clear rule on how to specify this. Does PHP automatically handle both cases?
The server is using PHP 5.3.
You should really store your headers within code as an array and finalize the preparation just prior to sending the request...
function prepareHeaders($headers) {
$flattened = array();
foreach ($headers as $key => $header) {
if (is_int($key)) {
$flattened[] = $header;
} else {
$flattened[] = $key.': '.$header;
}
}
return implode("\r\n", $flattened);
}
$headers = array(
'Content-Type' => 'application/xml',
'ContentLength' => $dl,
);
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => prepareHeaders($headers),
'timeout' => 60.0,
'ignore_errors' => true,
'content' => $send_xml
)));
$response = trim(file_get_contents($url, FALSE, $context));
Preparing context try to add:
ContentLength: {here_calculated_length} in 'header' key preceded with \r\n
"\r\n" at the end of 'header' key.
So it should look like:
$dl = strlen($send_xml);//YOUR_DATA_LENGTH
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: application/xml\r\nContentLength: $dl\r\n",
'timeout' => 60.0,
'ignore_errors' => true, # return body even if HTTP status != 200
'content' => $send_xml
)));
Just a little improvement of the suggestion by #doublejosh, in case it helps someone:
(use of array notation and one-liner lambda function)
$headers = [
'Content-Type' => 'application/xml',
'Content-Length' => strlen($send_xml)
];
$context = stream_context_create(['http' => [
'method' => "POST",
'header' => array_map(function ($h, $v) {return "$h: $v";}, array_keys($headers), $headers),
'timeout' => 60.0,
'ignore_errors'=> true,
'content' => $send_xml
]
]);
Sorry, I can only post 2 hyperlinks so I'm going to have to remove the http : //
Background
I'm, trying to convert the code here: https://github.com/RusticiSoftware/TinCan_Prototypes/blob/92969623efebe2588fdbf723dd9f33165694970c/ClientPrototypes/StatementIssuer/StatementIssuer.java
into PHP, specifically the makeRequest function. This code posts data to a Tin Can Compliant Learner Record Store.
The current version of my PHP code is here:
tincanapi.co.uk/wiki/tincanapi.co.uk:MediaWikiTinCan
The specification for the Tin Can API which everything should conform to is here:
scorm.com/wp-content/assets/tincandocs/TinCanAPI.pdf
There is also a working java script function that Posts data in the right format here (see the XHR_request function I think):
https://github.com/RusticiSoftware/TinCan_Prototypes/blob/92969623efebe2588fdbf723dd9f33165694970c/ClientPrototypes/GolfExample_TCAPI/scripts/TCDriver.js
I don't have access to the code or server that I'm posting to, but the end result should be an output here: beta.projecttincan.com/ClientPrototypes/ReportSample/index.html
Problem
I'm trying to use Curl to POST the data as JSON in PHP. Curl is returning 'false' but no error and is not posting the data.
On the recommendation of other questions on this site, I've tried adding 'json=' to the start of the POSTFIELDS, but since the Java and JavaScript versions does have this, I'm not sure this is right.
Can anybody suggest either how I might fix this or how I might get useful errors out of curl? My backup is to output the relevant JavaScript to the user's browser, but surely PHP should be able to do this server side?
Very grateful for any help.
Andrew
At least one thing is wrong: you should not be using rawurlencode on your Authorization header value.
Consider using php streams and json_encode() and json_decode() instead. The following code works.
function fopen_request_json($data, $url)
{
$streamopt = array(
'ssl' => array(
'verify-peer' => false,
),
'http' => array(
'method' => 'POST',
'ignore_errors' => true,
'header' => array(
'Authorization: Basic VGVzdFVzZXI6cGFzc3dvcmQ=',
'Content-Type: application/json',
'Accept: application/json, */*; q=0.01',
),
'content' => json_encode($data),
),
);
$context = stream_context_create($streamopt);
$stream = fopen($url, 'rb', false, $context);
$ret = stream_get_contents($stream);
$meta = stream_get_meta_data($stream);
if ($ret) {
$ret = json_decode($ret);
}
return array($ret, $meta);
}
function make_request()
{
$url = 'https://cloud.scorm.com/ScormEngineInterface/TCAPI/public/statements';
$statements = array(
array(
'actor' => array(
'name' => array('Example Name'),
'mbox' => array('mailto:example#example.com'),
'objectType' => 'Person',
),
'verb' => 'experienced',
'object' => array(
'objectType' => 'Activity',
'id'=> 'http://www.thincanapi.co.uk/wiki/index.php?Main_Page',
'definition' => array(
'name' => array('en-US'=>'TinCanAPI.co.uk-tincanapi.co.uk'),
'description' => array('en-US'=> 'TinCanAPI.co.uk-tincanapi.co.uk'),
),
),
),
);
return fopen_request_json($statements, $url);
}
list($resp, $meta) = make_request();
var_export($resp); // Returned headers, including errors, are in $meta
We've now released an open source library specifically for PHP, it uses a similar method as the accepted answer but rounds out the rest of the library as well. See:
http://rusticisoftware.github.io/TinCanPHP/
https://github.com/RusticiSoftware/TinCanPHP
I have a service that expects 2 objects... Authentication and Client.
Both are mapped correctly.
I am trying to consume them as Json, but I'm having a hard time doing that.
If I specify just one parameter it works fine, but how can I call this service passing 2 parameters? Always give me some exception.
Here is my rest service:
#POST
#Path("login")
#Consumes("application/json")
public void login(Authentication auth, Client c)
{
// doing something
}
And here is my PHP consumer:
$post[] = $authentication->toJson();
$post[] = $client->toJson();
$resp = curl_post("http://localhost:8080/login", array(),
array(CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
CURLOPT_POSTFIELDS => $post));
I tried some variations on what to put on CURLOPT_POSTFIELDS too but couldn't get it to work.
The problem you are probably having, is that you are declaring $post as a numbered array, which probably contains the array keys you are mapping. Basically, this is what you are giving it:
Array(
1 => Array(
'authentication' => 'some data here'
),
2 => Array(
'client' => 'some more data here'
)
)
When in reality, you should be creating the $post var like so:
Array(
'authentication' => 'some data here',
'client' => 'some more data here'
)
Try changing your code to something more like this (not optimal, but should get the job done):
$authentication = $authentication->toJson();
$client = $client->toJson();
$post = array_merge($authentication, $client);
$resp = curl_post("http://localhost:8080/login", array(),
array(CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
CURLOPT_POSTFIELDS => $post));