File upload to Box from Drupal - drupal-8

The following is a curl request that uploads a file to Box.
curl -X POST https://upload.box.com/api/2.0/files/content \
-H "Authorization: Bearer <token>" \
-H "Content-Type: multipart/form-data" \
-F attributes='{"name":"Test.pdf", "parent":{"id":"123"}}' \
-F file=#test.pdf
I'm trying to do the same thing in code:
$contents = file_get_contents($uri);
$attributes = array(
'name' => $filename,
'parent' => array('id' => $folderId),
);
$options = array(
'attributes' => $attributes,
'file' => $contents,
'headers' => array(
'Content-Type' => 'multipart/form-data',
'Authorization' => 'Bearer '. $boxAccess->getToken()
)
);
$uri = 'https://upload.box.com/api/2.0/files/content';
$client = \Drupal::httpClient();
$response = $client->request('POST', $uri, $options);
But I get back a 400 Bad Request response from Box.
Any ideas on what is wrong with the code I'm using?

I have run into a similar issue. The solution was to not set the Content-Type manually on the request.
PR to add a note to the docs: https://github.com/guzzle/guzzle/pull/2860

Your $options array structure doesn't look quite right.
Drupal 8 uses the Guzzle HTTP library for HTTP requests by default. The Guzzle documentation has a section on structuring multi-part form data:
http://docs.guzzlephp.org/en/stable/quickstart.html#sending-form-files
And your attributes look like they are JSON encoded in your first example, so you may want to use json_encode($attributes) rather than the raw array.

Related

While trying to integrate a ZOHO API in my web site.Zoho API Call working in POST Man tool,but in code not working why?

