Laravel 8 - Image not deleted from storage + not updating when "Edit" - php

possible "duplicate": Laravel - Delete images from storage / update post
I want laravel to delete the old image and replace it with new uploaded image in the edit form. I tried doing this:
if( $request->hasfile('violationStatement') ) {
$destination = 'violations/' . $violation->violationStatement;
// Deletes the file if it exists
if( File::exists($destination) ) {
File::delete($destination);
}
$file = $request->file('violationStatement');
$extension = $file->getClientOriginalExtension();
$filename = time() . '.' . $extension;
$file->move('violations/', $filename);
$violation->violationStatement = $filename;
}
$violation->update();
But the image is not deleted nor updating. In addition, I want to have a condition when I just want to edit data without uploading new image...
Here is the routing:
// Traffic Violations
Route::controller(TrafficViolationController::class)->group(function () {
Route::get('violations', 'index')->name('violations.index'); // Index page (DataTable)
Route::get('violations/create', 'create')->name('violations.create'); // The form for adding new records
Route::post('violations/create', 'store')->name('violations.store'); // Add new to DB
Route::get('violations/edit/{violation}', 'edit')->name('violations.edit'); // The form for editing records
Route::put('violations/edit/{violation}', 'update')->name('violations.update'); // Update record to DB
Route::get('violations/{violation}', 'destroy')->name('violations.destroy'); // Delete from DB
});

First make sure of namespace
use Illuminate\Support\Facades\File;
Then edit $violation->update() to $violation->save();
And if the path in public folder use this method public_path() as this
$destination = public_path('violations/' . $violation->violationStatement);
But if the path in storage folder use this method storage_path() as this
$destination = storage_path('violations/' . $violation->violationStatement);

I use Intervention\Image\Facades\Image for uploading image And Illuminate\Support\Facades\File For Manage Directories. below Code replace Pic If Exist. think now you have 123.jpg and you want replace it. it replace old pic with new one. if your image name is difference you can delete old one.
use Illuminate\Support\Facades\File;
use Intervention\Image\Facades\Image;
//Get Data Of uploaded pic
$file = $request->file('violationStatement');
$srcPath = $file->getRealPath();
$size = $file->getSize(); // if You Need Pic Size
$extension = $file->getClientOriginalExtension();
//Start Uploading
$Image = Image::make($srcPath);
$destPath = public_path("violations");
File::ensureDirectoryExists($destPath); // Check Directory Exist Or Make
$filename = time() . '.' . $extension;
$Image->save($destPath.'/'.$filename);
at last I suggest add some unique thing to Your Image Name because it may two user upload picture at Same Time!!! and One Picture replaced.

Related

Upload images with random name and also delete older image from the directory

I am trying to upload an image with a random name, also when I update the image, I want the previous image to be deleted.
Code below:
$banner=$_FILES ['banner']['name'];
$upload="../image/banner/";
$target_file = $upload.basename($_FILES["banner"]["name"]);
$imagefiletype= pathinfo($target_file,PATHINFO_EXTENSION);
move_uploaded_file($_FILES["banner"]["tmp_name"], $target_file );
Any help will be appreciated.
When update your new images at that time first store old image name in variable. after update true then delete old image in your directory using "unlink" function.
$old_image = "xyz" // store old image name
after update query success
unlink('../image/banner/'.$old_image); // delete old image in your directory
You can do it like this.
$path = 'image/folder/'; $unique_name=time().uniqid(rand());
$File_with_location = $path . $unique_name . '.' . strtolower(pathinfo($_FILES['img']['name'], PATHINFO_EXTENSION));
$filename = $_FILES["img"]["tmp_name"];
move_uploaded_file($filename, $File_with_location);
for deleting old image you can use this
$path = './root/home/folder/file.jpg';
if (unlink($path)) {
echo 'success';
} else {
echo 'fail';
}

Save and retrieve file in Laravel

I have difficulty understanding the file save and retrieval in Laravel. I managed to get the file saved into correct path
$fileNameWithExt = $request->file('Agreement_file')->getClientOriginalName();
$fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
$extention =$request->file('Agreement_file')->getClientOriginalExtension();
$filenameToStore = $fileName . '_' . $lab_id. '.'.$extention;
$request->Agreement_file->storeAs('agreements', $filenameToStore );
However not I want to create an a-tag to download the file, but cannot manage to get to download the file.
{{$filenameToStore}}
The file download but I get the error "Failed- Server Problem". I do not want to use a same link as these files are confidential and should not be able to be downloaded outside the app.
Something like that?
Step 1:
Create table files id | filename | user_id.
Step 2:
Create model File
Step 3:
Add file row in table.
$fileNameWithExt = $request->file('Agreement_file')->getClientOriginalName();
$fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
$extention =$request->file('Agreement_file')->getClientOriginalExtension();
$filenameToStore = $fileName . '_' . $lab_id. '.'.$extention;
$request->Agreement_file->storeAs('agreements', $filenameToStore );
File::create([
'filename' => $filenameToStore,
'user_id' => Auth::id()
]);
Step 4:
Create controller method download.
public function download(){
$filename = $request->input('filename');
$file = File::where('user_id', Auth::id())
->where('filename', $filename)
->firstOrFail();
$path = Storage::path('agreements/' . $filename);
if(Storage::exists($path)){
return Response::download($path, $filename);
}
}
Step 5:
Replace your link:
{{$filenameToStore}}
Or you can build it based on the file ID.

Laravel database images update failue

