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?
Related
i am new using codigniter. i am trying to display images from the mysql database by sending them to the database using a create page where you can type in a title, some info and select an image, everything displays after creating a project except for the image. once i open phpmyadmin it shows that there is data for the image but it looks like it's only MetaData and not the actual image itself. i have been stuck on this for a couple of days now so i hope you guys could help me out!
create function in The Controller (edited):
public function create(){
$model = new ProjectModel();
$file = $this->request->getFile('image');
if ($this->request->getMethod() === 'post' && $this->validate([
'title' => 'required|min_length[3]|max_length[255]',
'info' => 'required',
'image' => 'uploaded[image]',
]))
{
$model->save([
'title' => $this->request->getPost('title'),
'slug' => url_title($this->request->getPost('title'), '-', TRUE),
'info' => $this->request->getPost('info'),
$tempfile = $file->getTempName(),
$imgdata = file_get_contents($tempfile),
]);
var_dump($imgdata);
#echo view('project/success');
}
else
{
echo view('site/create');
}
}
My Model
namespace App\Models;
use CodeIgniter\Model;
class ProjectModel extends Model
{
protected $table = 'projects';
protected $allowedFields = ['title', 'slug', 'info', 'image'];
public function getProjects($slug = false)
{
if ($slug === false)
{
return $this->findAll();
}
return $this->asArray()
->where(['slug' => $slug])
->first();
}
}
this is the file that creates a div element once you press the create button
<?php if (! empty($projects) && is_array($projects)) : ?>
<?php foreach ($projects as $project_item): ?>
<div class="project-box" href="/projects/<?= esc($project_item['slug'], 'url') ?>">
<?php echo '<img class="project-image" src="data:image/jpeg;base64,'.base64_encode($project_item['image']).'" alt="image" ">'?>
<p class="project-name"><?=esc($project_item['title'])?></p>
<div class="bottom-border">
<p class="project-creator"><i class="far fa-user-circle"></i> <?=esc($project_item['creator'])?></p>
<div class="statistics">
<p class="project-likes"><i class="fas fa-heart"></i> <?=esc($project_item['likes'])?></p>
<p class="project-views"><i class="far fa-eye"></i> <?=esc($project_item['views'])?></p>
</div>
</div>
</div>
<?php endforeach; ?>
<?php else : ?>
<h3>No Projects</h3>
<?php endif ?>
this is the create file in which you can create a project
<div class="parent">
<?= \Config\Services::validation()->listErrors() ?>
<form action="/site/create" method="post">
<h1>Create Project</h1>
<?= csrf_field() ?>
<div class="form-group">
<input class="ph-title" type="input" name="title" placeholder="Title" /><br/>
</div>
<div class="grow-wrap">
<textarea class="ph-info" name="info" placeholder="Type in project info"></textarea>
</div>
<!-- <div class="file-input">
<label for="file">
Select file
<p class="file-name"></p>
</label>
</div> -->
<input class="file-btn" type="file" name="image" value=""/><br/>
<input class="create-btn" type="submit" name="submit" value="Create Project"/>
</form>
</div>
What am i doing wrong?
There are a few things wrong here. First off, your form is set for image uploading, but needs the enctype added to the form tag so that your backend PHP can recieve the $_FILES object
<form action="/site/create" method="post" enctype="multipart/form-data">
Remove the value="" from the input...
<input class="file-btn" type="file" name="image" />
Now you're ready to receive a file - see https://codeigniter4.github.io/userguide/libraries/uploaded_files.html
Your validation should be altered
$this->validate([
//... your other validations...
'image' => 'uploaded[image]' // instead of required
]);
If you want to store the image on your server and then record the name of the image in the database to retrieve later:
$imageDirectory="/path/to/where/you/store/images";
$imageName = $file->getRandomName();
$path = $this->request->getFile('image')->store($imageDirectory, $imageName);
// path is now the full path to the image on your server.
if you want to store the image BLOB data instead (like your example):
$tempfile = $file->getTempName();
$imgdata = file_get_contents($tempfile);
Then your insert would look like this...
$model->save([
'title' => $this->request->getPost('title'),
'slug' => url_title($this->request->getPost('title'), '-', TRUE),
'info' => $this->request->getPost('info'),
'image' => $imgdata,
]);
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!');
}
Here's my HTML:
<label for="attachement1">Attach a file: <small style="color:#999;">(type: zip/rar and below 10mb)</small></label>
<input type="file" name="file1"/><br/>
<label for="snapshot">Snapshot / Thumbnail:</label>
<input type="file" name="thumbnail" required/><br/>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class="btn btn-primary" name="Submit" value="Publish" />
Here is the code in my controller file (for the update function):
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'thumbnail' => 'mimes:jpg,jpeg,png|max:800',
'file1' => 'mimes:rar,zip|max:10000',
]);
$file1=$request->file('file1');
if(is_null($request->file('file1'))){
$p=pages::where('id', '=', $request['id'])->first();
$attmt1=$p->attachment;
}
else
{
$upload_dir='uploads';
$attmt1=$file1->getClientOriginalName();
$move=$file1->move($upload_dir, $attmt1);
}
if(is_null($request->file('thumbnail'))){
$p=pages::where('id', '=', $request['id'])->first();
$image=$p->thumbnail;
}
else
{
$img=$request->file('thumbnail');
$upload_dir='thumbnails';
$image=$img->getClientOriginalName();
$move=$img->move($upload_dir, $image);
//end thumbnail process
}
$mypage->title = $request->title;
$mypage->body = $request->body;
//$mypage->thumbnail = $request->thumbnail;
$mypage->slug = str_slug($request->slug, '-');
$mypage->menu_name = $request->menu_name;
$mypage->save();
return redirect()->route('menupages.index')->with('message', 'Page updated successfully.');
}
When I try to edit an item and upload an image (.jpg format), and click submit, I get a "The thumbnail must be a file of type: jpg, jpeg, png." I checked the database and the file was not recorded.
For some reason, it is detecting the image as some foreign image file type even though it is .jpg.
Are you Add enctype="multipart/form-data" on your form?
<form method="post" Action= "" enctype="multipart/form-data">
</form
When you want to upload something, you always need to add the following code to your form.
enctype="multipart/form-data"
If you don't do this, you can't upload something.
Did you add this to your html form?
I got help from a developer on this so I will post how we were able to solve the problem.
Here's the full revised code for the function:
Controller:
public function update(Request $request, $id)
{
$this->validate($request, [
'thumbnail' => 'mimes:jpg,jpeg,png|max:300000',
'file1' => 'mimes:rar,zip|max:10000',
]);
$file1 = $request->file('file1');
if(is_null($request->file('file1'))){
// $p=pages::where('id', '=', $request['id'])->first();
$p = MenuPage::find($request['id']);
$attmt1 = $p['attachment'];
}
else
{
$upload_dir = 'uploads';
$attmt1 = $file1->getClientOriginalName();
$file1->move($upload_dir, $attmt1);
}
if(is_null($request->file('thumbnail'))){
// $p=pages::where('id', '=', $request['id'])->first();
$p = MenuPage::findOrFail($request['id']);
$image = $p->thumbnail;
}
else
{
$img = $request->file('thumbnail');
$upload_dir = 'thumbnails';
$image = $img->getClientOriginalName();
$img->move($upload_dir, $image);
//end thumbnail process
}
//$check=pages::where('id', $request['id'])
//->update([
// 'title' => $title,
// 'body' =>$body,
// 'thumbnail' =>$thumbnail,
// 'slug' =>$slug,
// 'school' =>$school,
// 'attachment' =>$attmt1,
// 'menu_name' =>$menu_name,
// ]);
$mypage = MenuPage::find($id);
$mypage->title = $request->title;
$mypage->body = $request->body;
$mypage->thumbnail = $image;
$mypage->attachment = $attmt1;
$mypage->slug = str_slug($request->slug, '-');
$mypage->menu_name = $request->menu_name;
$mypage->save();
return redirect()->route('menupages.index')->with('message', 'Page updated successfully.');
}
View file (the bottom part):
<label for="attachement1">Attach a file: <small style="color:#999;">(type: zip/rar and below 10mb)</small></label>
<input type="file" name="file1"/><br/>
<label for="snapshot">Snapshot / Thumbnail:</label>
<input type="file" name="thumbnail" required/><br/>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input name="_method" type="hidden" value="PUT">
<input type="submit" class="btn btn-primary" name="Submit" value="Publish" />
I can get photos to upload as a user,
but I need to be able to pick that photo I just uploaded and display it as an avatar?
the problem is all the photos from all the users go into the same public folder so not sure how to show only the photo that the user uploaded
I am using Laravel
here is my form:
<h1>File Upload</h1>
<form class="picwid" action="{{ URL::to('../user/edituser') }}" method="post" enctype="multipart/form-data">
<label>Select image to upload:</label>
<input type="file" name="file" id="file">
<input type="submit" value="Upload" name="submit">
<input type="hidden" value="{{ csrf_token() }}" name="_token">
</form>
here is my function:
public function uploads(Request $request) {
$users = DB::table('users')->where('id', '=', auth()->id())->latest()->get();
if(Input::hasFile('file')){
$file = Input::file('file');
$file->move('profilepics', $file->getClientOriginalName());
$myImage = '<img src="profilepics"/>' . $file->getClientOriginalName();
}
return view('edituser', compact(['baskets', 'myImage']));
}
and here is my avatar output:
<div class="media-left">
<img src="../profilepics/ty.jpg" class="media-object" style="width:60px">
</div>
I changed the function uploads to:
public function uploads() {
$users = DB::table('users')->where('id', '=', auth()->id())->latest()->get();
$users_id = auth()->id();
if(Input::hasFile('file')){
$file = Input::file('file');
$file->move("profilepics/ $users_id", $file->getClientOriginalName());
}
return view('edituser', compact(['baskets', 'myImage', 'users_id']));
}
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