Postman request working but Php curl request not working. I used Postman auto generated code.
Zoho API CAll -> https://accounts.zoho.com/oauth/v2/token in postman tool
Result -> as JSON
{
"access_token": "1000.0c**********************7.********8",
"api_domain": "https://www.zohoapis.com",
"token_type": "Bearer",
"expires_in": 3600
}
PHP code here from Postman tool
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://accounts.zoho.com/oauth/v2/token',
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 => array('refresh_token' =>
'1000.3ea1636f577f421e71220d53d84f1fa0.df6c6323fd404daa568d364b0367756e','client_id' => '1000.N13Y5EYD42USXIH88PHCFB22GRLPDH','client_secret' => 'eec6c737dac644256b53b58d9610614319997025f0','redirect_uri' => 'http://localhost:8080/plugins/thanthiarchival/home.html','grant_type' => 'refresh_token'),
CURLOPT_HTTPHEADER => array(
'Cookie: b266a5bf57=57c7a14afabcac9a0b9dfc64b3542b70; iamcsr=a8d8b288-7040-4873-b04b-306620bf8f81; _zcsr_tmp=a8d8b288-7040-4873-b04b-306620bf8f81'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>
This php-curl code is generated from postman tool.Kindly suggest something.
To help see what is going on in the PHP-CURL request and debug, try setting Curl to verbose:
curl_setopt_array($curl, array(
...
CURLOPT_VERBOSE => 1,
...
));
if add the following code my ssl certificate problem solved
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,

Send attachment from s3 bucket using Mailgun

Trying to send an email with inline images embed. Only the file is not located on the server it is in an S3 bucket. How can this be done? The standard API doesn't seem to be reading the images into the email.
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = "YOUR_DOMAIN_NAME";
$params = array(
'from' => 'Excited User <YOU#YOUR_DOMAIN_NAME>',
'to' => 'bob#example.com',
'subject' => 'Hello',
'text' => 'Testing some Mailgun awesomness!',
'html' => '<html>Inline image: <img src="cid:test.jpg"></html>',
'inline' => array(
array('filePath' => '/path/to/image.jpg'))
);
# Make the call to the client.
$result = $mgClient->messages()->send($domain, $params);
By using inline param you can send the images with the correct path.

How to send XML POST request with Guzzle to web service API using Laravel?

I am trying to post a request to my Web API, using Laravel Guzzle Http client. However, I am getting errors trying to post the request. The data I want to send is XML as the API controller is built in XML return format.
I have tried all sorts of methods to post the request with Guzzle but it is yet to work.
public function createProperty(Request $request)
{
$client = new Client();
$post = $request->all();
$create = $client->request('POST', 'http://127.0.0.1:5111/admin/hotel', [
'headers' => [
'Content-Type' => 'text/xml; charset=UTF8',
],
'form-data' => [
'Name' => $post['hotel_name'],
'Address' => $post['address'],
'Phone' => $post['phone'],
'Email' => $post['email'],
'Website' => $post['website'],
'Latitude' => $post['latitude'],
'Longitude' => $post['longitude'],
'Tags' => $post['tags'],
'Priority' => $post['priority'],
'Visible' => $post['visible'],
'Stars' => $post['stars'],
'Description' => $post['description'],
'Facilities' => $post['facilities'],
'Policies' => $post['policies'],
'ImportantInfo' => $post['important_info'],
'MinimumAge' => $post['minimum_age']
]
]);
//dd($create->getBody());
echo $create->getStatusCode();
echo $create->getHeader('content-type');
echo $create->getBody();
$response = $client->send($create);
$xml_string = preg_replace('/(<\?xml[^?]+?)utf-16/i', '$1utf-8', $create->getBody());
$xml_string = $create->getBody();
//dd($xml_string);
$hotels = simplexml_load_string($xml_string);
return redirect()->back();
}
I expected the result to POST to the web service and save data to database, but however I got the error "Client error: POST 'http://127.0.0.1:5111/admin/hotel' resulted in a '400 bad request' response. Please provide a valid XML object in the body
Rather than using post-data in the guzzle request, you need to use body:
$create = $client->request('POST', 'http://127.0.0.1:5111/admin/hotel', [
'headers' => [
'Content-Type' => 'text/xml; charset=UTF8',
],
'body' => $xml
]);
$xml will be the XML data you want to send to the API. Guzzle will not create the XML data for you, you'll need to do this yourself.
The XML data can be created using the DomDocument class in PHP.
If you are using Laravel 7+ this simple line should work very well
$xml = "<?xml version='1.0' encoding='utf-8'?><body></body>";
Http::withHeaders(["Content-Type" => "text/xml;charset=utf-8"])
->post('https://destination.url/api/action', ['body' => $xml]);

Yii2 Cookie not generating

I am trying to set the cookie but cookie is not getting saved. Below is what I have tried:
$cookies = Yii::$app->response->cookies;
$cookies->add(new \yii\web\Cookie([
'name' => 'abc',
'value' => 'xyz',
'expire' => time() + 86400 * 365,
]));
$cookies1 = Yii::$app->request->cookies;
if ($cookies1->has('abc'))
$cookieValue = $cookies1->getValue('abc');
echo 'value : '.$cookieValue;
echo '<pre>'; print_r($_COOKIE);
$cookieValue does not hold any value. Cookie isn't generated. What am I doing wrong?
Your code is fine. Your problem is that you are trying to set and then get the cookie in the same request.
Your browser has not yet received the response, so it has not had the chance to add the cookie before you try to read it out.
You just need to set and then fetch the cookie in separate requests:
public function actionSetCookie() {
$cookies = Yii::$app->response->cookies;
$cookies->add(new \yii\web\Cookie([
'name' => 'abc',
'value' => 'xyz',
'expire' => time() + 86400 * 365,
]));
echo 'Cookie set!';
}
public function actionGetCookie() {
$cookies1 = Yii::$app->request->cookies;
if ($cookies1->has('abc'))
$cookieValue = $cookies1->getValue('abc');
echo 'value : '.$cookieValue;
}
Set your cookie like this
$cookie = Yii::$app->response->cookies;
$cookie = new \yii\web\Cookie
([
'name' => 'abc',
'value' => 'xyz',
'expire' => time() + 86400 * 365,
]);
Yii::$app->getResponse()->getCookies()->add($cookie);
//check cookie is exist or not
if(Yii::$app->getRequest()->getCookies()->has('abc'))
{
// if exist then get cookie value
$username = Yii::$app->getRequest()->getCookies()->getValue('abc');
}
Just putting here my answer, as several time visited this question but could not find solution. I spent one whole day to solve it. So hope this answer will help someone.
In my case I've used axios package which sent request from frontend and I got response Set-Cookie in the header but not saved in the browser. So setting axios.defaults.withCredentials = true; solved my issue.

Batch upload multiple photos to multiple user accounts

I have an array that looks as follows:
$userImages = array(
'100000000000001' => array(
'..../image01.jpg',
'..../image02.jpg',
'..../image03.jpg',
),
'100000000000002' => array(
'..../image04.jpg',
'..../image05.jpg',
'..../image06.jpg',
),
);
which contains FB user ids as keys, and then an array of images to upload to each users account.
My upload code looks as follows:
/** #var FacebookSessionPersistence $facebook */
$facebook = $this->container->get('fos_facebook.api');
$facebook->setFileUploadSupport(true);
$count = 1;
foreach ($userImages as $userId => $images) {
$batch = array();
$params = array();
foreach ($images as $image) {
$request = array(
'method' => 'post',
'relative_url' => "{$userId}/photos",
'attached_files' => "file{$count}",
'access_token' => $this->getUserAccessToken($userId)
);
$batch[] = json_encode($request);
$params["file{$count}"] = '#' . realpath($image);
$count++;
}
}
$params['batch'] = '[' . implode(',', $batch) . ']';
$result = $facebook->api('/', 'post', $params);
return $result;
I've added user access tokens to each image, under access_token, but when $facebook-api() is called, I get the following back from Facebook:
Does anyone know why, I'm getting these errors? Am I adding the user access token in the wrong place?
The access_token had to be added to the $params associative array, in the root, not to each image item!
Your logic is good, but you need to put the access token inside the body for every individual request.
For example:
...
$request = array(
'method' => 'post',
'relative_url' => "{$userId}/photos",
'attached_files' => "file{$count}",
'body' => "access_token={$this->getUserAccessToken($userId)}",
);
...
Does anyone know why, I'm getting these errors? Am I adding the user access token in the wrong place?
Have you made sure, you’ve actually added access tokens at all, and not perhaps just a null value?
The error message does not say that you used a wrong or expired user access token, but it says that a user access token is required.
So I’m guessing, because you did not really put actual tokens into your separate batch request parts in the first place, then the fallback to your app access token occurs, and hence that particular error message.