I'm using Laravel 5.4 and Guzzle to upload files and images to another server.
I am using the following method on the client/server side
public function store (Request $request)
{
$dataForm = $request->all();
$Client = new Client();
$response = $Client->post('http://localhost/WebService/public/api/client',
[
'multipart' =>
[
[
'name' => 'UploadIMG',
'filename' => 'image_org',
'Mime-Type' => 'image_mime',
'contents' => $ request->file('UploadIMG'),
],
]
]);
$ response = $ response-> getBody () -> getContents ();
return response () -> json (['error' => $ response]);
}
In the documentation part of the contents is 'contents' => fopen ('/ path / to / file', 'r') but I do not want to save the image but already get the request to be able to send, how is this possible?
the way I'm using comes a corrupted file in the web service.
I ran some tests with postman, so the problem is in the guzzle
With your current code for Guzzle, you're passing the $request->file('UploadIMG') which is an instance of Illuminate\Http\UploadedFile. For the 'contents' of the HTTP request, you need to pass the actual file itself into it.
Because the UploadedFile eventually extends SplFileInfo, my guess is to use its method of $request->file('UploadIMG')->openFile(). If you can't read it from there, then my second guess would be to save it temporarily then read that.
Related
Any Idea how to edit pictures on Cloudinary using Laravel API? I did a lot of searches, but I didn't find any references. The add worked successfully, but I didn't find a solution for the edit.
Add code
$user->user_image = Cloudinary::upload(
$request->file('user_image')->getRealPath(),
[
'folder' => 'Testing'
]
)->getSecurePath();
Attempt at updating picture
public function updatePicture(Request $request, $user_id)
{
$data = $request->validate([
'user_image' => '',
]);
$data = Cloudinary::upload(
$request->file('user_image')->getRealPath(),
[
'folder' => 'Testing'
]
)->getSecurePath();
User::where("user_id", $user_id)->update($data);
return response()->json([
'message' => 'Successfully updated Picture!',
'success' => true,
], 200);
}
For deleting, you can use the destroy() method of the API, for example:
$result = Cloudinary::destroy(
$public_id, //Public ID of the file from Cloudianry to delete - returned from the Upload API response
[
'...' => '...' //any optional parameters
]
)
For a list of all optional parameters and possible values please see:
https://cloudinary.com/documentation/image_upload_api_reference#destroy_method
In terms of updating, I am assuming you are referring to Cloudinary's update details of a single resource method of the Admin API. If so, you can access it like so:
$admin_api = Cloudinary::admin();
$result = $admin_api->update($public_id, $options = []);
Alternatively, if you're referring to the explicit method of the Upload API then you could access it like so:
$result = Cloudinary::explicit($public_id, $options = []);
I'm using Guzzle 7 to grab content from an external API with basic authentication. It works fine. Now I'd like to integrate cache management. So i've tried to use this plugin: [Guzzle-cache-middleware][1] and I can't make it working correctly. I can get API response and my desired content but the cache directory is not populated.
I've searched all around the web but I can't figure this out. Could you please tell me how to solve this? Here is my code:
$userName = "xxxxxxx";
$password = "yyyyyyyyyyy";
require_once './vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Kevinrob\GuzzleCache\CacheMiddleware;
use Kevinrob\GuzzleCache\Strategy\PublicCacheStrategy;
$stack = HandlerStack::create();
$cache = new CacheMiddleware();
$stack->push($cache, '/home/xxxx/xxxxx/guzzle2/cache');
$client = new Client([
'handler' => $stack,
'base_uri' => 'https://api.xxxxx.com/xxx/',
"timeout" => 30.0,
]);
$json = $client->get('zzzzzz.json', [
'auth' => [
$userName,
$password
]
]);
var_dump($json->getHeaderLine(CacheMiddleware::HEADER_CACHE_INFO));
Output:
string(4) "MISS"
So API result is different from cache. But headers params (ETag and Last-Modified) are still unchanged and my cache folder is still blank.
Thank you for your help!
Phpunit, Laravel 5.5
How do I emulate, not fake, an actual file upload with phpunit and Laravel. My latest stab at it is like this. From the unit test:
$handle = fopen($path,'r');
$content = fread($handle,2048);
fclose($handle);
$fdata = [
'delimiter' => '3',
'id' => 1,
'allow_shared_roles' => 'on',
'file'=>$name
];
$this->call('POST','/event/add-wizard/2',$fdata,[],[],[
'Content-Length'=>strlen($content),
'Content-Type'=>'multipart/form-data;boundary='.$content,
'Content-Disposition'=>'form-data;name="file";filename="'.$name.'"'
],$content);
Then on the server side, this is where I get hung up.
if ($request->hasFile('file')) {
$input['extension'] = strtolower($request->file('file')->getClientOriginalExtension());
}
$validator = \Validator::make($input, ['file' => 'required', 'extension' => 'in:csv', 'delimiter' => 'required'], ['extension.in' => 'The file must be a .csv file.']);
if ($validator->fails()) {
return \Redirect::back()->withInput()->withErrors($validator);
}
if (!file_exists(storage_path('temp-files'))) {
\File::makeDirectory(storage_path('temp-files'));
}
$date = \Carbon\Carbon::now();
$tmpFile = $request->file('file')->move(storage_path('temp-files'), $date->format('YmdHis') . '_' . $request->file('file')->getClientOriginalName());
Then I get move on null error on the last line shown.
Having never done this kind of thing before I admit I'm stabbing in the dark. Any help would be greatly appreciated.
After confirming in the comments that you want to check if the upload routine is being followed instead really uploading a file you can mock the facade File to see if the methods are called and with the right parameters (optional).
To mock a Facade in Laravel you can use the build in shouldReceive('method_name') method. In your situation you can add this before the call:
// should create new directory
File::shouldReceive('makeDirectory')
->once();
// should move the uploaded file to the dir
File::shouldReceive('move')
->once()
->andReturn( $fake_file );
You can read more about mocking facades here.
I'm trying to automate a file download in headless chrome using Laravel/Dusk.In GUI mode,the file downloads just fine in my download folder.But in headless mode,the download does not take place at all.Is there any way to solve this issue?
For those who come across this, I found a simple solution with the current version of Laravel at the time of writing this.
I suggest first creating a directory in your storage path called temp (probably want to gitignore this too), and then navigate to the DuskTestCase.php file setup with the Dusk installation.
Under the driver method, add the following under the section that initializes the ChromeOptions variable.
$options->setExperimentalOption('prefs', [
'download.default_directory' => storage_path('temp')
]);
The driver function should now look like this:
$options = (new ChromeOptions())->addArguments([
'--disable-gpu',
'--headless',
'--window-size=1920,1080'
]);
$options->setExperimentalOption('prefs', [
'download.default_directory' => storage_path('temp')
]);
return RemoteWebDriver::create(
'http://localhost:9515',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options
)
);
As a side note, this worked for me with a PDF file created via JS, so I can't definitively say how this works with a file downloaded from the back-end.
public function testDownload($account){
$this->browse(function (Browser $browser) {
$download_path = storage_path('your/download/path');
$url = $browser->driver->getCommandExecutor()->getAddressOfRemoteServer();
$uri = '/session/' . $browser->driver->getSessionID() . '/chromium/send_command';
$body = [
'cmd' => 'Page.setDownloadBehavior',
'params' => ['behavior' => 'allow', 'downloadPath' => $download_path]
];
(new \GuzzleHttp\Client())->post($url . $uri, ['body' => json_encode($body)]);
// Start your test
$browser->visit("http://example.com/export")
//your asserts here
}
It's not necessary to trigger a separate Guzzle POST, I used a CustomWebDriverCommand instead:
$command = new \Facebook\WebDriver\Remote\CustomWebDriverCommand(
$driver->getSessionID(),
"/session/:sessionId/chromium/send_command",
"POST",
[
"cmd" => "Page.setDownloadBehavior",
"params" => ["behavior" => "allow", "downloadPath" => '/your/download/path']
]
);
$driver->getCommandExecutor()->execute($command);
I am trying to make a http post request in laravel as below
$client = new Client(['debug'=>true,'exceptions'=>false]);
$res = $client->request('POST', 'http://www.myservice.com/find_provider.php', [
'form_params' => [
'street'=> 'test',
'apt'=> '',
'zip'=> 'test',
'phone'=> 'test',
]
]);
It return empty response. On debugging ,following exception is occurring
curl_setopt_array(): cannot represent a stream of type Output as a STDIO FILE*
I am using latest version of guzzle.
Any idea how to solve it?.
The request() method is returning a GuzzleHttp\Psr7\Response object.
To get the actual data that is returned by your service you should use:
$data = $res->getBody()->getContents();
Now check what you have in $data and if it corresponds to the expected output.
More information on using Guzzle Reponse object here
I had to do this
$data = $res->getBody()->getContents();<br>
but also change<br>
$client = new \GuzzleHttp\Client(['verify' => false, 'debug' => true]);<br>
to<br>
$client = new \GuzzleHttp\Client(['verify' => false]);
Here is what i did for my SMS api
use Illuminate\Support\Facades\Http; // Use this on top
// Sample Code
$response = Http::asForm()
->withToken(env('SMS_AUTH_TOKEN'))
->withOptions([
'debug' => fopen('php://stderr', 'w') // Update This Line
])
->withHeaders([
'Cache-Control' => 'no-cache',
'Content-Type' => 'application/x-www-form-urlencoded',
])
->post($apiUrl,$request->except('_token'));