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);
}
}
Related
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);
how to delete images file from public/images folder in laravel 5 ??
i found some example from this site, but i know they are just using the file name in their record table, but i'm using something like URL e.g localhost/project/uploads/filename.jpg on my record table. so if i tried like this :
$image_path = $data->image; // the value is : localhost/project/image/filename.format
if(File::exists($image_path)) {
File::delete($image_path);
}
the file is not deleted
help pls, thanks
If you want to delete image from your server, you have to reference location of file in directory server, means you could not reference by url link to delete it.
Commonly, Laravel 5 file is locate in public folder.
Example: your files are located in public/images
$image_path = "/images/filename.ext"; // Value is not URL but directory file path
if(File::exists($image_path)) {
File::delete($image_path);
}
If I can delete image from server by reference URL then Google is the first target :)
You can use the normal PHP delete file keyword ( #unlink )
$image_path = "the name of your image path here/".$request->Image;
if (file_exists($image_path)) {
#unlink($image_path);
}
This is what I do to delete an image:
public function SliderDelete(String $slider_id)
{
$slider = Slider::findOrFail($slider_id);
$image_path = public_path("\storage\images\sliders\\") .$slider->photo;
if(File::exists($image_path)) {
File::delete($image_path);
}
else{
$slider->delete();
//abort(404);
}
$slider->delete();
return response()->json(['success'=>'Slider deleted successfully!']);
}
in laravel 8 you do it like
// import Storage class
use Illuminate\Support\Facades\Storage;
Storage::disk('public')->delete('path-of-file');
you can use disk of your choice like
Storage::disk('s3')->delete('path-of-file');
$filename = public_path($fileloc);
if(File::exists($filename)) {
File::delete($filename);
}
call this function and pass two parameter
$filepath = path where your file exist
$filename = name of your file
public static function UnlinkImage($filepath,$fileName)
{
$old_image = $filepath.$fileName;
if (file_exists($old_image)) {
#unlink($old_image);
}
}
public function destroy($id)
{
$imagePath = YourModelName::select('image')->where('id', $id)->first();
$filePath = $imagePath->image;
if (file_exists($filePath)) {
unlink($filePath);
YourModelName::where('id', $id)->delete();
}else{
YourModelName::where('id', $id)->delete();
}
}
To be able to delete the image it should be in the following form :
"/uploads/img1.jpg" where uploads directory is in the public directory then use the following code:
$image_path = puplic_path("/uploads/img1.jpg")
if (file_exists($image_path)) {
File::delete($image_path);
}
Here is the correct and easy way .
if (file_exists(public_path() . '/storage/gallery/images/'. $item->image)) {
unlink(public_path() . '/storage/gallery/images/'. $item->image);
}
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!
I have setup a repository to create a new resident.
<?php namespace Crescent\Repos;
interface ResidentRepository {
public function create($input);
}
Then in my controller I have, which uses the intervention image class to resize an image and it uploads correctly to the directory, but how can I save the name of the file to the DB using this repo?
public function store()
{
if (Input::hasFile('photo')){
$res = new Residents;
$file = Input::file('photo');
$name = $file->getClientOriginalName();
$input = Input::all();
$image = Image::make(Input::file('photo')->getRealPath())->resize(200, 200);
$image->save(public_path() . '/uploads/residents/' . $input['photo']->getClientOriginalName());
$res->photo = $name; // This doesn't work
}
$this->resident->create(Input::all());
}
Everything else works all the data, but the image isn't storing the name just showing some temp dir/name like /tmp/phpIX7KcY
I see that you have done $res = new Residents; and $res->photo = $name; but you haven't done $res->save(); which would have saved the name to the table corresponding to Residents. Also since you haven't added anything else to $res, only the photo would be saved.
Replace the code in your controller with the following:
public function store()
{
$input = Input::all();
if (Input::hasFile('photo')){
$file = Input::file('photo');
$name = $file->getClientOriginalName();
$image = Image::make(Input::file('photo')->getRealPath())->resize(200, 200);
$image->save(public_path() . '/uploads/residents/' . $input['photo']->getClientOriginalName());
$input['photo'] = $name;
}
$this->resident->create($input);
}
If in your code $this->resident->create(Input::all()); saves all data properly except the photo, it is because by passing Input::all() you're saving everything exactly as it was received from the client and the filename received from the resizing operation isn't present in Input::all(). By assigning Input::all() to the variable $input and doing $input['photo'] = $name;, the location of the file on the server is stored instead of the location on the client. So, by doing $this->resident->create($input);, the location on the server is stored along with other data received from the client.
I would like to create a controller that handles uploading files to user specific folders. I currently have a from that allows users to upload a file which sends the post data to the controller.
What I would like the controller to do is take the uploaded file, and place it in a folder e.g. /public/{username}/files
But I am not too sure how to approach it using symfony.
As Mahok commented, the Symfony2 docs are useful here.
I would follow them with the added additions. When you save the document, pass the username:
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
//get the user and pass the username to the upload method
$user = $this->get('security.context')->getToken()->getUser();
$document->upload($user->getUsername());
$em->persist($document);
$em->flush();
$this->redirect(...);
}
When you upload the file, use the username:
public function upload($username)
{
if (null === $this->file) {
return;
}
//use the username for the route
$this->file->move(
"/public/$username/files/",
$this->file->getClientOriginalName()
);
// set the path property to the filename where you've saved the file
$this->path = $this->file->getClientOriginalName();
// clean up the file property as you won't need it anymore
$this->file = null;
}
Saving it this way you wont actually need to use the extra entity methods like "getAbsolutePath" etc
Note that you may have to slugify the username if you accept spaces etc.
Edit:
You will need to set up a oneToMany relationship for users to files so that you can locate the file later on.
This might help you---
$upload_dir = "your upload directory/{username}";
if (!is_dir($upload_dir)) {
#mkdir($upload_dir, "755", true);
}
move_uploaded_file($source,$destination);