I have this form to edit article and change photo:
<h1>Edit: {{$article->title}}</h1>
<hr>
{!! Form::model($article, ['method'=>'PATCH','files' => true, 'action'=>['ArticlesController#update', $article->id]]) !!}
#include('articles.form',['submitButtonText'=>'Update Article'])
{!! Form::close() !!}
#include('errors.list')
now at Controller I have this function:
public function update($id, Requests\ArticleRequest $request)
{
$photo= 'http://nationaluasi.com/dru/content/hotelIcon.png';
$file = array('photo' => $request->file('photo'));
// setting up rules
$rules = array('photo' => 'required',); //mimes:jpeg,bmp,png and for max size max:10000
// doing the validation, passing post data, rules and the messages
$validator = Validator::make($file, $rules);
if ($validator->fails()) {
// send back to the page with the input data and errors
$photo = 'http://nationaluasi.com/dru/content/hotelIcon.png';
}
else {
// checking file is valid.
if ($request->file('photo')->isValid()) {
$destinationPath = public_path().'/images'; // upload path
$extension = $request->file('photo')->getClientOriginalExtension(); // getting image extension
$photo = str_random(5).'.'.$extension; // renameing image
$request->file('photo')->move($destinationPath, $photo); // uploading file to given path
// sending back with message
}
else {
}
}
$article = Auth::user()->articles()->findOrFail($id);
$article['photo'] = $photo;
$article->update($request->all());
Alert::message('Your auction is updated', 'Wonderful!');
return redirect('auctions');
}
but now when I try to submit uploaded photo I get this result in column photo: C:\wamp\tmp\php21F4.tmp but also image is uploaded into /images folder...
What is the problem here? How to update article... also I want to say that is everything fine when I add article - add photo so on method store everything is the same and work fine...
UPDATE:
I try:
$article = Auth::user()->articles()->findOrFail($id);
$article['photo'] = $photo;
dd($photo);
and everything is fine, photo is uploaded succesfully just i dont update article['photo']... so problem is here:
$article->update($request->all());
But how to solve it? Why article['photo'] is not updated ?
I tried to correct your code, use this.
public function update($id, Requests\ArticleRequest $request)
{
$this->validate($request, [
'photo' => 'required|image|max:10000',
// validate also other fields here
]);
// checking file is valid.
if (!$request->file('photo')->isValid()) return redirect()->back()->withErrors(["photo" => "File is corrupt"]);
// file is valid
$destinationPath = public_path().'/images'; // upload path
$extension = $request->file('photo')->getClientOriginalExtension(); // getting image extension
$filename = str_random(5).'.'.$extension; // give a name to the image
$request->file('photo')->move($destinationPath, $filename); // uploading file to given path
// sending back with message
$article = Auth::user()->articles()->findOrFail($id); //if article id is unique just write Article::findOrFail($id)
$article_fields = $request->except('photo');
$article_fields['photo'] = $filename;
$article->update($article_fields);
Alert::message('Your auction is updated', 'Wonderful!');
return redirect('auctions');
}
I'll assume you're using Laravel 5. I believe the issue is this line:
$article->update($request->all());
The update method expects an array of column and value pairs. Your code above is giving it the original (unmodified) request which doesn't include your new photo location.
With Laravel you can actually get the article object, set the column directly within the object and then save the changes.
Try changing the last few lines of your method to:
$article = Auth::user()->articles()->findOrFail($id); // get the article
$article->photo = $photo; // set the photo column to your new location
$article->save(); // this will save your changes
Alert::message('Your auction is updated', 'Wonderful!');
return redirect('auctions');
Take a look at the Laravel documentation for more explanation.
Related
//Here is my edit form (image field)
I have an edit form which has an image field where a user can upload a new image if he wants to.
But if the user does not upload a new photo I want to just use the photo that's already in the database. And not update the image field at all. But in my code whenever I am trying to without uploading new image form is not taking the old input value.
<div class="form-group">
<input type="file" name="image">
</div>
//this is the update function
public function update(Request $request, $id)
{
$this->validate($request,[
'name' => 'required',
'image' => 'mimes:jpeg,bmp,png,jpg'
]);
// get form image
$image = $request->file('image');
$slug = str_slug($request->name);
$category = Category::find($id);
if (isset($image))
{
// make unique name for image
$currentDate = Carbon::now()->toDateString();
$imagename = $slug.'-'.$currentDate.'-'.uniqid().'.'.$image->getClientOriginalExtension();
// check category dir is exists
if (!Storage::disk('public')->exists('category'))
{
Storage::disk('public')->makeDirectory('category');
}
// delete old image
if (Storage::disk('public')->exists('category/'.$category->image))
{
Storage::disk('public')->delete('category/'.$category->image);
}
// resize image for category and upload
$categoryimage = Image::make($image)->resize(1600,479)->stream();
Storage::disk('public')->put('category/'.$imagename,$categoryimage);
// check category slider dir is exists
if (!Storage::disk('public')->exists('category/slider'))
{
Storage::disk('public')->makeDirectory('category/slider');
}
// delete old slider image
if (Storage::disk('public')->exists('category/slider/'.$category->image))
{
Storage::disk('public')->delete('category/slider/'.$category->image);
}
// resize image for category slider and upload
$slider = Image::make($image)->resize(500,333)->stream();
Storage::disk('public')->put('category/slider/'.$imagename,$slider);
} else {
$imagename = $category->image;
}
$category->name = $request->name;
$category->slug = $slug;
$category->image = $imagename;
$category->save();
Toastr::success('Category Successfully Updated :)' ,'Success');
return redirect()->route('admin.category.index');
}
// When i click on the edit button it shows the No file Chosen it is not displaying the old image ..
you should change your validation
in STORE function, you should give an image and upload it (if it is required)
but in UPDATE function maybe the user does'nt want to change image and user only wants to change for exmaple just the name, so user can select no image in update
so your validation in UPDATE must be NULLABLE.
$this->validate($request,[
'name' => 'required',
'image' => 'nullable|mimes:jpeg,bmp,png,jpg'
]);
I have this function where I want to update user background image so I write:
public function updateBg(Request $request)
{
$user = Auth::user();
$this->validate($request, [
'background' => 'image|max:10000',
// validate also other fields here
]);
// checking file is valid.
if (!$request->file('background')->isValid()) return redirect()->back()->withErrors(["background" => "File is corrupt"]);
// file is valid
$destinationPath = public_path().'/images/Custaccounts/'.$user->id; // upload path
$extension = $request->file('background')->getClientOriginalExtension(); // getting image extension
$ran = str_random(5);
$photo = $ran.'.'.$extension;
$request->file('background')->move($destinationPath, $photo); // uploading file to given path
$bg = $user->id.'/'.$photo;
dd($bg);
$user->update(['background' => $bg]);
return Redirect::back();
}
this line wont work: $user->update(['background' => $bg]); dd($bg) give me right string and image is uploaded just I cant update my 'background; field ...
also when I write:
$user->update(['background' => $bg, 'name'=>'John']);
name is updated but background not... at user model background field is fillable of cource
If i understand your problem you are trying to update the bg field form User table.. Your code must work. If not working Try this:-
Remove this :- $user->update(['background' => $bg]);
Update this :- User::where('id',Auth::user()->id)->update(['background' => $bg]);
Hope it helps!
First at all I'm sorry for my bad English, I have been searching all how to fix my problem (Image on database is gone when trying to not update the image) and I found this : codeigniter image update
My problem is pretty same like that question, but when I try to fix it to be like that its still error.
So I can update an image or change the old image into new image, but when I try to not update the image (maybe just edit the another values in form, not the image), the image value on database is gone (NULL). And what I want is when I not update the image, the image is still same like the old image. Here is my code, placed in same file on model directory :
Constructor :
public function __construct()
{
parent::__construct();
// Setting up the upload configuration
$config['upload_path'] = 'photo_dir/';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['file_ext_tolower'] = TRUE;
$config['max_size'] = 2048;
$this->load->library('upload', $config);
}
Function to get old image value :
// This function is to read the old image in database
private function _selected_img($id)
{
return $this->db->select()
->from('tb_exam')
->where('id_exam', $id)
->limit(1)
->get()
->row();
}
Update function :
// The update function
public function update($id)
{
// Get the old image first and declare it in variable `file`
$file = $this->_selected_img($id)->img;
// Upload the image
$this->upload->do_upload('img');
// If upload image data is not null, and then change the
// `file` value into the image file_name
if ($this->upload->data() !== '')
{
$file = $this->upload->data('file_name');
}
// Object to update
$this->object = array(
'id_teacher' => $this->input->post('id_teacher'),
'id_subject' => $this->input->post('id_subject'),
'question' => $this->input->post('question'),
'img' => $file,
'option_a' => $this->input->post('option_a'),
'option_b' => $this->input->post('option_b'),
'option_c' => $this->input->post('option_c'),
'option_d' => $this->input->post('option_d'),
'option_e' => $this->input->post('option_e'),
'answer_key' => $this->input->post('answer_key')
);
// Update the data
$this->db->where($this->main_id, $id)->update($this->table, $this->object);
// If record is success, return TRUE
// but if not, return FALSE
if ($this->db->affected_rows() > 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
All of your helps and answer is highly appreciated !
Have you got the old image name correctly. please check that by echo $file; exit;
if you are not getting the file name correctly use the following code to get the old image name$query = $this->db->get_where('tb_exam', array('id_exam' => $id));
$data=$query->result_array();
$file=$data[0]['img'];
use this code directly in your update function
I want to update a record in my model, and it contains a file field, here is the form code:
<div class="row">
<?php echo $form->labelEx($model,'img'); ?>
<?php echo CHtml::activeFileField($model,'img',array('width'=>25,'lentgh'=>25)); ?>
<?php echo $form->error($model,'img'); ?>
</div>
and here is the update action in the controller:
$model=$this->loadModel($id);
$img = $model->img;
if(isset($_POST['Press']))
{
$model->attributes=$_POST['Press'];
$model->img = $img;
if(isset($_POST['Press']['img'])){
if(!empty ($_POST['Press']['img']))
$model->img = CUploadedFile::getInstance($model, 'img');
So if the user didn't upload an image, the value of img attribute should not be updated and the model should be validated, but I got validation error every time I click on save and the img file filed is empty, so how I can fix this issue ?
Form validations are handeled by the model.
You can set an imagefield of filefield to be allowed to be empty like this in your model.php:
array('image', 'file', 'types'=>'jpg,png,gif',
'maxSize'=>1024 * 1024 * 5,
'allowEmpty' => true),
EDIT:
You can check if the file is empty before overwriting the current value of the object
$imageUploadFile = CUploadedFile::getInstance($model, 'image');
if($imageUploadFile !== null){ // only do if file is really uploaded
$imageFileName = mktime().$imageUploadFile->name;
$model->image = $imageFileName;
}
You can use csenario as:
array('image', 'file', 'types'=>'jpg,png,gif',
'maxSize'=>1024 * 1024 * 5,
'allowEmpty' => false, 'on'=>'insert'),
array('image', 'file', 'types'=>'jpg,png,gif',
'maxSize'=>1024 * 1024 * 5,
'allowEmpty' => true, 'on'=>'update'),
after that it will allow empty field on update
Faced the same issue and here is my solution.
But first I will describe how I work with models.
Basic POST processing
if (Yii::app()->request->getIsPostRequest()) {
$basicForm->attributes = Yii::app()->request->getParam(get_class($basicForm));
if ($basicForm->validate()) {
$logo = CUploadedFile::getInstance($basicForm, "logo");
if (!is_null($logo)) {
try {
// uploads company logo to S3
} catch (\Exception $e) {
// display any kind of error to the user or log the exception
}
}
if ($basicForm->save(false))
$this->refresh();
}
}
and my logo field has rule ["logo", "file", "mimeTypes" => ["image/png", "image/jpeg"], "allowEmpty" => true].
This rule gives me freedom to upload or not to upload the file, BUT if I want to change another form field not changing the file it will empty the model's logo field and my database too.
Problem
File gets empty if form update trying to update another form field, not file
Why it happening?
This happening because file validator expects CUploadedFile type of object when you have string in the model's logo field. String from database where you storing path to logo. And string is not CUploadedFile. And after if ($basicForm->validate()) model resets the logo field to null.
Solution
Own validation rule which will upload/reupload the file if logo is of hype `` and do nothing if logo of basic string type. Here I will put a basic "in-model" validator, it is up to you to move it into separate class, etc.
public function checkFile($attribute, $params)
{
$mimeTypes = isset($params["mimeTypes"]) ?$params["mimeTypes"] :[];
$allowEmpty = isset($params["allowEmpty"]) ?$params["allowEmpty"] :false;
/** #var CUploadedFile $value */
$value = $this->{$attribute};
if (!$allowEmpty && empty($value))
$this->addError($attribute, "{$attribute} can not be empty");
if (!empty($value)) {
if (is_object($value) && CUploadedFile::class === get_class($value) && 0 < sizeof($mimeTypes)) {
if (!is_array($value->type, $mimeTypes))
$this->addError($attribute, "{$attribute} file is of wrong type");
} elseif (!is_string($value)) {
// we can die silently cause this error won't actually ever get to the user in normal use cases
$this->addError($attribute, "{$attribute} must be of type either CUploadedFile or PHP string");
}
}
}
I called it checkFile and then the logo rule becomes ["logo", "checkFile", "mimeTypes" => ["image/png", "image/jpeg"], "allowEmpty" => true],
That is it. Enjoy.
Note: I'm putting this here as an example. Code may not be completely correct, or used as is, all the stuff like that... :)
I'had same problem. In my user model there wos a field containing path to image and i wanted to update model and fileField cleared my images.
So i figured workaround - store field containing path_to_file at start of action "update" in $tmp_variable and if there is no new upload - just set it before save():
public function actionUpdate($id)
{
$request = Yii::app()->request;
$model = $this->loadModel($id, 'YourModel');
$tmpPathToImage = $model->your_path_to_file_in_model;
$yourModelPost = $request->getPost('YourModel');
if (!empty($yourModelPost)) {
$model->setAttributes($yourModelPost);
$fileSource = Yii::getPathOfAlias('webroot.uploads.yourModel');
$imgTmp = CUploadedFile::getInstance($model, 'your_path_to_file_in_model');
if ($imgTmp !== null) {
$imgTmp->saveAs($fileSource.'/'.$imgTmp->name);
$model->your_path_to_file_in_model = '/'.UPLOADS_YOUR_MODEL_FILE_PATH_RELATIVE.'/'.$imgTmp->name;
}
else {
$model->your_path_to_file_in_model = $tmpPathToImage;
}
if ($model->save()) {
$this->redirect(['/admin/yourModel/index']);
}
}
$this->render('update', [
'model' => $model,
]);
}
Hope it helps someone... :)
I'm trying to learn to an process image form that uploads images to a database and lets users view the image on the website, this is done using Laravel 4. I must have some sort of bug, because the view doesn't have any errors, but when I select an image to upload and hit the "save" button on my form, nothing happens other than it looks like the form has been refreshed because the file is gone.
Routes
// This is for the get event of the index page
Route::get('/', array(
'as' => 'index_page',
'uses' => 'ImageController#getIndex'
));
// This is for the post event of the index page
Route::post('/', array(
'as' => 'index_page_post',
'before' => 'csrf',
'uses' => 'ImageController#postIndex'
));
ImageController.php
class ImageController extends BaseController {
public function getIndex()
{
// Let's first load the form view
return View::make('tpl.index');
}
public function postIndex()
{
// Let's validate the form first with the rules which are set at the model
$input = Input::all();
$rules = Photo::$upload_rules;
$validation = Validator::make($input, $rules);
// If the validation fails, we redirect the user to the index page, with errors
if ($validation->passes()) {
// If the validation passes, we upload the image to the database and process it
$image = Input::file('image');
// This is the original uploaded client name of the image
$filename = $image->getClientOriginalName();
// Because Symfony API does not provide filename
// without extension, we will be using raw PHP here
$filename = pathinfo($filename, PATHINFO_FILENAME);
// We should salt and make an url-friendly version of the file
$fullname = Str::slug(Str::random(8) . $filename) . '.' .
$image->getClientOriginalExtension();
// We upload the image first to the upload folder, then
// get make a thumbnail from the uploaded image
$upload = $image->move
(Config::get('image.upload_folder'), $fullname);
Image::make(Config::get('image.thumb_folder').'/'.$fullname)
->resize(Config::get('image.thumb_width'), null, true)
->save(Config::get('image.thumb_folder').'/'.$fullname);
// If the file is now uploaded we show a success message
// otherwise, we show an error
if ($upload) {
// image is now uploaded, we first need to add column to the database
$insert_id = DB::table('photos')->insertGetId(
array(
'title' => Input::get('title'),
'image' => $fullname
)
);
// Now we redirect to the image's permalink
return Redirect::to(URL::to('snatch/'.$insert_id))
->with('success', 'Your image is uploaded successfully!');
}
else {
// Image cannot be uploaded
return Redirect::to('/')->withInput()
->with('error', 'Sorry, the image could not be uploaded.');
}
}
else {
return Redirect::to('/')
->withInput()
->withErrors($validation);
}
}
Image Model
class Photo extends Eloquent {
// the variable that sets the table name
protected $table = 'photos';
// the variable that sets the table name
protected $fillable = array('title', 'image');
// the timestamps enabled
public $timestamps = true;
// Rules of the image upload form
public static $upload_rules = array(
'title' => 'required|min:3',
'image' => 'required|image'
);
}
The view for the form
#extends('frontend_master')
#section('content')
{{ Form::open(array('url' => '/', 'files' => true )) }}
{{ Form::text('title', '', array(
'placeholder' => 'Please insert your title here')) }}
{{ Form::file('image') }}
{{ Form::submit('save', array('name' => 'send')) }}
{{ Form::close() }}
#stop
Let me know if you can find any bugs, I'm pretty sure something must be going wrong in my ImageController#postIndex
Thanks for any insights
2 things you need to check out.
1st off, once you updated your composer.json to include the Intervention/Image package. you should run composer dump-autoload to refresh the autoload file.
2ndly, there's a logical error in your controller.
Image::make(Config::get('image.thumb_folder').'/'.$fullname)
->resize(Config::get('image.thumb_width'), null, true)
->save(Config::get('image.thumb_folder').'/'.$fullname);
should be
Image::make(Config::get('image.image_folder').'/'.$fullname)
->resize(Config::get('image.thumb_width'), null, true)
->save(Config::get('image.thumb_folder').'/'.$fullname);
because you've already moved the image file to image_folder with the code below:
$upload = $image->move
(Config::get('image.upload_folder'), $fullname);
Hope this helps.