Trouble printing out image from public folder laravel - php

I want to show the image that I had just uploaded and only show it to those who have uploaded it. For example, user table contain jack, Emily and John, so if jack were to upload a file the image will show directly under him, but I don't know how to do it?
This is how it look like now:
Controller: (how I store the image)
public function store1(Request $request){
$this->validate($request, [
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if ($request->hasFile('file')) {
$image = $request->file('file');
$name = $image->getClientOriginalName();
$size = $image->getClientSize();
$destinationPath = public_path('/images');
$image->move($destinationPath, $name);
$userImage = new UserImage;
$userImage->name = $name;
$userImage->size = $size;
//dd($userImage);
$userImage->save();
}
view.blade.php
#foreach ($data as $object)
<b>Name: </b>{{ $object->name }}<br><br>
#endforeach
I saw people using this inside their blade.php, but I don't know what the $model is:
<img src="{{ asset('public/images/' . $model->image) }}">
Upload.blade.php (this is my upload page where user will upload their image)
{{ csrf_field() }}
<div class="form-group">
<label for="imageInput" class="control-label col-sm-3">Upload Image</label>
<div class="col-sm-9">
<input type="file" name="file">
</div>
</div>
<div class="form-group">
<div class="col-md-6-offset-2">
<input type="submit" class="btn btn-primary" value="Save">
</div>
</div>
</form>

There are many ways to do it.
You could either use Eloquent or using query builder of Laravel.
In your controller you should get all the images that the user uploaded.
Query builder approach :
//don't forget the namespace
`use DB;`
//in your function write this.
$images = DB::table('user_images')
->join('users', 'users.id', '=', 'user_images.user_id')
->where('users.id', '=', $id)
->get();
//use dd($images) to verify that the variable $images has data
//send $images in your view
in your view write a foreach loop like so:
#foreach($images as $image)
<img src="{{ asset('public/images/' . $image->name ) }}">
#endforeach

Related

Display image from create model blade

I have a model and when I am creating a new one I want to be able to store an image from controller, like this:
public function create($id)
{
//
$user = User::FindOrFail($id);
$photos = Photo::all();
return view('posts.create', ['user'=>$user, 'photos'=>$photos]);
}
public function store(Request $request, $id)
{
//
$validateData = $request->validate([
'title' => 'required|string',
'text' => 'nullable|max:255',
'image' => 'nullable|image|mimes:jpg,png,jpeg,gif,svg|max:2048',
'user_id' => 'nullable|int',
]);
// return 'passed validation';
$size = $request->file('image')->getSize();
$name = $request->file('image')->getClientOriginalName();
$request->file('image')->storeAs('public/images/', $name);
$photo = new Photo();
$photo->name = $name;
$photo->size = $size;
$photo->save();
$a = new Post;
$a->title = $validateData['title'];
$a->text = $validateData['text'];
$a->image = $photo;
$a->user_id = $id;
$a->save();
session()->flash('message', 'Post was created');
return redirect()->route('posts.index', ['id'=>$id]);
}
While I try to also display all available images in create blade:
<form method="POST" action="{{route('posts.store', ['id'=>$user->id])}}">
#csrf
<p>Title: <input type="text" name="title" value="{{old('title')}}"></p>
<p>Text: <input type="text" name="text" value="{{old('text')}}"></p>
#csrf
<input type="file" name="image">
<input type="submit" name="Upload">
<ul>
#foreach ($photos as $photo)
<li>
<p>
{{ $photo->name }}
</p>
<img src="{{ asset('storage/images/'. $photo->name) }}">
</li>
#endforeach
</ul>
Cancel
When I try to submit I get the following errors:
The image must be an image.
The image must be a file of type: jpg, png, jpeg, gif, svg.
This error can't be true as I try to upload only jpg and png images, but I can't understand where I do something wrong.
Edit: Is there a way to store the image without declaring a new model?

Get the actual file name and extention from image file in laravel

When I am uploading an image to the form and returning it from the controller, the image name and extention are changing.I am a beggar, so if I make a mistake while asking a question, I would like to apologize.
This is my form:
<form action="{{ route('admin.slider.store') }}" method="POST" enctype="multipart/form-data">
#csrf
<div class="row">
<div class="col-md-12">
<label class="control-label">Image</label>
<input type="file" name="image">
</div>
</div
<button type="submit" class="btn btn-success">Save</button>
</form>
This is my controller:
public function store(Request $request)
{
$this->validate($request, [
'image' => 'required|mimes:jpeg,bmp,png,jpg',
]);
$image = $request->file('image');
return $image;
}
My image file name is :demo.jpg
Controller return result is like that:
C:\xampp\tmp\php5E86.tmp
This is the same result when I give another picture, only the last four characters are changing.
C:\xampp\tmp\phpF239.tmp
It is very helpful to know why I am getting .tmp file return.
use getClientOriginalName to get orginal file name
$request->image->getClientOriginalName()
To get file extension
$request->image->extension();
or
$name = $request->file('image')->getClientOriginalName();
$extension = $request->file('image')->extension();
Ref:https://laravel.com/docs/8.x/filesystem#other-uploaded-file-information

How to attach/upload more images in laravel user mysql database row where there are uploaded images from the past

Please help me, in Laravel, I have a database, where I have users and patients. In the patients table, I have an "image" row, I upload the multiple images there, their names are imploded by " | " and the directory is /images-patients. It all works fine, but I have a problem when I want the user to attach more images to the current patient, making them more. In PatientController in the update function, I use the same code with the form, for attaching more images and when I want to attach the images to the patient, it removes the old ones and replaces them with the newly uploaded ones. How can I attach more images, by just adding more images in the array, being imploded by " | ", without removing the previously uploaded ones to the patient, when the form is submitted? Here is my code:
patient.blade.php
<div class="card-header">Attach image to a patient {{ $patient -> name }} <span class="float-right" id="close-edit-details-modal" style="cursor:pointer;"><b>X</b></span>
</div>
<div class="card-body">
{{-- Forms --}}
<form action="{{ route('admin.patients.update') }}" enctype="multipart/form-data" method="POST">
#csrf
#method("PUT")
<input type="text" name="id" value="{{ $patient -> id }}" hidden>
<div class="form-group">
<label for="image">Image</label>
<input type="file" multiple="multiple" name="image[]" />
</div>
<input type="submit" class="btn btn-primary btn" value="Attach the image">
</form>
PatientController.php
public function update(Request $request)
{
$request -> validate([
'image' => 'required',
]);
$destinationPath = './images-patients/';
$images=array();
if($files=$request->file('image')){
foreach($files as $file){
$filename=$file->getClientOriginalName();
$file->move($destinationPath, $filename);
$images[]=$filename;
}
}
$allImages = implode(" | ", $images);
$patient = Patient::find($request -> id);
$patient -> image = $allImages;
$patient -> save();
return redirect('admin/patient/' . $patient->id)-> with('success', 'Successfully attached photos to a patient!');
}
web.php
Auth::routes();
Route::middleware('auth', 'isAdmin')->namespace('admin')->group(function(){
Route::get('/users', 'UsersController#index')->name('admin.users');
Route::get('/admin/settings', 'SettingsController#index')->name('admin.settings');
Route::get('/admin/user/{id}', 'UsersController#getUser')->name('admin.user');
Route::get('/admin/patients', 'PatientController#index')->name('admin.patients');
Route::get('/admin/patient/{id}', 'PatientController#show')->name('admin.patient');
Route::get('/admin/blank', 'BlankController#index')->name('admin.blank');
Route::get('/admin/patients/search', 'PatientController#searchPatients')->name('admin.patients.search');
Route::get('/admin/patients/usearch', 'PatientController#searchUsers')->name('admin.patients.usearch');
Route::put('/admin/patients/update', 'PatientController#update')->name('admin.patients.update');
Route::post('/admin/users/store', 'UsersController#store')->name('admin.user.store');
Route::post('/admin/patients/store', 'PatientController#store')->name('admin.patients.store');
Route::put('/admin/user/update', 'UsersController#update')-> name('admin.user.update');
});
Route::get('/', 'HomeController#index')->name('home');
One little change is required in the PatientController to get the results you desire.
public function update(Request $request)
{
$request -> validate([
'image' => 'required',
]);
$destinationPath = './images-patients/';
$images=array();
if($files=$request->file('image')){
foreach($files as $file){
$filename=$file->getClientOriginalName();
$file->move($destinationPath, $filename);
$images[]=$filename;
}
}
$allImages = implode(" | ", $images);
$patient = Patient::find($request -> id);
//Append the names of newly uploaded files to the existing value
$patient->image .= " | $allImages";
$patient->save();
return redirect('admin/patient/' . $patient->id)-> with('success', 'Successfully attached photos to a patient!');
}

Display a link if an item has a PDF in laravel

I am trying to get an item to display a link to PDF if that item has a PDF associated with it. I am not sure how the if statement would be formatted. I am using Laravel for this.
Here is the code that I have in the controller for the item:
//PDF Upload
if($request->hasFile('spec_sheet')) {
//Get file name and extension
$filenameWithExt = $request->file('spec_sheet')->getClientOriginalName();
//Get just file name
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
//Get Ext
$extension = $request->file('spec_sheet')->getClientOriginalExtension();
//Store file name
$fileNameOfPdfToStore = $filename. '.' .$extension;
//Upload
$path = $request->file('spec_sheet')->storeAs('public/mcelroy-specs', $fileNameOfPdfToStore);
}
$rental = new Rental;
$rental->title = $request->title;
$rental->name = $request->name;
$rental->description = $request->description;
$rental->product_image = $fileNameToStore;
$rental->spec_sheet = $fileNameOfPdfToStore;
$rental->save();
In the view I have this:
#foreach($rentals as $rental)
<article class="cards-item">
<figure class="card product">
<div class="card-images">
<img src="/storage/rentals/{{$rental->product_image}}" alt="" >
</div>
<figcaption class="card-content">
<h1 class="card-title">{{ $rental->title }}</h1>
<h2 class="card-title product_title">{{ $rental->name }}</h2>
<p class="card-text" style="text-align:left;">{{ $rental->description }}
#if(!empty($spec_sheet))
Download Spec Sheet
#endif
</p>
<form action="{{ route('cart.store') }} " method="POST">
{{ csrf_field() }}
<input type="hidden" name="id" value="{{ $rental->id }}">
<input type="hidden" name="title" value="{{ $rental->title }}">
{{-- <input type="hidden" name="pickupDate" value="{{ $rental->pickupDate }}">
<input type="hidden" name="returnDate" value="returnDate"> --}}
<div class="buttons">
<div class="back">
<button class="primary button" type="submit">Add to Cart</button>
</div>
</div>
</form>
</figcaption>
</figure>
</article>
#endforeach
Seems like you are looking for the right way to do something in Laravel, but there is no right way.
Given
#if(!empty($spec_sheet))
Download Spec Sheet
#endif
I would make two changes, 1) shouldn't $spec_sheet be $rental->spec_sheet? and 2) swap out the #if(!empty(...)) with #unless(empty()) as I feel that including a ! will make it harder to understand when you come back to this in a few weeks.
So I am suggesting you use this which should be just fine, since there's no right way to do this in Laravel.
#unless(empty($rental->spec_sheet))
Download Spec Sheet
#endunless
Your code above will not work if there is no PDF attached, as the variable $fileNameOfPdfToStore will not exist and a hard error will be thrown. But assuming you fix that issue and store an empty string for the file name or perhaps NULL instead of the file path, then you could create a new attribute in the Rental model that looks like this:
public function getHasSpecSheetAttribute() {
return $this->spec_sheet==null? false:true;
}
Then in your view you would do this:
#if($rental->hasSpecSheet)
Download Spec Sheet
#endif
In order to fix the PDF upload code, just put an else statement and put this inside of it:
$fileNameOfPdfToStore = null;
#if(strlen({$rental->spec_sheet) > 0))
Download Spec Sheet
#endif
use string length to determine if there was file name uploaded or not

Laravel: Can't get uploaded images to display

On my website, a registered user can create a post by uploading an image and writing a description. I have made it where a unique image name is created based on the user's image name and the time they upload the image. Once a name is created it is stored in the post database. The image name successfully gets stored and so does the actual image. However, when it comes to actually displaying the image on the post nothing comes up like it can't find the image. I can't seem to figure out why this is.
Here is my PostController.php class:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class PostController extends Controller
{
public function getDashboard(){
$posts = Post::orderBy('created_at', 'desc')->get();
return view('dashboard', ['posts' => $posts]);
}
public function postCreatePost(Request $request){
$this->validate($request, [
'body' => 'required',
'cover_image' => 'image|nullable|max:1999'
]);
if($request->hasFile('cover_image')){
$filenameWithExt = $request->file('cover_image')->getClientOriginalName();
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
$extension = $request->file('cover_image')->getClientOriginalExtension();
$fileNameToStore = $filename . '_' . time() . '.' . $extension;
$path = $request->file('cover_image')->storeAs('public/cover_images', $fileNameToStore);
} else{
$fileNameToStore = 'noimage.jpg';
}
$post = new Post();
$post->body = $request['body'];
$post->cover_image = $fileNameToStore;
$message = 'There was an error';
if($request->user()->posts($post)->save($post)){; //points here
$message = 'post successfully created';
}
return redirect()->route('dashboard')->with(['message' => $message]);
}
public function getDeletePost($post_id){
$post = Post::where('id', $post_id)->firstOrFail();
$post->delete();
return redirect()->route('dashboard')->with(['message' => 'post deleted']);
}
}
Here is my view:
<section class="row new-post">
<div class="col-md-6 col-md-offset-3">
<form action="{{ route('postcreate') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<input type="file" name="cover_image" class="form-control" id="cover_image">
</div>
<div class="form-group">
<textarea class="form-control" name="body" rows="5" placeholder="your post"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create post</button>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
</div>
</section>
#foreach($posts as $post)
<section class="row posts">
<div class="col-md-6">
<article class="post">
<p>{{ $post->body }}</p>
<div class="info">Posted by {{ $post->user->first_name }} {{ $post->user->last_name }} on {{ $post->created_at }}</div>
<div class="interaction">
Like|
#if(Auth::user() == $post->user)
Edit|
Delete
#endif
</div>
</article>
</div>
<div class="col-md-6">
<img src="/storage/cover_images/{{ $post->cover_image }}">
</div>
</section>
#endforeach
Here is my migration:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('cover_image');
$table->text('body');
$table->integer('user_id');
});
You're storing as public/cover_images but echoing out storage/cover_images.
Updated following your response;
Why not try using
<img src="{{ asset('storage/cover_images/' . $post->cover_image) }}">

Categories