Avatar resize and delete - php

I'm trying to resize avatar but it's don't work.
I'm using intervention/image package.
Avatar stores but its stores in original sizes and when i update avatar old avatar is not deleting don't know why (
so what's i'm doing wrong?
public function avatarUpdate(Request $r)
{
Storage::delete('users'.'/'.Auth::user()->avatar);
if ($r->hasFile('avatar')) {
$thumbnailImage = Image::make($r->avatar);
$filename = $thumbnailImage->resize(50, 50);
$filename = $r->avatar->getClientOriginalName();
$r->avatar->storeAs('users', $filename, 'public');
$url = 'users/';
User::where('id', Auth::id())->update([
'avatar' => $url . $filename
]);
}
return redirect()->back();
}

I think we need here more context. But i assume that
$r->avatar->storeAs('users', $filename, 'public');
stores the file into public folder while
Storage::delete('users'.'/'.Auth::user()->avatar);
tries to find the image path within private storage.
Try this out
Storage::disk('public')->delete('users/'.Auth::user()->avatar);
maybe this will work

Related

Laravel Azure Blob Storage Cache Images

this is my scenario:
I have a Laravel 6.x application and I'm using the FlySystemAzureBlobStorage package to store images on Azure Blob Storage.
Then I want to use the InterventionImageCache package to get and cache the images for faster client's downloads in different sizes.
I've already done it in this way:
public static function getImageResponseForApi($storageDiskName, $imagePath, $width = null, $height = null)
{
//check if the image exists on disk
$exists = empty($storageDiskName) ?
Storage::exists($imagePath) :
Storage::disk($storageDiskName)->exists($imagePath);
if ($exists) {
$image = empty($storageDiskName) ?
Storage::get($imagePath) :
Storage::disk($storageDiskName)->get($imagePath);
if (!empty($width) || !empty($height)) {
//use the image cache function to get the cached image if exists
$image = \Image::cache(function ($ima) use ($image, $width, $height) {
//check if height and with are higher than original or not
$ima->make($image)->resize($width, $height, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
});
}
$sizes = getimagesizefromstring($image);
$headers = [
'Content-Length' => strlen($image),
'Content-Type' => $sizes["mime"]
];
return \Response::make($image, 200, $headers);
} else {
return null;
}
}
There is a problem working in this way: I must download the image from azure blob storage before the system can check if a resized cached version of it exists.
The Azure package i'm using doesn't provide the possibility to get the image paths, so I can't find another solution to my problem.
So, is there a way to achieve the image caching without I have to download the file every time?
I use a separate route for showing/caching the image in my blade.
I store the image as BLOB in MYSQL PRODUCT table identified by product_id
BLADE:
<img src="/dbimage/{{$product->id}}.png" >
ROUTE:
Route::get('/dbimage/{id}',[ProductImageController::class, 'getImage']);
CONTROLLER:
class ProductImageController extends Controller
{
public function getImage($prodcutImageID){
$productID=explode(".",$prodcutImageID);
$rendered_buffer= Product::all()->find($productID[0])->image;
$response = Response::make($rendered_buffer);
$response->header('Content-Type', 'image/png');
$response->header('Cache-Control','max-age=2592000');
return $response;
}
}
This makes the browsers cache the images

Save user image url in database

I save the image in the public folder but i need the image url saved in the database instead of the file name.
https://devdojo.com/episode/laravel-user-image
public function update_avatar(Request $request){
if ($request->hasFile('avatar')){
$avatar = $request ->file('avatar');
$fileName = time().'.'. $avatar->getClientOriginalExtension();
Image::make($avatar)->resize(300, 300)->save( public_path('/uploads/avatars/'. $fileName));
$user = Auth::user();
$user->avatar = $fileName;
$user->save();
}
return view('profile', array('user' => Auth::user()));
}
It is highly not recommend to use that approach, instead save the name in database, and use the file path with the name on the database to display the image.
For example:
<img class="border-radius-3" src="{{ asset('uploads/avatars/'.$user->image)}}" alt="">
Just tell us what you're trying to accomplish.
If you need save file URL in DB you can use something like this
$user->avatar = '/uploads/avatars/'.$fileName);
You should convert img to base64 to store it as a string in DB.
I never recommend this, but anyway:
$data = base64_encode($img);

