laravel - saving and accessing an uploaded file - php

I am studying some laravel code that I downloaded and I am getting some problem.
This supposed to be the functions to save,delete and download the files but the problem is.
The files are being saved in a folder named with a number on "storage\app\public\project-files\" (i.e. storage\app\public\project-files\11), both destroy and download methods are referencing different paths, I tried to change but didn't worked, download show FileNotFoundException and destroy just remove from the database but not from the folder
So is this code wrong? How It supposed to be?
I've read about using artisan:link but seems odd to me run this command every time I want upload a file to make a link
PS. I cheched the routes, so the methods are being called
Thanks
public function store(Request $request)
{
if ($request->hasFile('file')) {
$file = new ProjectFile();
$file->user_id = $this->user->id;
$file->project_id = $request->project_id;
$request->file->store('public/project-files/'.$request->project_id);
$file->filename = $request->file->getClientOriginalName();
$file->hashname = $request->file->hashName();
$file->size = $request->file->getSize();
$file->save();
$this->project = Project::find($request->project_id);
return view('project-files');
}
public function destroy($id)
{
$file = ProjectFile::find($id);
File::delete('storage/project-files/'.$file->project_id.'/'.$file->hashname);
ProjectFile::destroy($id);
$this->project = Project::find($file->project_id);
return view('project-files');
}
public function download($id) {
$file = ProjectFile::find($id);
return response()->download('storage/project-files/'.$file->project_id.'/'.$file->hashname);
}

You are storing files in storage so i assume you have uploaded image in the following path
project\storage\app\public\project-files
if this is the path then you can delete using
Storage::delete('public/project-files/1.JPG');
for Downlaoding file
$path= storage_path('app/public/project-files/3.JPG');
return response()->download($path);

Related

Laravel 5.5 get file after uploading with Storage

In my Laravel 5.5 project I am having a problem in showing uploaded files. I uploaded the files using Storage. The part of store action of the controller is indicated below.
if ($request->hasFile('content_uz'))
{
$path = $request->file('content_uz')->store('/content/lesson'.$topic->lesson->id.'/topic'.$topic->id);
$data->content_uz = $path;
}
if ($request->hasFile('content_ru'))
{
$path = $request->file('content_ru')->store('/content/lesson'.$topic->lesson->id.'/topic'.$topic->id);
$data->content_ru = $path;
}
Uploading happened successfully. The path to uploaded 'content_uz' file is stored with "storage/app/content/lesson2/topic3" path and content_uz column is stored in my db as below:
content\lesson2\topic3\WSjrlG9a1ermGDOvRJTjn9iEIhfFvhVzjaOs6l79.mp4
How can I display the files in my Blade template? I searched the web, but with no result.
You can use method like this,
public function showFile() {
header("Content-type: video/mp4");
return Storage::get($filePath);
}
I hope this will help.
You may access the files of storage directory by two ways.
If your files are publicly accessible then you may follow laravel public disk.
If your files are protected or private then you may declare a route to access the files.
Route::get('content/{lesson}/{topic}/{file}', function($lesson, $topic, $file)
{
//Check access logic
$filePath = '/content/' . $lesson . '/' . $topic . '/' . $file;
return Storage::get($filePath);
});

Laravel: Refresh response()->file

In Laravel I use this route
Route::get('admin/showBill/{file}','Admin\FileController#showBill');
and this code
class FileController extends AuthController
{
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file) );
if(!\File::exists($path)) return back();
return response()->file($path);
}
to display a pdf from my storage folder.
So if I have the pdf bill-1.pdf in my /storage/app/bills/ folder, then I can view it with the url
example-domain.com/admin/showBill/bill-1.pdf
The problem is that if I open that pdf with the browser, replace it, and refresh (F5) the page, then the old bill is shown. I guess its because its stored in the cache. Can I force Laravel to show the new replaced file?
I tried
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file) );
if(!\File::exists($path)) return back();
$path .= '?v='. time();
return response()->file($path);
}
But then Laravel tells me that this file does not exist. I am looking for a solution where I have not to rename the pdf file.
Are you sure you're replacing the right file?
If so, place this dd(). I've created an endpoint, response an empty pdf file - viewed it - replaced it with a content-filled pdf file and it works just fine when I replace it.
Edit: Also, you should validate the $file variable, using either a formrequest or validating in the controller.
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file));
if(!\File::exists($path)) {
dd("Quite possibly the problem is here, on the redirect back");
}
return response()->file($path);
}

Laravel ajax deleting files fails

