Store and download a file from database using laravel - laravel

I would like on button press to download a file from database and at the same time to store it on server. There is the used code for download.
$objects = Obj::get()->toArray();
$time = Carbon::now();
$name = "Inventory_Snapshot_".$time;
$export_file = \Excel::create($name, function($excel) use ($objects) {
$excel->sheet("Objects", function($sheet) use ($objects)
{
$sheet->fromArray($objects);
});
});
$export_file->download();
I need somehow to save this file to server too, if the name doesn't exist yet. The path for the stored file has to be public/resources/snap
Thank you!

Related

Safety in laravel file upload

I have a simple question.. Is it safe to have a app that has a file upload system for users to send images to our project, and store those files in this directory?
$file->move(public_path('../storage/app/public/files'), $name);
Or is it better to store in:
$file->move(public_path('files'), $name);
This way it stores the file in the "files" directory inside the public directory.
That would be ok and also depends on your app and number of users but I recommend to change the name of the file and also you can accept only JPG or PNG file for more security for changing the name of the file you can do it like this :
$image_name = rand() . '.' . $image->getClientOriginalExtension();
$image->move(public_path('images'), $image_name);
with this function you can get all data from db for that id then you can show whatever you want in the blade
public function show($id)
{
$data = YOUR_MODEL::findOrFail($id);
return view('view', compact('data'));
}

Is there a way to save the pdf created from blade straight to database as a pdf file?

I have created a pdf file of the bill that the customer can download. What i want to do is save the same pdf in my database without having to download it first and then upload again. Is there a way to do this?
Controller:
public function export(){
$user = Auth::user()['id'];
$now = Carbon::now()->format('Y-m-d');
$wherecond = " userid=".$user." and created_at like '%".$now."%' ";
$bill = DB::table('cartitems')->select('cartid','category','menu','price','created_at')->whereRaw($wherecond)->orderBy('created_at', 'ASC')->get();
$whereconditn = " userid=".$user." and created_at like '%".$now."%' ";
$cost = DB::table('cartitems')->whereRaw($whereconditn)->sum('price');
$pdf = PDF::loadView('/pages.bill', ['bill' => $bill, 'cost' => $cost]);
return $pdf->stream('bill.pdf');
}
Here i have created a pdf on blade bill.blade.php and the user can download the file but can i save the same pdf directly to the database without downloading it for admin part?
You can add BLOB type in your database to save PDF. But it's not the best practice due to the amount of storage that is required.
I suggest you the following process :
Step 1) generate your PDF file
Step 2) save your PDF file on your webserver
Step 3) create a link (URL) to your PDF file
Step 4) save link (URL) in your database

Laravel : To rename an uploaded file automatically