PHP: generate unique string for filename

I want to upload files with an unique random string as file name, then if I upload a file called file.txt that will be hashed like m84n3nv38tu48a, if I upload the same file again it won't be saved because the same file name with that hash exists.
Then download the file searching it by the original name, hashing again and compare to find out in the directory.
Something like this
public function storeFile(Request $request) {
$file = $request->file('file');
$filename = $file->getClientOriginalName();
$path = $file->move(storage_path()."\\app\\file", md5_file($file);
$response = [
"file Name" => $filename,
"Extension" => $file->getClientOriginalExtension(),
"Path" => storage_path().$path
];
return response()->json($response);
}
public function downloadFile($fileName) {
$fullpath = storage_path()."\\app\\file\\".md5_file($fileName);
$file = file_exists($fullpath);
if($file)
return response()->download($fullpath, $fileName);
return response()->json('File not Found', 404);
}
The md5_file method in downloadFile doesn't (obviously work) because $fileName is a string (not a file) then I get a different hash.
How could I resolve this?
EDIT
I want to replace the entire file name with a unique ID.

Laravel Access Images outside public folder

I need to store images in a backend for logged in users. The stored images need to be protected and not visible from the outside (public). I choosed a "storage" folder for this.
I came up with this in my Controller:
public function update(Request $request, $id)
{
//Show the image
echo '<img src="'.$_POST['img_val'].'" />';
//Get the base-64 string from data
$filteredData=substr($_POST['img_val'], strpos($_POST['img_val'], ",")+1);
//Decode the string
$unencodedData=base64_decode($filteredData);
//Save the image
$storagepath = storage_path('app/images/users/' . Auth::user()->id);
$imgoutput = file_put_contents($storagepath.'/flyer.png', $unencodedData);
return view('backend.flyers.index')->withImgoutput($imgoutput)
//->withStoragepath($storagepath);
}
after hitting the save button, which triggers the update() I am able to see the image in my view, and it is also stored in my folder (current users=10) "storage/app/images/users/10/flyer.png"
my question is how can I access the image path?
I want to show the stored image with img src="">. I have no idea what to put inside "src= ..."
While dealing with user file uploads in web applications, the major aspect is about user's content's security.
One should use secure way to upload private files of a user in web applications.
As in your case, you want to access user's image outside public folder.
This can be done in a most secure way as given below.
First of all create a directory right in the root directory of Laravel (where the public folder is located), let the directory's name be uploads. Use this directory to upload private user files.
In the case of images create an another directory inside uploads as uploads/images/ inside uploads directory so that you can have a different storage locations for different type of files.
Remember to upload the image in images directory with a different name and without their extensions so that it looks like a extension-less file.
Keep the file name and its extension in the database which can be used later to retain image's location.
Now you need to create a separate route to show user's image.
Route::get('users/{id}/profile_photo', 'PhotosController#showProfilePhoto')->name('users.showProfilePhoto');
PhotosController.php
class PhotosController extends Controller {
private $image_cache_expires = "Sat, 01 Jan 2050 00:00:00 GMT";
public function showProfilePhoto($id) {
$user = User::find($id);
$path = base_path() . '/uploads/images/';
if($user && $user->photo) // Column where user's photo name is stored in DB
{
$photo_path = $path . $user->photo; // eg: "file_name"
$photo_mime_type = $user->photo_mime_type; // eg: "image/jpeg"
$response = response()->make(File::get($photo_path));
$response->header("Content-Type", $photo_mime_type);
$response->header("Expires", $this->image_cache_expires);
return $response;
}
abort("404");
}
}
The method above inside PhotosController - showProfilePhoto($user_id) will run as soon as you access the route named - users.showProfilePhoto.
Your HTML code will look like this.
<img src="<?php echo route('users.showProfilePhoto', array('id' => $user->id)); ?>" alt="Alter Text Here">
The above code will work like a charm and the image will be shown to the user without declaring/publishing the proper image path to public.
According to me this is the secure way to deal with file uploads in web applications.
You can do this like this:
Route::get('images/{filename}', function ($filename)
{
$path = storage_path() . '/' . $filename;
if(!File::exists($path)) abort(404);
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
Reference:
Laravel 5 - How to access image uploaded in storage within View?
Or Alternatively you can use this library: https://github.com/thephpleague/glide
Just use composer to install it in your project
By default, this will render images from your storage, and allow you to do all sorts of things with it such as cropping, color correction etc.
Reference:
http://glide.thephpleague.com/
https://laracasts.com/discuss/channels/laravel/laravel-5-how-can-we-access-image-from-storage?page=1
Atimes you might have some images you do not wish to store in public directory for some various reasons.
Although storing your images has lots of advantages.
There are many ways you can achieve this, however I have this simple solution.
You should create a helper class like so if already don't have one
<?php namespace App\Services;
class Helper
{
public function imageToBase64($path)
{
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
return 'data:image/' . $type . ';base64,' . base64_encode($data);
}
}
Then in your view (blade)
#inject('helper', 'App\Services\Helper')
<img width="200" height="250" src="{{$helper->imageToBase64(storage_path('app/images/users/' . Auth::user()->id)}}">
It will work 100% work. Open file filesystem in app/config/filesystem.php and write like that
'profile' => [
'driver' => 'profile',
'root' => '/home/folder/public_html/projectname/public/profiles',
],
Add this file at top
use Illuminate\Support\Facades\Storage;
My variable name is
$directoryName = 'profile';
$imageName = $request->image; // image is array of base64 encoded urls
$directory_path ='profiles';
Below function save your file in public/profiles folder.
function UploadImagesByBase64($directoryName, $imageName,$directory_path)
{
$data = array();
$image = $imageName;
foreach ($image as $image_64) {
if($image_64 !=null){
$extension = explode('/', explode(':', substr($image_64, 0, strpos($image_64, ';')))[1])[1]; // .jpg .png .pdf
$replace = substr($image_64, 0, strpos($image_64, ',')+1);
// find substring fro replace here eg: data:image/png;base64,
$image = str_replace($replace, '', $image_64);
$image = str_replace(' ', '+', $image);
$imageName = Str::random(10).time().'.'.$extension;
Storage::disk($directoryName)->put($imageName, base64_decode($image));
$data[] = $directory_path.'/'.$imageName;
}
}
$imageName = implode(',', $data);
return $imageName;
}

Laravel 5 storage

I have tried to upload an image file in a sub-folder but I didn't get the help from internet. In Laravel website they mentioned about create folder but not explaining about sub-folders. My purpose is I need to upload an image in to sub-folder. Eg: userdata/1/1.jpg.
I have tried some code which is given below.
public function store(ProfileimageRequest $request, $id)
{
User::findOrFail($id);
$file = $request->file('file');
Storage::makeDirectory($id); //result is 1
$extension = $file->getClientOriginalExtension();
Storage::disk('local')->put($id.'.'.$extension, File::get($file)); //result is 1.jpg
}
The result of above code is creating folder "1" and image "1.jpg" but image is not creating inside the folder.
You probably have to specify that you want to the file to be uploaded into the folder. In the put() method add the folder's name with the file's name.
public function store(ProfileimageRequest $request, $id)
{
User::findOrFail($id);
$file = $request->file('file');
Storage::makeDirectory($id); //result is 1
$extension = $file->getClientOriginalExtension();
Storage::disk('local')->put($id.'/'.$id.'.'.$extension, File::get($file));
}
Let me know if this works out for you.

Categories