Safety in laravel file upload - laravel

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'));
}

Related

how to save dompdf file to storage and name the file dynamicly in laravel

does anyone know how to save generated pdf file and name it dynamicly using dompdf in laravel?
i always encounter this error
failed to open stream: No such file or directory
while trying to generated pdf file and save it to project directory.
here its my controller code
$bills = Tagihan::join('pesanan', 'tagihan.id_pesanan', 'pesanan.id_pesanan')
->join('kendaraan', 'pesanan.id_kendaraan', 'kendaraan.id_kendaraan')
->join('kategori_mobil', 'kendaraan.id_kategori_kendaraan', 'kategori_mobil.id_kategori')
->join('users', 'pesanan.id_pengguna', 'users.id')
->where('pesanan.id_pesanan', $save->id_pesanan)
->select('pesanan.*', 'users.*', 'tagihan.*', 'kendaraan.*', 'kategori_mobil.nama_kategori')
->first();
$today = Carbon::now('GMT+7')->toDateString();
$pdf = new PDF();
$pdf = PDF::loadView('admin.tagihan.pdf', compact('bills','today'));
file_put_contents('public/bills/'.$noOrder.'.pdf', $pdf->output() );
return redirect()->route('pesananIndex');
i want to save my pdf file with custom string with $noOrder.'pdf', but when i use static name like this
file_put_contents('public/bills/bubla.pdf', $pdf->output());
i had no error, any solution?
You can getOriginalContent from http response into a variable then push it to your file.
$pdf = PDF::loadView('admin.tagihan.pdf', compact('bills','today'));
$content = $pdf->download()->getOriginalContent();
Storage::put('public/bills/bubla.pdf',$content);
...
Storage::disk('local')->makeDirectory('/pdf/order');
$pdf = PDF::loadView('PDF.Order.OrderPDF-dev', ['invoiceDetail'=>$invoiceDetail]);
$path = 'storage/pdf/order/';
$pdf->save($path . $fileName);
return url($path.$fileName);
In my example first i created folder for PDF. makeDirectory(...) will create folder if exist or not.
$path is location where i want to put my file in Dir. do not use absolute path or public path function here. only define location where you want to create file.
I am creating file in Storage folder. so i added storage/.....

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');

Can't write image data to path in laravel

I am having the same error as this guy is :
Another thread
basically the error i have is uploading the image to the specific path, my code is as follows :
public function postCreate() {
$validator = Validator::make(Input::all() , Product::$rules);
if ($validator->passes()) {
$product = new Product;
$product->category_id = Input::get('category_id');
$product->title = Input::get('title');
$product->description = Input::get('description');
$product->price = Input::get('price');
$image = Input::file('image');
$filename = date('Y-m-d-H:i:s')."-".$image->getClientOriginalName();
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
$product->image = 'public/img/products'.$filename;
$product->save();
return Redirect::to('admin/products/index')
->with('message' , 'Product created');
}
return Redirect::to('admin/products/index')->with('message' , 'something went wrong')
->withErrors($validator)->withInput();
}
I was just trying to follow a tutorial on laravel e-commerce web application.
I guess the problem is that i don't have write permisson in my directory , how do i add write permission in my directory. I.E. the public folder, I googled a few places , but i don't understand what is it that i have to edit ?
I.E the htaccesss file or can i make write changes on the cmd ? also how do i check what weather a directory is write protected .
PS. i am using windows . i am attaching a screenshot of the error .
Thank you.
You might want to change the dateformat since windows doesn't allow colons in filenames:
$filename = date('Y-m-d-H:i:s')."-".$image->getClientOriginalName();
And you also might want to add a trailing slash to your path so it doesn't concatenate the filename to the folder path:
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
Generally this error occurs when you do not yet have the directory that will store the image inside the public directory. Sometimes it can be a permission issue.
Does you img directory exists in your public directory?
To fix this, follow the steps:
Use this snippet:
$relPath = 'img/'; //your path inside public directory
if (!file_exists(public_path($relPath))) { //Verify if the directory exists
mkdir(public_path($relPath), 666, true); //create it if do not exists
}
Or manually create the img directory in public
2.Then you can save your image:
Image::make($image)->resize(468, 249)->save(public_path('img/products'.$filename)); //save you image
$product->image = 'img/products'.$filename; //note
$product->save();
**NOTE: We do not need to specify the public directory in the path because we are using a relative path. The img directory will be created inside public directory.
Along with this, you need to make sure the folder path exists and which has right permissions set.
$relPath = 'img/product/';
if (!file_exists(public_path($relPath))) {
mkdir(public_path($relPath), 777, true);
}
Where $relPath is the path relative to public directory.
This requirement is however windows specific. In linux, folder directory will be created if it does not exist.
I also recommend all of you to check if $path exists. Like Jose Seie use native PHP check, I recommend you to thought about build-in helpers.
This can be achieved with File Facade helper:
File::exists($imagePath) or File::makeDirectory($imagePath, 777, true);
Advice you to use Laravel built-in functions, classes & helpers to improve the performance of your application!
well , i made the correction that john suggested and then made the following corrections :
I replaced the below code :
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
with :
$path = public_path('img/products/'.$filename);
Image::make($image->getRealPath())->resize(468, 249)->save($path);
problem solved , i don't know why public_path works , but never mind .

Why my .jpg files are saved as .tmp?

I am following a tutorial from Laracasts, for uploading files. Here in the example I will upload a jpg file or png file, and in my images folder I get a file with different name and with a different extension. Why is that?
This is how I am moving the uploaded file.
And here is how the files are saved.
You better send also the filename:
Input::file('photo')->move($destinationPath, $fileName);
You'll probably be able to (not tested)
Input::file('photo')->move($destinationPath, Input::file('photo')->getClientOriginalName());
Also, check the docs: http://laravel.com/docs/requests#files
You may try this (No need to use public_path):
public function store()
{
$targetPath = 'images'; // For "public/images"
$file = Input::file('image'); // If "image" is the name of the file input
$filename = $file->getClientOriginalName();
$file->move($targetPath, $fileName);
}

Resources