Generating and downloading a text file on the fly in Laravel - laravel

My data is stored in the database and I need to give it out of it in a text file. There is no point in creating a file on disk, but an attempt to generate a response with a file does not work. Found a way like this but it doesn't work ERR_INVALID_RESPONSE
$contents = 'My data from db';
$filename = 'example.txt';
return response()->streamDownload(function () use ($contents) {
echo $contents;
}, $filename);

In your route name the route with something reasonable like:
Route::get('filename.txt', [FooController::class, 'foo']);
And in your controller at foo() action:
$headers = [
'Content-Type' => 'application/plain',
'Content-Description' => 'File name',
];
$contents = 'My data from db';
return \Response::make($contents, 200, $headers);

Related

Laravel : I received song file "form-data" from one of API then i need to forward that file to another API. Any idea to forward?

Laravel project 1 controller how to forward file to API-2
Input::file('songFile')->move("/tmp", $newname);
i used this function and store tmp location then how to use this tmp location file and forward?
In order to post a file to API endpoint, you can follow the following code.
try{
$path = 'var/www/html/myproject/public/file.txt';//your file path
if (!empty($path) && file_exists($path)) {
$guzzleResponse = $client->post($api_url, [
'multipart' => [
[
'name' => 'file',// it is the name as specfied in the payload of api_url
'contents' => fopen($path, 'r')// or you can use file_get_contents()
]
],
'headers' => $headers
]);
}
if ($guzzleResponse->getStatusCode() == 200) {
$response = json_decode($guzzleResponse->getBody());// whatever you want to do with response
}
}catch(RequestException $e){
return $e; //You can also handle specific status codes here using eg $e->getResponse()->getStatusCode() == '400'
}
Also $headers can be like this
[
'Accept' => 'application/json',
'Authorization' => 'Bearer '. $userToken,
]
See more information in Guzzle

Path of the file stored in s3 does not match with provided - Using Laravel

I'm building a service to upload images with laravel and stored in a aws s3 bucket, this is the function responsible for store image.
public function fromUrl(Request $request)
{
$validator = Validator::make($request->all(), [
'files' => 'required|array|min:1',
'files.*' => 'string',
]);
if (!$validator->fails()) {
$paths = [];
foreach ($validator->validate()['files'] as $file) {
$url = config('services.s3.host') . Storage::disk('s3')->put('images/public', file_get_contents($file), 'public');
array_push($paths, $url);
}
return $paths;
} else {
throw new ValidateException([
'message' => $validator->errors()->toArray(),
'rules' => $validator->failed()
]);
}
}
The request body looks like this.
{
"files": [
"https://image-url-1",
"https://image-url-2"
]
}
I expect that the path returned when saving the image is something like this.
[
"https://my-bucket-url/images/public/random-name-for-image1",
"https://my-bucket-url/images/public/random-name-for-image2"
]
but instead I'm getting the following.
[
"https://my-bucket-url/1",
"https://my-bucket-url/1"
]
You are misusing put in your example.
Firstly the first parameter is the path plus filename and you have no filename random logic. The third parameter is options array.
$randomFileName = uniqid(rand(), true);
$path = 'images/public/' . $randomFileName;
Storage::disk('s3')->put($path, file_get_contents($file));
This code will save an element at images/public/$randomFileName. To return the proper path you can use the url() method.
$url = Storage::disk('s3')->url($path);
array_push($paths, $url);

Image is not saved/updated into database using Laravel

I am trying to save my image into database while creating my user and i am using postman for this
My Code:
public function register(Request $request) {
$body = $request->all();
$userProfile = $body['user_profile'];
$userPrev = $body['privileges'];
$userProfile['is_super_admin'] = $userPrev['is_super_admin'];
$facilities = $userPrev['facilities'];
$bodyObj = array_merge($userProfile, $userPrev);
$validator = UserValidations::validateUser($bodyObj);
if ($validator->fails()) {
return response([
'status' => false,
'message' => __('messages.validation_errors'),
'errors' => $validator->errors()->all()
], 200);
}
DB::beginTransaction();
try {
If (Input::hasFile('image')) {
$file = Input::file('image');
$destinationPath = public_path() . '/profile_images/';
$filename = $file->getClientOriginalName();
$file->move($destinationPath, $filename);
$this->user->where('id', Auth::user()->id)->update(['profile_pic' => $filename]);
}
My user is created and saved into database, but the image is not.
Your help will be highly appreciated!
I am really confused. You want to store image in database (bad Idea). Secondly, You want to store image in database but you are storing the file name only.
Suggetion : If you would like to store images in database you have an option to convert it into base64 and store the string. While retrieving you could decode base64. For example:
$file = Input::file('image');
$img_data = file_get_contents($file);
$base64 = $base64_encode($img_data);
$this->user->where('id', Auth::user()->id)->update(['profile_pic' => $base64 ]);
Another suggetion [Best way] : store path in the database and store the file in the storage or public and use the url to access the image
However if you still want to save it on database
$image = addslashes(file_get_contents(Input::file('image')));
$this->user->where('id', Auth::user()->id)->update(['profile_pic' => $image ]);

Laravel : Force the download of a string without having to create a file

I'm generating a CSV, and I want Laravel to force its download, but the documentation only mentions I can download files that already exist on the server, and I want to do it without saving the data as a file.
I managed to make this (which works), but I wanted to know if there was another, neater way.
$headers = [
'Content-type' => 'text/csv',
'Content-Disposition' => 'attachment; filename="download.csv"',
];
return \Response::make($content, 200, $headers);
I also tried with a SplTempFileObject(), but I got the following error : The file "php://temp" does not exist
$tmpFile = new \SplTempFileObject();
$tmpFile->fwrite($content);
return response()->download($tmpFile);
Make a response macro for a cleaner content-disposition / laravel approach
Add the following to your App\Providers\AppServiceProvider boot method
\Response::macro('attachment', function ($content) {
$headers = [
'Content-type' => 'text/csv',
'Content-Disposition' => 'attachment; filename="download.csv"',
];
return \Response::make($content, 200, $headers);
});
then in your controller or routes you can return the following
return response()->attachment($content);
A Laravel 7 approach would be (from the docs):
$contents = 'Get the contents from somewhere';
$filename = 'test.txt';
return response()->streamDownload(function () use ($contents) {
echo $contents;
}, $filename);
Try this:
// Directory file csv, You can use "public_path()" if the file is in the public folder
$file= public_path(). "/download.csv";
$headers = ['Content-Type: text/csv'];
//L4
return Response::download($file, 'filename.csv', $headers);
//L5 or Higher
return response()->download($file, 'filename.csv', $headers);

File download using Guzzle and Dropbox API on laravel

I'm trying to create a function that I can use to download a specified file to a local folder on my machine. The request is successful and I do receive the filedata, however, I can't figure out how to extract the and write it to the specified path. How can I do it ?
Here's my function :
public function dropboxFileTransfer()
{
$local = fopen('files/get.zip', 'r');
$file = $this->client->get('https://api-content.dropbox.com/1/files/auto/dropbox-sdk-php-1.1.5.zip', [
'headers' => [
'Authorization' => 'Bearer ' . \Session::get('dtoken'),
],
]);
$stream = Stream::factory($file->getBody()->__toString());
$dest = Stream::factory($local);
$dest->write($stream);
return 'ok';
}

Resources