My user uploads a profile picture which is stored in storage/profile_picture/user1.png. I use Filesystem and Storage classes to do so.
To retrieve the image I use {!! Html::image(route('profile.thumbnail', $user->profilepic_filename), "Your Picture Here", ['class'=>'img-responsive']) !!}
In my Controller I have
public function thumbnail($filename)
{
$user = User::where('profilepicture_filename', '=', $filename)->firstOrFail();
$file = Storage::disk('local_profile')->get($user->profilepicture_filename);
//$file = URL::asset('/images/default_profilepicture.png'); //doesn't work
return (new Response($file, 200))->header('Content-Type', $mime);
}
}
I want to get a default image if the profile picture is not found or not uploaded. How can I do so?
Thanks,
K
For something like this I would just override the accessor (aka getter) on your User model.
http://laravel.com/docs/master/eloquent-mutators#accessors-and-mutators
Any database column, such as profilepicture_filename can be manipulated after it's retrieved using a get___Attribute method, where ___ is the column name in Camel Case
class User
{
/**
* #return string
*/
public function getProfilepictureFilenameAttribute()
{
if (! $this->attributes['profilepicture_filename'])) {
return '/images/default_profilepicture.png';
}
return $this->attributes['profilepicture_filename'];
}
}
Now you simply have to do
<img src="{{ asset($user->profilepicture_filename) }}">
And it will display either their picture or the default if they don't have one. You no longer need the thumbnail route.
you could just do in you view:
#if(!file_exist($file->name))
<img src="/path/to/default.png">
#else
<img src="{{$file->name}}">
#endif
or in your controller:
if(!$file)
{
$file = '.../default/blah.png';
}
Related
I'm using Laravel 9 and I wanted to show an image which is stored at storage/app/avatars.
So I tried this at the Blade:
{{ \App\Http\HelperClasses\ImageHelper::admAvatar() }}
And this is the ImageHelper Class:
namespace App\Http\HelperClasses;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
class ImageHelper
{
public static function admAvatar()
{
$content = Storage::get('avatars/profile.png');
return Response::make($content)->header('content-type','image/jpeg');
}
}
So I tried making an image from the profile.png and return it after all.
But the problem is it does not show anything!
And when I dd(Response::make($content)->header('content-type','image/jpeg')), I get this:
And the result of dd($content) also goes like this:
So how can I convert this properly into an image?
I did it like this
Controller:
public function getFile($type, $id) {
$attachment = Attachment::where([['parent_type', $type], ['parent_id', $id]])->latest()->firstOrFail();
$headers = ['content-type' => 'image/jpeg'];
$contents = Storage::get($attachment->file_path);
return response($contents, 200, $headers);
}
Routes:
Route::get('/attachments/display/{type}/{id}', [App\Http\Controllers\AttachmentController::class, 'getFile']);
HTML:
<img src="/attachments/display/avatar/1" />
I am passing data to the view of the component by $user->profile->profile_pic when I dd in that view it shows the desired value perfectly. But when I use that in some conditions or in tags to print that value it says that Attempt to read property "profile_pic" on null. Although, It is not because I can die and dump that and that value can be seen
Usage of the component:
<x-details
:user="$user->id"
class="w-96 mt-10 py-4"
letter="{{ $user->username[0] }}"
editable="{{ Auth::user()->username == $user->username }}"
profile_pic="{{ $user->profile->profile_pic }}"
/>
The component
<?php
namespace App\View\Components;
use Illuminate\View\Component;
use App\Models\User;
use Illuminate\Support\Facades\DB;
class details extends Component
{
/**
* Create a new component instance.
*
* #return void
*/
public $user;
public function __construct($user = 1)
{
$this->user = $user;
}
/**
* Get the view / contents that represent the component.
*
* #return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render()
{
$user = User::with(['profile'])->firstWhere("id", $this->user);
$pic = $user->profile->profile_pic;
return view('components.details', compact("pic"));
}
}
The view of the component
<div>
#props([
"letter" => "A",
"editable" => 0,
"profile_pic" => 0
])
{{-- #php
$src = "";
if($profile_pic) {
$src = "/uploads/$profile_pic";
} else {
$src = url("fonts/icons/avatars/$letter.svg");
}
#endphp --}}
<div>
{{-- #dd($pic) --}}
{{ $pic }}
{{-- #if(!$editable)
#else
<form id="fileUpload">
<input class="hidden" type="file" name="upload_pic" id="upload_pic">
</form>
#endif --}}
</div>
</div>
It's a common issue when you trying to dd() something in foreach, it will always dump first item only and die, so you are always confirm first item and think it work as well as expected.
In your case, there is probably some user doesn't have profile_pic or profile don't have any profile_pic related on it.
Try to use the code below to debug with it in your component.
public function render()
{
try {
$user = User::with(['profile'])->firstWhere("id", $this->user);
$pic = $user->profile->profile_pic;
return view('components.details', compact("pic"));
} catch (Exception $e) {
dd($user->profile);
}
}
Inside the component, you should use $this:
So instead of
$pic = $user->profile->profile_pic
You should do
$pic = $this->user->profile->profile_pic
I'm stuck with putting a html output in Laravel 7 & nova 3.8
according to: https://nova.laravel.com/docs/3.0/search/global-search.html#title-subtitle-attributes
i try to make a function that put a html image in front of some resource on index pages:
public function title()
{
return "<img width='20px' height='10px' src='./flags/".$this->country.".png' >";
}
I read that laravel 7 use {!! !!} ( https://laravel.com/docs/7.x/blade#displaying-data )
But if i use it in resource file in app/nova/some-resource.php php gives error.
How to easy put a image based on country field in resource title ?
--
update 23.08.2020
I tried to create a Text field in my resource as it can have ->asHtml()
and i have a nice flag image on index and detail view
public function fields(Request $request)
{
return [
(...)
Text::make('Country Flag',
function () {
return "<img width='20px' height='10px' src='http://fishmarket.nowakadmin.com/flags/".$this->country.".png' >";
})->asHtml(),
(...)
]};
and in title i changed to:
public function title()
{
return $this->country_flag.' '.$this->name;
}
Result is that title looks like
''' '.$this->name // it looks like $this->country_flag = '';
The only wat to achieve goal of use html in field as i found:
Instead of just belongsTo i used Stack to use html in Text and data from other needed fields:
Stack::make('Details', [
Text::make('Country',
function () {
$flaga = DB::table('companies')->where('id', $this->company_id)->first();
return "<img width='20px' height='10px' src='/flags/".$flaga->country.".png'> ".$flaga->country;
})->asHtml()
->sortable(),
BelongsTo::make('Company')
->default(function ($request) {
return $request->user()->company_id;
})
->sortable(),
]),
And i have some html with flag image and company id in single field on resource without even touching resource $title
try this:
// for index
public static function label()
{
// input your logic to show label
return 'Your Label Index';
}
Hi everyone I want to add a file, not an image. There are different types of files in laravel. With the file I need to upload the user id to the database but I don't know how to store it in controller, here are my scripts:
Controller.php:
public function uploaded(Request $request, $id)
{
$client = Client::findOrFail($id);
$path = $request->image->store('storage/uploads','public');
return back();
}
upload.blade.php
{!! Form::open(['action' => ['FileController#upload', $client->id, 'files' => 'true']]) !!}
{!!Form::file('image') !!}
{!!Form::submit('Upload File') !!}
{!! Form::close() !!}
and web.php
Route::post('upload/{id}/', 'FileController#uploaded');
Can you explain me how to do it correctly?
Just change your upload.blade.php as
{!! Form::open(['route' => ['file.upload', $client->id, 'files' => 'true']]) !!}
{!!Form::file('image') !!}
{!!Form::submit('Upload File') !!}
{!! Form::close() !!}
and your web.php to
Route::post('upload/{id}/', 'FileController#uploaded')->name('file.upload');
I little confuse about your question. But I hope my answer can help you with your problem.
First Answer:
If you want to save the file in database I think you can save it with store the file path only in another table, we can call it user_files with this structure:
user_files
| id | user_id | file |
| 1 | 2 | /home/name/file
And the relations between this table and clients table is oneToMany.
so in your Client.php will be have this method:
Client.php
public function files() {
return $this->hasMany(File::class, 'user_id');
}
and your File.php will be have this method:
File.php
public function client() {
return $this()->belongsTo(Client::class, 'user_id');
}
After that, now we move in controller that handle upload method. We should save the file with associate the data from client.
public function uploaded(Request $request, $id)
{
$client = Client::findOrFail($id);
// If you need to upload file not only image, I think you should use $request->file() method;
$file = $request->file('file');
// And then we save the name use this method, maybe you want to save it with change the name and include the user_id
$name = 'User' . '#' . $client->id . '.' . $file->getClientOriginalExtension();
// It will make the file named 'User#2.doc'
// After that we move the file in 'uploads' directory or other public directory you want.
$file->move(public_path('uploads'), $name);
$newFile = new File;
$newFile->file = public_path('uploads') . '/' . $name;
$newFile->client()->associate($client);
$newFile->save();
return back();
}
That if you want to save the file in database with user_id as identifier, and also you can access it as usual, like if you want to access the image file:
<img src="{{$newFile->file}}" />
Second Answer
But if you only want to save the file with the name of user_id you can use only the method in controller:
public function uploaded(Request $request, $id)
{
$client = Client::findOrFail($id);
// If you need to upload file not only image, I think you should use $request->file() method;
$file = $request->file('file');
// And then we save the name use this method, maybe you want to save it with change the name and include the user_id
$name = 'User' . '#' . $client->id . '.' . $file->getClientOriginalExtension();
// It will make the file named 'User#2.doc'
// After that we move the file in 'uploads' directory or other public directory you want.
$file->move(public_path('uploads'), $name);
return back();
}
I have to store and retrieve an image from the database.
I want to store an image instead of image path or image name. When I searched for it I only found solutions for storing an image path or name. So can someone tell me how to store and retrieve an image with its size in KBs from database?
This is my route.
Route::get('big_image/{id}/image', function ($id)
{
$user = big_image::find($id);
return response()->make($user->image, 200, array(
'Content-Type' => (new finfo(FILEINFO_MIME))->buffer($user->image)
));
});
This is my controller
public function new_store(Request $request ,$id){
$event_id = $id;
$img = new big_image;
$file = $request->file('image');
$contents = $file->openFile()->fread($file->getSize());
$img = big_image::find($id);
$img->image = $contents;
$img->image_name = $request->image_name;
$img->event_id = $event_id;
$img->save();
$images=DB::table('big_image')->where('event_id','=',$event_id)->get();
return view('image_upload',compact('images','id','response'));
}
My display.blade.php file
#extends('app')
#section('content')
<h2 style="text-align: center;margin-top: 10px;">Image Gallery</h2>
<span> add more pictures</span><br>
<span>Back to events</span><br>
#foreach($images as $item)
<div class="col-sm-4">
{{--<img src="data:image/jpeg;base64,'.base64_encode( $item->image ).'"/>;--}}
</div>
#endforeach
#stop
Actually with Laravel it only involves a few lines of code. Let's say you have a user that has an avatar which is stored in the database. Assuming you're using MySQL, here's how you would store and retrieve the avatar from the database:
1. First you'll need to have an avatar column in the users table that can store binary data. Depending on how large you want to allow the avatar image to be, the data type of the column can be one of the following:
BLOB up to 64KB
MEDIUMBLOB up to 16MB
LONGBLOB up to 4GB
2. To store the uploaded image in the database you can do this:
Route::post('user/{id}', function (Request $request, $id) {
// Get the file from the request
$file = $request->file('image');
// Get the contents of the file
$contents = $file->openFile()->fread($file->getSize());
// Store the contents to the database
$user = App\User::find($id);
$user->avatar = $contents;
$user->save();
});
3. To fetch and ouput the avatar you can do the following:
Route::get('user/{id}/avatar', function ($id) {
// Find the user
$user = App\User::find(1);
// Return the image in the response with the correct MIME type
return response()->make($user->avatar, 200, array(
'Content-Type' => (new finfo(FILEINFO_MIME))->buffer($user->avatar)
));
});
So to access the avatar of the user with an id equal to 10 you can just use this URL:
http://domain.com/user/10/avatar
You can store files in database in blob fields.
Maybe this link helps you
Then You can create url to your image:
Route::get('/images/{image}', function($image)
{
header("Content-type: image/jpeg");
//"select image from table where id = $image"
echo $here_I_get_my_img_from_DB;
});
and get img from url: /image/{img_id}