I am allowing users to upload any kind of file on my page, but there might be a clash in names of files. So, I want to rename the file automatically, so that anytime any file gets uploaded, in the database and in the folder after upload, the name of the file gets changed also when other user downloads the same file, renamed file will get downloaded.
I tried:
if (Input::hasFile('file')){
echo "Uploaded</br>";
$file = Input::file('file');
$file ->move('uploads');
$fileName = Input::get('rename_to');
}
But, the name gets changed to something like:
php5DEB.php
phpCFEC.php
What can I do to maintain the file in the same type and format and just change its name?
I also want to know how can I show the recently uploaded file on the page and make other users download it??
For unique file Name saving
In 5.3 (best for me because use md5_file hashname in Illuminate\Http\UploadedFile):
public function saveFile(Request $request) {
$file = $request->file('your_input_name')->store('your_path','your_disk');
}
In 5.4 (use not unique Str::random(40) hashname in Illuminate\Http\UploadedFile). I Use this code to ensure unique name:
public function saveFile(Request $request) {
$md5Name = md5_file($request->file('your_input_name')->getRealPath());
$guessExtension = $request->file('your_input_name')->guessExtension();
$file = $request->file('your_input_name')->storeAs('your_path', $md5Name.'.'.$guessExtension ,'your_disk');
}
Use this one
$file->move($destinationPath, $fileName);
You can use php core function rename(oldname,newName) http://php.net/manual/en/function.rename.php
Find this tutorial helpful.
file uploads 101
Everything you need to know about file upload is there.
-- Edit --
I modified my answer as below after valuable input from #cpburnz and #Moinuddin Quadri. Thanks guys.
First your storage driver should look like this in /your-app/config/filesystems.php
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'), // hence /your-app/storage/app/public
'visibility' => 'public',
],
You can use other file drivers like s3 but for my example I'm working on local driver.
In your Controller you do the following.
$file = request()->file('file'); // Get the file from request
$yourModel->create([
'file' => $file->store('my_files', 'public'),
]);
Your file get uploaded to /your-app/storage/app/public/my_files/ and you can access the uploaded file like
asset('storage/'.$yourModel->image)
Make sure you do
php artisan storage:link
to generate a simlink in your /your-app/public/ that points to /your-app/storage/app/public so you could access your files publicly. More info on filesystem - the public disk.
By this approach you could persists the same file name as that is uploaded. And the great thing is Laravel generates an unique name for the file so there could be no duplicates.
To answer the second part of your question that is to show recently uploaded files, as you persist a reference for the file in the database, you could access them by your database record and make it ->orderBy('id', 'DESC');. You could use whatever your logic is and order by descending order.
You can rename your uploaded file as you want . you can use either move or storeAs method with appropiate param.
$destinationPath = 'uploads';
$file = $request->file('product_image');
foreach($file as $singleFile){
$original_name = strtolower(trim($singleFile->getClientOriginalName()));
$file_name = time().rand(100,999).$original_name;
// use one of following
// $singleFile->move($destinationPath,$file_name); public folder
// $singleFile->storeAs('product',$file_name); storage folder
$fileArray[] = $file_name;
}
print_r($fileArray);
correct usage.
$fileName = Input::get('rename_to');
Input::file('photo')->move($destinationPath, $fileName);
at the top after namespace
use Storage;
Just do something like this ....
// read files
$excel = $request->file('file');
// rename file
$excelName = time().$excel->getClientOriginalName();
// rename to anything
$excelName = substr($excelName, strpos($excelName, '.c'));
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;
$excel->move(public_path('equities'),$excelName);
This guy collect the extension only:
$excelName = substr($excelName, strpos($excelName, '.c'));
This guy rename its:
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;

How to display file which had already upload laravel 5.2?

I upload file in to my database and moved that file as same name in documents folder in a root path like below :)
public function store(PslCall $call,Request $request)
{
$this->validate($request, $this->rules);
$uploadDestinationPath = base_path() . '/documents/';
$current_id = Document::where('call_id',$call->id)->count()+1;
if ($request->hasFile('file'))
{
$file =$request->file;
$fileName = $file->getClientOriginalName();
$file->move($uploadDestinationPath, $call->id.'_'.$current_id.'_'.$fileName);
}
$input = $request->all();
$input['file'] = $call->id.'_'.$current_id.'_'.$fileName;
$input['call_id'] = $call->id;
Auth::user()->documents()->create($input);
return Redirect::route('calls.documents.index',$call->id)->with('message','You have successfully submitted');
}
its works perfect now im display in my index page all the files like below :)
<td>{{strtoupper($document->title)}}</td>
<td>{{$document->file}}</td>
now my route file i have route to display my file like this :
Route::get('documents/{file}',function() {
return 'hi';
});
here im getting hi output when i click <td>{{$document->file}}</td> this path
but i want know how to display file which i upload same file name ?
As documentation says if you want to display the file content then you may use inside your route function something like:
return response()->file('pathToFile');
If download the file is what you want, then try to use instead:
return response()->download('pathToFile');

How to put storage file download excel for laravel 5.1

I want to put location storage in my apps, when download file in the folder privacy me. Any idea?
public function getExport(){
$user = Members::all();
Excel::create('Export Data',function($excel) use($user){
$excel->sheet('Sheet 1',function($sheet) use($user){
$sheet->fromArray($user);
});
})->export('xlsx');
}
Change the ->export() method to ->save('xlsx').
If you want to use a custom path, pass that as the 2nd argument like so:
->save('xlsx', storage_path('excel/exports'));
If you also want to get back the data from the storage, pass true as the 3rd argument and alias the closure return to a variable:
$file = Excel::create('Export Data',function($excel) use($user){
$excel->sheet('Sheet 1',function($sheet) use($user){
$sheet->fromArray($user);
});
})->save('xlsx', storage_path('excel/exports'), true);
Now you can access $file to get further information about the storage object.
You can also find more in the maatwebsite/excel documentation

Resources