I am trying to update images in my database.I am using laravel 5.4 version.
I am getting this error.
Type error: Argument 1 passed to Illuminate\Database\Eloquent\Builder::make() must be of the type array, object given, called in C:\xampp\htdocs\laravel_eshopper\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php on line 1357
Here is my update function in the controller script.
if use http://image.intervention.io/
Change Product::make($image) to Image::make($image)
Ah okay I know the problem.
First, the best practice is not save the image in database just save the path where you save the image.
Here I give you example code:
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
$location = public_path('images/home/');
// now saving the file
$image->move($location, $filename);
// delete oldfile
$oldFilaname = $product->image;
Storage::delete($oldFilename);
// update
$product->image = $location . '/' . $filename;
}

Detecting if user is uploading the same image

I have a form that contains an image upload and an input text box. The user will be able to upload an image and enter text without refreshing the page using Ajax. The image will be relayed to PHP and PHP will handle what to do with the image. My problem is that for the first time the user uploads an image, it'll be checked if the same image name is on the server or not. If it is, the image name will get a uniqid() and then will be uploaded. But what if the user changes the data in the text box field, but keeps the image? Then that image will be uploaded again with a uniqid() since it's already on the server. I've tried solving this using my current code for the image handling:
PHP
$target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name";
if (isset($_SESSION["size"]))
{
$prevSize = $_SESSION["size"];
if (filesize($prevSize) != filesize($size))
{
if (#getimagesize($target_file) == true)
{
$ext = pathinfo($name, PATHINFO_EXTENSION);
$name = basename($name, "." . $ext);
$name = $name . uniqid() . "." . $ext;
$target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name";
}
}
}
else
{
$_SESSION["size"] = $size;
if (#getimagesize($target_file) == true)
{
$ext = pathinfo($name, PATHINFO_EXTENSION);
$name = basename($name, "." . $ext);
$name = $name . uniqid() . "." . $ext;
$target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name";
}
}
move_uploaded_file($tempName, $target_file);
Unfortunately, this code isn't working like I want it to. If I upload the same image twice in a row, in the same session, it doesn't override my previous image. Instead, it puts it on the server with a uniqid name. What am I doing wrong? And if there's a better way in solving this, I'd love to know!
What you can do is whenever someone uploads an image, store a hash of the image, encrypt it and store it in the database on the image row.
From now on, whenever someone uploads an image run a query like this:
SELECT COUNT(*) FROM images WHERE hash = $hash then in an if statement check if the returned value is bigger than 0, if it is, do what you need to do without re-uploading the image, and if it is 0, then upload your image and proceed
I chose a user avatar upload for this example. I'm not sure what your image is, but the workflow should be similar. No duplicate avatars will be copied to the image path.
function get_avatar_filename($filename) {
// only generate an avatar filename if the mimetype matches
switch (mime_content_type($filename)) {
case 'image/jpeg':
return sprintf('%s.jpg', hash_file('md5', $filename));
case 'image/gif':
return sprintf('%s.gif', hash_file('md5', $filename));
case 'image/png':
return sprintf('%s.png', hash_file('md5', $filename));
// otherwise the user uploaded a non-supported image
// return the default image
default:
return 'default-avatar.jpg';
}
}
function upload_avatar($avatarPath, $filename) {
// get the avatar filename
$f = get_avatar_filename($filename);
// copy the file to $avarPath only if the file doesn't already exist
if (!file_exists("{$avatarPath}/{$f}")) {
move_uploaded_file($filename, "{$avatarPath}/{$f}");
}
// return the avatar filename
return $f;
}
Now you can use these functions when you process the user form submission
// process user form submission ...
// ...
$filename = upload_avatar(
$_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/",
$_FILES['user_avatar']['tmp_name']
);
// save the avatar location for the user ...
// or whatever
$user->setAvatar($filename);
$user->save();
If the user uploads a non-supported image type, they will just be assigned default-avatar.jpg which is a file that should exist in your images directory.

PHP file-upload not working

I'm having trouble moving the file. I'm also wondering if there's a way for a user to upload a different picture, and have it automatically remove the old one?
move_uploaded_file(#$_FILES["profilepic"]["tmp_name"],"userdata/".$_POST['username']."/profilepic".$_FILES["profilepic"]["name"]);
You have remove # before $_FILES and check error.
if you want to replace picture old to new then make your own user wise image name and use it like.
$_POST['username']=test;
$imagname=$_POST['username']."_img";
move_uploaded_file(#$_FILES["profilepic"]["tmp_name"],"userdata/".$_POST['username']."/profilepic/".$imagename);
Try this block of code
$imagename = $_FILES['profilepic']['name'];
$source = $_FILES['profilepic']['tmp_name'];
$imagename = str_replace(" ", "_", $imagename);
$target = "userdata/".$_POST['username']."/profilepic" . $imagename;
move_uploaded_file($source, $target);
Make sure you have got write permission to the folder userdata,plmexico,profilepic.
Good habits:
Rename the user's file with a name generated by your algorithm. As you want to replace the profile pic when they upload a new picture you naming can combine user_id with the file name. So the code becomes.
$localname = $_FILES['profilepic']['name'];
$imagename = $user_id."_profile".explode(end(",",$localname)); // $user_id is the user's id
$source = $_FILES['profilepic']['tmp_name'];
$imagename = str_replace(" ", "_", $imagename);
$target = "userdata/".$_POST['username']."/profilepic" . $imagename;
move_uploaded_file($source, $target);
This code doesn't work if the user uploads an image in different format.

Categories