File upload using http request in Extbase, TYPO3 CMS - file-upload

We want to upload file using http request to some api endpoint in TYPO3 9.

File upload can be done using \TYPO3\CMS\Core\Http\RequestFactory in
TYPO3
$filePath = '/var/www/html/MyTypo3Project/Image.png';
$username = 'test';
$password = 'test';
$multipart = [
// File Parameter
[
'name' => 'Image', //Api side parameter name
'contents' => fopen(realpath($filePath), 'r'),
'filename' => 'MyCustomName.png' // Custom filename
],
//Other Parameters
[
'name' => 'custom_param',
'contents' => 'custom_param_value'
]
];
// Request options along with auth header
$additionalOptions = [
'auth' => [$username, $password],
'multipart' => $multipart,
];
$requestFactory = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\RequestFactory::class);
$response = $requestFactory->request(
$url, // Api Endpoint Url
'POST',
$additionalOptions // Passing the additional options
);

Related

How can I get the S3 bucket Object URL after pointing my subdomain?

I have created a AWS S3 bucket where I am storing PDF files. Now I am fetching the object URL properly like below:
https://bucketnametest.s3.amazonaws.com/sample.pdf.
Now, I have pointed the AWS S3 bucket URL to my custom subdomain. So, I can directly hit the browser with https://customdomain.com/sample.pdf and I am getting the PDF as well. But the problem is, I am not getting the object URL like "https://customdomaintest.com/sample.pdf". Can anyone help how to fetch the bucket object URL like "https://customdomain.com/sample.pdf".?
Using the below code, I am getting the object URL like "https://bucketname.s3.amazonaws.com/sample.pdf". But I want it like "https://customdomain.com/sample.pdf".
<?php
require 'vendor/autoload.php';
$s3 = new Aws\S3\S3Client([
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => [
'key' => "xxxxxxxxxxxxxxxx",
'secret' => "xxxxxxxxxxxxxxxxxxxx",
]
]);
$source = 'pdf/document91.pdf';
$uploader = new Aws\S3\MultipartUploader($s3, $source, [
'bucket' => 'bucketname',
'key' => "document91.pdf",
'Body' => "",
'ACL' => 'public-read',
]);
try {
$result = $uploader->upload();
echo "Upload complete: {$result['ObjectURL']}\n";
} catch (MultipartUploadException $e) {
echo $e->getMessage() . "\n";
}

Problem to upload file with from-param in Laravel 8 external api with guzzle or HTTP client

I am using Mirakl api. I faced an issue with the file upload with form-peram in Laravel 8 external api with guzzle or HTTP client.I got 400 Bad Request.The api expects file with from-param like this
{
"order_documents": [{
"file_name": String,
"type_code": String
}]
}
The documentation of my endpoint can be found from this link (http://185.29.149.41/eci/mir/doc/api/OR74.html) and here is my codes --
public function upload_order(Request $request)
{
$order_id = $request->order_id;
if ($files = $request->file('files')) {
$name = $files->getClientOriginalName();
Storage::disk('invoice')->put($name, file_get_contents($files->getRealPath()));
$path = Storage::disk('invoice')->path($name);
}
$file['order_documents'][] = [
'file_name' => $name,
'type_code' => $request->type_code,
];
$json = json_encode($file);
$data = [
['name' => 'order_documents','contents' => $json],
];
$data[] = [
'name' => 'files',
'contents' => mb_convert_encoding($path, 'UTF-8', 'UTF-8'),
'filename' => $name,
];
$body['multipart'] = $data;
$configApi = $this->configApi($this->getMarketplaceID($request->marketplace), auth()->user()->id);
$url = $configApi['url'].'/api/orders/'.$order_id.'/documents';
$client = new Client(['verify' => false]);
$response = $client->request(
'POST',
$url,
[
'multipart' => $data,
'headers' => $configApi['headers']
]);
return json_decode($response->getBody(), true);
}

Rest Unknown Error while uploading image on wordpress media using guzzle

Rest Unknown Error while uploading image on wordpress media using guzzle:
Actually m trying to upload image using guzzle but the wordpress is giving server error that rest upload unknown error ... Please tell what i am doing wrong???
public function store(Request $request)
{
//
$image_path = $request->file('image')->getPathname();
$image_mime = $request->file('image')->getmimeType();
$image_org = $request->file('image')->getClientOriginalName();
$username = '####';
$password = '#######';
$http = new \GuzzleHttp\Client;
$response = $http->POST('websitenameurl/wp2/wp-json/wp/v2/media/',
[
'headers'=>[
'Authorization'=> 'Basic ' . base64_encode( $username . ':' . $password),
'Content-Type' => 'Application/json'
],
'multipart' => [
[
'name' => 'image',
'filename' => $image_org,
'Mime-Type'=> $image_mime,
'contents' => fopen($image_path, 'r' ),
],
],
]);
$result = json_decode((string)$response->getBody(),true);
return $result;
}

How to call an API using raw input using Guzzle

I have an API which is working well with Postman but upon trying to call it in code, I get errors. See below
In Postman
Below is how I am calling the API in code:
In Code
public function pay_bill(Request $request){
$client = new Client(); //GuzzleHttp\Client
$username = 'xxxx';
$password = 'xxx#2020*';
$credentials = base64_encode("$username:$password");
$transaction_id = intval($request->input('transaction_id'));
$amount = (int)$request->input('amount');
$bill_number = (int)$request->input('bill_number');
$return_url = $request->input('return_url');
$response = $client->post('https://gatewaytest.e.com:5000/gateway/initialize', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Basic ' . $credentials,
'X-API-KEY' => '7c4a8d09ca3762af61e59520943dc26494f8941b',
],
'form_params' => [
'transaction_id' => $transaction_id,
'total_amount' => $amount,
'bills' => ["bill_ref" => $bill_number, "amount" => $amount],
'return_url'=> $return_url
],
'verify' => true
]);
$transaction_data = $response->getBody();
return $transaction_data;
}
What am I doing wrong? How do I send body as raw like is done in postman? I imagine the problem could be due to using form_params
I finally found the solution as shown below:
'bills' => [["bill_ref" => $bill_number, "amount" => $amount]]

