How can I rename a webdav collection using Symfony Client? - php

I am using an http Client with Symfony. In this example I am creating a folder.
$client = HttpClient::create();
/* #var $response ResponseInterface */
$createFolder = $client->request('MKCOL', $filePath, [
'auth_basic' => [$user, $authKey],
]);
This works well.
Now I want to rename a folder:
$renameFolder = $client->request('MOVE', $filePath, [
'auth_basic' => [$user, $authKey],
]);
But what I cannot figure out is, where do I define the new folder name?

You seem to be accessing a Webdav server, from the MKCOL command.
If you want to use MOVE, the destination should be passed on a Destination header, as shown here.
With Symfony Http Client, the request would be something like:
$moveCollection = $client->request('MOVE', $collectionPath,
[
'auth_basic' => [$user, $authKey],
'headers' => [
'Destination' => $newCollectionPath
]
]
);

Related

Trying to use Laravel HTTP to upload a file to a 3rd party

I have the following Postman request for testing a third party API;
What I am trying to do is convert this into code using Laravel's HTTP class, the code i currently have is;
public function uploadToThridParty()
{
$uploadContents = [
'id' => 'this-is-my-id',
'fileUpload' => true,
'frontfile' => Storage::get('somefrontfile.jpg'),
'sideview' => Storage::get('itsasideview.png'),
];
$request = Http::withHeaders(
[
'Accept' => 'application/json',
]
);
$response = $request
->asForm()
->post(
'https://urltoupload.com/upload', $uploadContents
)
}
But every time I run this, the 3rd party API comes back with Invalid ID, even though if i use Postman with the same ID it works fine.
I cant seem to figure out where i am going wrong with my code;
As #Cbroe mention about attach file before sending post request you can make this like this example:
public function uploadToThridParty()
{
$uploadContents = [
'id' => 'this-is-my-id',
'fileUpload' => true
];
$request = Http::withHeaders(
[
'Accept' => 'application/json',
]
);
$response = $request
->attach(
'frontfile', file_get_contents(storage_path('somefrontfile.jpg')), 'somefrontfile.jpg'
)
->attach(
'sideview', file_get_contents(storage_path('itsasideview.png')), 'itsasideview.jpg'
)
->post(
'https://urltoupload.com/upload', $uploadContents
)
}
Also i think you need remove asForm method because it's override your header accept type to application/x-www-form-urlencoded that is way your exception is Invalid ID
Some third party API would require you to have the request with content type as multipart/form data
you can double check all the headers being pass on your postman request HEADERS tab and view on Hidden headers.
If you indeed need your request to be in multipart/form-data, You can use the multipart options of guzzle.
Although this doesnt seem to be on Laravel HTTP-Client docs, you can simply pass a asMultipart() method in your HTTP request
just check the /vendor/laravel/framework/src/Illuminate/Support/Facades/Http.php for full reference of HTTP client.
You can have your request like this.
public function uploadToThridParty() {
$uploadContents = [
[
'name' => 'id',
'contents' => 'this-is-my-id'
],
[
'name' => 'fileUpload',
'contents' => true
],
[
'name' => 'frontfile',
'contents' => fopen( Storage::path( 'somefrontfile.jpg' ), 'r')
],
[
'name' => 'sideview',
'contents' => fopen( Storage::path( 'itsasideview.jpg' ), 'r')
],
];
$request = Http::withHeaders(['Accept' => 'application/json']);
$response = $request->asMultipart()->post('https://urltoupload.com/upload', $uploadContents );
}

how to send a file to an external api in laravel job?

I want to upload an image from a mobile app and send that file to Laravel API then, I want to send that image to an external API for getting information from pictures. In the controller I have the following code:
public function processImage(Request $request): JsonResponse
{
$request->validate([
'image' => 'image|mimes:jpeg,jpg,png,gif'
]);
$file = $request->file('image');
$filePath = $file->store('temp');
ProcessImageJob::dispatch($filePath);
$jobStatusId = 1;
return response()->json(compact('jobStatusId'));
}
In ProcessImageJob I call the API like this:
$client = new Client();
$response = $client
->post($uploadUrl, [
'headers' => $this->authHeaders,
'multipart' => [
[
'name' => 'files',
'contents' => fopen($this->image, 'r'),
'headers' => [ 'Content-Type' => 'image/jpeg']
],
]
]);
$response = json_decode($response->getBody()->getContents(), true);
when I request, it gives in the queue terminal this error: fopen(temp/XLCeHZJqkmwtyIhJ75rgDNTbXIhrlmncsvqTvvkD.jpg): Failed to open stream: No such file or directory how to fix this error? I appreciate any help.
P.S: For Laravel app, I use sail for docker.