IN my vue js ajax post am storing file like
$imagename = sha1(time()).".".$request->profile_pic->extension();
$path = $request->profile_pic->storeAs('public/images/users',$imagename);
$user = \Auth::user();
//remove old file and retain new one
if(\Storage::has($user->profile_pic)){
\Storage::delete($user->profile_pic);
}
$user->picture = $path;
$user->save();
THe above works and the image is saved in the storage/app/public/images/users which is okay
But the database field is saved as public/images/users so when accessing the value in the frontend its not found
After several tests i found out that in the database i need to save the file as
storage/images/users //note path is not starting with public
so i changed the
$user->picture="storage/images/users".$imagename;
But now after doing this the part that removes old file fails
if(\Storage::has($user->profile_pic)){
\Storage::delete($user->profile_pic);
}
How do i adjust the delete part to also work.
UPDATE FOR FULL CONTROLLER CODE
public function changeProfilePic(Request $request){
if ($request->hasFile('profile_pic')) {
$imagename = sha1(time()).".".$request->profile_pic->extension();
$path = $request->profile_pic->storeAs('public/images/users',$imagename);
$user = \Auth::user();
//remove old file and retain new one
if(\Storage::has($user->profile_pic)){
\Storage::delete($user->profile_pic);
}
$user->profile_pic = "storage/images/users".$imagename;
//if save fails delete the uploaded image
if($user->save()){
return response("true", 200);
}else {
\Storage::delete($path);
return response("false", 200);
}
}else{
return response("false", 200);
}
}
in mmy vue js during upload am using vue-image-crop-upload plugin
<image-uploader field="profile_pic"
...other stuff for plugin
url="/change-profile-picture"
langType="en"
:headers="headers"
img-format="png"></image-uploader>
laravel route
Route::post('/change-profile-picture', 'UserController#changeProfilePic');
This is the way i resolved it
After a quick check i found out that no matter what i try
Storage::has or Storage::exists
Aways returns false and `Storage::delete doesnt throw any error even if the file doesnt exists
Also a quick check on the file path i had to change the name stored on database from storage to public hence explde and implode
TRHe final code that works is
public function changeProfilePic(Request $request){
if ($request->hasFile('profile_pic')) {
$imagename = sha1(time()).".".$request->profile_pic->extension();
$path = $request->profile_pic->storeAs('public/images/users',$imagename);
$user = \Auth::user();
$olduserpicdata = explode("/",$user->profile_pic);
$olduserpicdata[0] = "public";
//remove old file and retain new one
Storage::delete(implode("/",$olduserpicdata));
$user->profile_pic = "storage/images/users/".$imagename;
//if save fails delete the uploaded image
if($user->save()){
return response("true", 200);
}else {
Storage::delete($path);
return response("false", 200);
}
}else{
return response("false", 200);
}
}

How to upload a file (Laravel)

I want to upload a file in Laravel:
I put this code in route
Route::post('upload', 'myconttest#test')->name('upload');
And put this code in controller
function test(Request $request){
$file=$request->file('myfile');
$filename=$file->getClinetOriginalName();
// $projectname;
$path='files/';
$file->move($path,$filename);
}
I create a folder in public called files. The code runs without error but the file is not saved.
Its a working code please see this
public function store(Request $request)
{
$checkval = implode(',', $request->category);
$input = $request->all();
$input['category'] = $checkval;
if ($request->hasFile('userpic')) {
$userpic = $input['pic'];
$file_path = public_path("avatars/$userpic");
if(File::exists($file_path)) {
File::delete($file_path);
}
$fileName = time().$request->userpic->getClientOriginalName();
$request->userpic->move(public_path('avatars'), $fileName);
$input['userpic'] = $fileName;
Product::create($input);
return redirect()->route('productCRUD.index')->with('success','Product created successfully');
}
}
Make sure your form is enabled to upload the file. So check that the following attribute is set or not.
<form action"" 'files' => true>
Use the following namespace
use Illuminate\Support\Facades\Input;
Then try this:
$file = Input::file('myfile');
$filename = $file->getClinetOriginalName();
move_uploaded_file($file->getPathName(), 'your_target_path/'.$filename);
I think you can try this:
First you give folder permission to files folder in public folder
function test(Request $request){
$file=$request->file('myfile');
$filename=$file->getClinetOriginalName();
$file->move(public_path().'/files/', $filename);
}
Hope this work for you !!!
In controller test function you need to given public path of files folder like
$path = public_path('files/');
for moving file on given public folder path.

Laravel storing temporary filename in database

The upload script is working, the file also gets saved by the correct/desired name. However, while storing data in database, it stores .tmp filename instead
controller code:
public function store(CreateChapterRequest $request)
{
if($request['chapter_content_type']==6) {
//upload file
$record_save = $this->processFile($request->file('chapter_document'));
$request['chapter_document']=$record_save;
}
Chapter::create($request->all());
}
protected function processFile($requestData)
{
$input['chapter_document'] = time().'.'.$requestData->getClientOriginalExtension();
$destinationPath = public_path('uploads/chapters/');
$requestData->move($destinationPath, $input['chapter_document']);
return $input['chapter_document'];
}
It's storing file name as C:\project\xampp\tmp\phpD837.tmp. What's wrong?
It works with $record=new Chapter(); $record->save($request->all()); but not with ::create()
Don't know why!

Categories