API returning 400 Bad Request response

I have built an API and an application that uses that API. Everything was working but now, for some reason, I get a 400 Bad Request response. I am not sure if I changed something in the code so I wanted to double check it was correct.
So my API call is this
$client = new GuzzleHttp\Client();
$jsonData = json_encode($data);
$req = $client->request('POST', 'https://someurl.com/api/v1/createProject', [
'body' => $jsonData,
'headers' => [
'Content-Type' => 'application/json',
'Content-Length' => strlen($jsonData),
]
]);
$output = $req->getBody()->getContents();
The API has a route set up correctly which uses post. The function it calls is correct, and I have changed it for testing to simply return
return response()->json(["Success", 200]);
When I test the API out within Postman, I can see that Success is returned. When I test the API within the other application I have built, I dont even see a POST request within the console, I am just displayed a Laravel error 400 Bad Request.
What could be the cause of this issue?
Thanks
Update
I have changed the request to this
$data= json_encode($data);
$req = $client->post('https://someurl.com/api/v1/createProject', [
'body' => $data
]);
If I output $data after it has been encoded, I get something like this
{
"projectName":"New Project",
"clientName":"Test Client",
}
Within the controller function of the API that is being called, I simply do
return response()->json(['name' => $request->input('clientName')]);
The 400 error has now gone, but I now get null returned to me
{#326 ▼
+"name": null
}
Request is being injected into the function as it should be. Should I be returning the data in a different way?
Thanks
Probably you did $ composer update and Guzzle updated.
So if you are using newest Guzzle (guzzlehttp/guzzle (6.2.2)) you do POST request:
$client = new GuzzleHttp\Client();
$data = ['name' => 'Agent Smith'];
$response = $client->post('http://example.dev/neo', [
'json' => $data
]);
You do not need to specify headers.
To read response you do following:
$json_response = json_decode($response->getBody());
My full example (in routes file web.php routes.php)
Route::get('smith', function () {
$client = new GuzzleHttp\Client();
$data = ['name' => 'Agent Smith'];
$response = $client->post('http://example.dev/neo', [
'json' => $data,
]);
$code = $response->getStatusCode();
$result = json_decode($response->getBody());
dd($code, $result);
});
Route::post('neo', function (\Illuminate\Http\Request $request) {
return response()->json(['name' => $request->input('name')]);
});
or you could use following (shortened), but code above is "shorter"
$json_data = json_encode(['name' => 'Agent Smith']);
$response = $client->post('http://example.dev/neo', [
'body' => $json_data,
'headers' => [
'Content-Type' => 'application/json',
'Content-Length' => strlen($json_data),
]
]);
note: If you are running PHP5.6, change always_populate_raw_post_data to -1 (or uncomment the line) in php.ini and restart your server. Read more here.
In my case I was using public IP address in BASE_URL while I should have been using the private IP. From mac you can get your IP by going into system preferences -> network.
This is with Android + Laravel (API)