Error while POSTing file with GuzzleHTTP - part was null

I try to send the file via GuzzleHTTP from my application to external API, I make it like this:
public function storeImagesInAmazon(Request $request) {
$uploadFilePath = 'some/endpoint';
$file = $request->file('file');
$client = new Client();
$response = $client->request('POST', $uploadFilePath, [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'multipart/form-data',
],
'multipart' => [
[
'name' => 'file',
'contents' => $file
]
]
]);
$result = json_decode($response->getBody(), true);
return [
'hashedID' => $result['hashedID']
];
}
The error I get is:
Server error: POST some/endpoint resulted in a 500 Internal Server Error response:\n
Errorerror while processing file: Failed to process file: part was null
I tested it via Postman, adding key = 'file', value = 'some_file.pdf' in Body form-data, I am sure file is correct, I mean it isn't damaged, I tried to post different files large one, a small one, pdf or jpg/png.
But I still have this issue and I can't find a solution for this.
I found this solution Guzzle form_params not accepting array
what I'm trying to say is, you need $option as your next param like in that post
$response = $client->post('api', $options);
and that $option is where your headers or multipart or other options goes as per documentation. i already tried using $options and its worked in my case.

How to send data to CloudFlare API?

I'm trying to delete files from my CloudFlare cache using PHP. Using Guzzle I've done this:
$client = new \GuzzleHttp\Client;
$response = $client->delete('https://api.cloudflare.com/client/v4/zones/myzoneid/purge_cache', [
'query' => [
'files' => 'https://example.com/styles.css,
],
'headers' => [
'X-Auth-Email' => 'myemail',
'X-Auth-Key' => 'myapikey',
],
]);
But when I run this I get an error:
Client error: DELETE https://api.cloudflare.com/client/v4/zones/myzoneid/purge_cache?files=https%3A%2F%2Fexample.com/etc resulted in a 400 Bad Request response: {"success":false,"errors":[{"code":1012,"message":"Request must contain one of \"purge_everything\", \"files\", \"tags\" (truncated...)
I can't get it to work using Postman either. I put in the required headers and try to set a key of files or files[] with the URL but it doesn't work. I've also tried data with raw JSON as the value like {"files":["url"]} (along with a JSON content-type header) but get the same error. It thinks I'm not sending the files key.
The method for purge_cache is POST instead of DELETE (Source: https://api.cloudflare.com/#zone-purge-files-by-url).
The payload is not sent as 'query', but as 'json'.
Files should be an array, not a string.
So the correct syntax should be....
$client = new \GuzzleHttp\Client;
$response = $client->post('https://api.cloudflare.com/client/v4/zones/myzoneid/purge_cache', [
'json' => [
'files' => ['https://example.com/styles.css'],
],
'headers' => [
'X-Auth-Email' => 'myemail',
'X-Auth-Key' => 'myapikey',
],
]);

Default form_params for guzzle 6

Is there a way to globally add form_params to all requests with guzzle 6?
For example:
$client = new \GuzzleHttp\Client([
'global_form_params' => [ // This isn't a real parameter
'XDEBUG_SESSION_START' => '11845',
'user_token' => '12345abc',
]
]);
$client->post('/some/web/api', [
'form_params' => [
'some_parameter' => 'some value'
]
]);
In my ideal world, the post would have the result of array_merge-ing global_form_params and form_params:
[
'XDEBUG_SESSION_START' => '11845',
'user_token' => '12345abc',
'some_parameter' => 'some value',
]
I can see also wanting something like this for query or json
According to Creating a client you can set "any number of default request options" and on the GuzzleHttp\Client Source Code
$client = new Client['form_params' => [form values],]);
would apply your form_params to every request.
This could create issues with GET requests due to the Content-Type header being changed within Client::applyOptions. It would ultimately depend on server configuration.
If your intentions are to have the client make both GET and POST requests then you might be better served by moving the form_params into middleware. For example:
$stack->push(\GuzzleHttp\Middleware::mapRequest(function (RequestInterface $request) {
if ('POST' !== $request->getMethod()) {
// pass the request on through the middleware stack as-is
return $request;
}
// add the form-params to all post requests.
return new GuzzleHttp\Psr7\Request(
$request->getMethod(),
$request->getUri(),
$request->getHeaders() + ['Content-Type' => 'application/x-www-form-urlencoded'],
GuzzleHttp\Psr7\stream_for($request->getBody() . '&' . http_build_query($default_params_array)),
$request->getProtocolVersion()
);
});

Categories