I have problem with codeigniter upload function.
The function works well, but sometimes didn't work and without any error info.
snippet in controller
...
function add_process() {
$data['title'] = anchor('event/','<b>EVENT</b>', array('class' => 'back'));
$data['subtitle'] = ' / Add Event';
$data['main_view'] = 'event/event_form';
$data['form_action'] = site_url('event/add_process');
$this->form_validation->set_rules('eventName', 'Event Name', 'required');
$this->form_validation->set_rules('eventDate', 'Event Date', 'required');
if (empty($_FILES['eventImage']['name'])){
$this->form_validation->set_rules('eventImage', 'Event Image', 'required');
}
if ($this->form_validation->run() == TRUE) {
$config['upload_path'] = './images/event/';
$config['allowed_types'] = 'jpg|jpeg|png';
//$config['max_width'] = '3000';
//$config['max_height'] = '3000';
$this->load->library('upload', $config);
$this->upload->do_upload('eventImage');
$eventImage = $this->upload->data();
$event = array( 'eventName' => $this->input->post('eventName'),
'eventDate' => date('Y-m-d', strtotime($this->input->post('eventDate'))),
'eventDescriptions' => $this->input->post('eventDescriptions'),
'eventImage' => 'images/event/'.$eventImage['file_name'],
'isActive' => $this->input->post('isActive')
);
$this->Event_model->add($event);
$this->session->set_flashdata('message', '1 record was successfully added!');
redirect('event/add');
} else {
$this->load->view('admin/admin_main', $data);
}
}
...
could you tell please, what am i missing here?
Replace this
$this->Event_model->add($event);
$this->session->set_flashdata('message', '1 record was successfully added!');
redirect('event/add');
to this
if ($this->Event_model->add($event)) {
$this->session->set_flashdata('message', '1 record was successfully added!');
redirect('event/add');
}
Related
I am working on a blog application in Codeigniter 3.1.8 and Bootstrap 4. I have an "Edit post" form with validation.
If validation fails (because the Title field has been emptied, for example), the form should reload with validation errors.
My update() (lives in the Posts controller) method is wrong: it uses a redirect, so the form is reloaded without validation errors, to its initial state.
public function edit($id) {
// Only logged in users can edit posts
if (!$this->session->userdata('is_logged_in')) {
redirect('login');
}
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
$data['posts'] = $this->Posts_model->sidebar_posts($limit=5, $offset=0);
$data['post'] = $this->Posts_model->get_post($id);
if ($this->session->userdata('user_id') == $data['post']->author_id) {
$data['tagline'] = 'Edit the post "' . $data['post']->title . '"';
$this->load->view('partials/header', $data);
$this->load->view('edit-post');
$this->load->view('partials/footer');
} else {
/* If the current user is not the author
of the post do not alow edit */
redirect('/' . $id);
}
}
public function update() {
// Form data validation rules
$this->form_validation->set_rules('title', 'Title', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('desc', 'Short description', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('body', 'Body', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
$id = $this->input->post('id');
// Update slug (from title)
if (!empty($this->input->post('title'))) {
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug);
if ($slugcount > 0) {
$slug = $slug."-".$slugcount;
}
} else {
$slug = $this->input->post('slug');
}
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if(!$this->upload->do_upload()){
$errors = array('error' => $this->upload->display_errors());
$post_image = $this->input->post('postimage');
} else {
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
if ($this->form_validation->run()) {
$this->Posts_model->update_post($id, $post_image, $slug);
$this->session->set_flashdata('post_updated', 'Your post has been updated');
redirect('/' . $slug);
} else {
redirect('/posts/edit/' . $slug);
}
}
I am almost certain the problem is this line: redirect('/posts/edit/' . $slug); but I have not been able to find a viable alternative.
Using $this->edit($id) instead of redirect('/posts/edit/' . $slug); does not work either. I wish it would, because I want to keep the code DRY.
What shall I change?
Edit. I did this:
if ($this->form_validation->run()) {
$this->Posts_model->update_post($id, $post_image, $slug);
$this->session->set_flashdata('post_updated', 'Your post has been updated');
redirect('/' . $slug);
} else {
$this->form_validation->run();
$this->session->set_flashdata('errors', validation_errors());
var_dump($this->session->flashdata('errors'));
//redirect('/posts/edit/' . $slug);
}
The var_dump($this->session->flashdata('errors')); returns all the validation errors.
I wish to add the class has-error to the form-group and append <p class="error-message">The Title field is required.</p>.
<div class="form-group has-error">
<input type="text" name="title" id="title" class="form-control error" placeholder="Title" data-rule-required="true" value="Learn to code with us" aria-invalid="true">
<p class="error-message">The Title field is required.</p>
</div>
You have 3 options:
Use flash data in update method on failure (you are already using it on success). Simply assign the errors to a flash data variable and get it after you redirect back to edit.
Combine edit and update methods (most common for non-ajax usage).
Use ajax and return json encoded strings for errors or success messages.
Option 2:
This option also solves the potential authentication issue pointed out in the comments.
Please read the comments embedded in the code.
public function edit($id) {
// Only logged in users can edit posts
if (!$this->session->userdata('is_logged_in')) {
redirect('login');
}
$data['post'] = $this->Posts_model->get_post($id);
if ($this->session->userdata('user_id') == $data['post']->author_id) {
show_error('Access denied'); // function exits
}
if ($_POST) {
$this->form_validation->set_rules('title', 'Title', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('desc', 'Short description', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('body', 'Body', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
//$id = $this->input->post('id'); not required anymore
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if ($this->form_validation->run() && $this->upload->do_upload()) {
// always use the name from the upload lib
// sometimes it changes it in case of duplicates (read docs for more)
$post_image = $this->upload->data('file_name');
// doesn't make sense with title validation rule, this will always be true to get
// passed validation
if (!empty($this->input->post('title'))) {
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug);
if ($slugcount > 0) {
$slug = $slug . "-" . $slugcount;
}
} else {
$slug = $this->input->post('slug');
}
$this->Posts_model->update_post($id, $post_image, $slug);
$this->session->set_flashdata('post_updated', 'Your post has been updated');
redirect('/' . $slug);
} else {
$data['errors'] = validation_errors() . $this->upload->display_errors();
}
}
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
$data['posts'] = $this->Posts_model->sidebar_posts($limit = 5, $offset = 0);
$data['tagline'] = 'Edit the post "' . $data['post']->title . '"';
$this->load->view('partials/header', $data);
$this->load->view('edit-post');
$this->load->view('partials/footer');
}
What I would do in this scenario is merge both methods into a single method relying on the validation to know if I am saving the entry or not.
your code would look something like this:
public function edit($id) {
// Only logged in users can edit posts
if (!$this->session->userdata('is_logged_in')) {
redirect('login');
}
$Post = $this->Posts_model->get_post($id);
// user does not own the post, redirect
if ($this->session->userdata('user_id') !== $Post->author_id) {
redirect('/' . $id);
}
// Form data validation rules
$this->form_validation->set_rules('title', 'Title', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('desc', 'Short description', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('body', 'Body', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
// if validation fails, or the form isn't submitted
if ($this->form_validation->run() === false ) {
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
$data['posts'] = $this->Posts_model->sidebar_posts($limit=5, $offset=0);
$data['post'] = $Post;
$data['tagline'] = 'Edit the post "' . $data['post']->title . '"';
$this->load->view('partials/header', $data);
$this->load->view('edit-post');
$this->load->view('partials/footer');
}else{
// Update slug (from title)
if (! empty($this->input->post('title'))) {
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug);
if ($slugcount > 0) {
$slug = $slug."-".$slugcount;
}
} else {
$slug = $this->input->post('slug');
}
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if(!$this->upload->do_upload()){
$errors = array('error' => $this->upload->display_errors());
$post_image = $this->input->post('postimage');
} else {
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
$this->Posts_model->update_post($id, $post_image, $slug);
$this->session->set_flashdata('post_updated', 'Your post has been updated');
redirect('/' . $slug);
}
}
and you don't have to implement the update separately, you just post to /edit/$id instead of /update/$id ... this is a rough example, your slug checking (which I haven't touched upon) is not the correct way to do it, if it passes the validation the title is already filled since it's set to required so I guess you meant if (! empty(slug) ), but again in your else you are setting the slug directly from user input, so I would add it to the validation and make sure it's unique in the database except for the $id that's being edited currently.
Again, this is the result of copy & paste from your original code i might have missed something so give it a good read to make sure nothing is missing and include the validation errors in the data you are passing to the view.
I have managed to get the desired result using set_flashdata() as suggested by #Alex
In the controller I have:
public function update() {
// Form data validation rules
$this->form_validation->set_rules('title', 'Title', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('desc', 'Short description', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_rules('body', 'Body', 'required', array('required' => 'The %s field can not be empty'));
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
$id = $this->input->post('id');
// Update slug (from title)
if (!empty($this->input->post('title'))) {
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug);
if ($slugcount > 0) {
$slug = $slug."-".$slugcount;
}
} else {
$slug = $this->input->post('slug');
}
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if(!$this->upload->do_upload()){
$errors = array('error' => $this->upload->display_errors());
$post_image = $this->input->post('postimage');
} else {
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
if ($this->form_validation->run()) {
$this->Posts_model->update_post($id, $post_image, $slug);
$this->session->set_flashdata('post_updated', 'Your post has been updated');
redirect('/' . $slug);
} else {
$this->form_validation->run();
$this->session->set_flashdata('errors', validation_errors());
redirect('/posts/edit/' . $slug);
}
}
In the view:
<?php if ($this->session->flashdata('errors')) {
$errors = $this->session->flashdata('errors');
echo '<div class="error-group alert alert-warning alert-dismissible">' . "\n";
echo '<button type="button" class="close" data-dismiss="alert">×</button>' . "\n";
echo $errors;
echo '<p class="error-message">We have restored the post.</p>';
echo '</div>';
} ?>
public function addAppdetails()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('appname', 'App Name', 'required');
$this->form_validation->set_rules('platform', 'Platform', 'required');
//$this->form_validation->set_rules('category','App Category','required');
$this->form_validation->set_rules('description', 'App Description', 'required');
//$this->form_validation->set_rules('app_pic','App Pic','required');
//$this->form_validation->set_rules('file','App File','required');
if ($this->form_validation->run()) {
$appname = $this->input->post('appname');
$platform = $this->input->post('platform');
$category1 = $this->input->post('category');
$descripton = $this->input->post('description');
$category = implode(",", $category1);
$data = array('name' => $appname, 'platform' => $platform, 'description' => $descripton, 'category' => $category);
$this->appImageupload();
die;
$this->Dev_model->addApp($data);
} else {
$data['dataArray'] = $this->sessionStart();
$category = $this->input->post('category');
print_r($category);
$this->load->view('dev/addApp', $data);
}
}
public function appImageupload()
{
$config['upload_path'] = './uploads/appImages';
$config['allowed_types'] = 'exe';
$config['file_type'] = 'exe';
$config['max_size'] = 1000000000;
$this->load->library('upload', $config);
if ( ! $this->upload->appImageUpload('app_pic'))
{
$error = array('error' => $this->upload->display_errors());
print_r($error);
}
else
{
$data = array('upload_data' => $this->upload->data());
return $data;
}
}
The function appImageupoad is for uploading '.exe' files. So whenever I try to upload an executable file it gives the error. But if I change the $config['allowed-type] to .jpg or any image file extension then gets uploaded.
P.S.I have also tried the same thing in do_upload() it gives the same error.
You can also remove these lines of code
$config['file_type'] = 'exe';
$config['max_size'] = 1000000000;
You already specified allowed types allowed_types
Give it a try and if works then you can apply another validations as well
I've been trying to upload a pic to a folder and store its path in the database, my code seems to work correctly, but no it's not, After i click submit button, it goes to a blank page.
Using Inspect element, Network option in my browser, when seeing the parameters sent
I see correct input from the text fields but for the image,
Content-Disposition: form-data; name="myimage"; filename="IMG_8971.JPG"
Content-Type: image/jpeg
Plus some other weirly looking characters and symbols like :
ÿØÿà
CONTROLLER:
private function setup_upload_option()
{
$config = array();
$config['upload_path'] = 'blog/uploads/';
$config['allowed_type']='jpg|jpeg|png|gif';
$config['encrypt_name']= TRUE;
$config['overwrite']=FALSE;
return $config;
}
public function post_new_blog()
{
$this->form_validation->set_rules('title', 'Title of the Blog', 'trim|required');
$this->form_validation->set_rules('desc', 'Content of the Blog', 'trim|required');
$this->form_validation->set_rules('tags', 'Tags fo the blog', 'trim|required');
if($this->form_validation->run()==FALSE) {
$this->session->set_flashdata('fail', validation_errors());
$this->load->view('blogsection/addblog', array('logged_in' => $this->logged_in));
}
else {
$this->load->library('upload');
$files = $_FILES;
$count = count($_FILES['myimage']['name']);
for($i=0; $i<$count ;$i++)
{
$_FILES['myimage']['name'] = $files['myimage']['name'][$i];
$_FILES['myimage']['type'] = $files['myimage']['type'][$i];
$_FILES['myimage']['size'] = $files['myimage']['size'][$i];
$_FILES['myimage']['tmp_name'] = $files['myimage']['tmp_name'][$i];
$this->upload->initialize($this->setup_upload_option());
if($this->upload->do_upload()==TRUE)
{
$data = $this->upload->data();
$config1['image_library'] = 'gd2';
$config1['source_image'] = $data['full_path'];
$config1['new_image'] = 'blog/uploads/thumbs/';
$config1['create_thumb'] = false;
$config1['height'] = 200;
$config['width'] = 200;
$this->load->library('image_lib', $config1);
$this->image_lib->initialize($config1);
$this->image_lib->resize();
$mydata = $this->session->all_userdata();
$dataarray = array(
'blog_title' => $this->input->post('title', true),
'blog_content' => $this->input->post('desc', true),
'blog_tags' => $this->input->post('tags', true),
'blog_image_name' => $data['orig_name'],
'blog_image' => $data['full_path'],
'date_posted' => date(" jS \of F Y "),
'posted_by' => $mydata['username']
);
$this->main_model->save_new_posts($dataarray);
$this->load->view('blogsection/addblog', array('logged_in' => $this->logged_in, 'success' => 'Blog was posted successfully',$dataarray));
}
}
}
}
MODEL:
public function save_new_posts($dataarray)
{
$this->db->insert('blogs', $dataarray);
if($this->db->affected_rows()>0)
{
return true;
}
}
i have code that always works, it is some what different from you method i hope it will help you.
$imgpath='uploads/profile_pic/';
$all_img="";
if($_FILES["profile_pic"]['name'])//form input type file
{
$path_parts = pathinfo($_FILES["profile_pic"]["name"]);
$image_path = $path_parts['filename'].'_'.time().'.'.$path_parts['extension'];
$all_img.=$image_path;
move_uploaded_file($file_tmp=$_FILES["profile_pic"]["tmp_name"],$imgpath."/".$image_path);
$data['cm_user_profile_pic']=$all_img;//store image name in array
}
Codeigniter when i update the form others are updating but image path disappears
Form Submit
user name update
password update
image url delete
Form Submit
user name update
password update
Not -> image url delete
CONTROLLER
public function profil_guncelle($id)
{
if(!empty($_FILES['avatar']['name'])){
$config['upload_path'] = 'uploads';
$config['allowed_types'] = 'jpg|jpeg|png|gif';
$config['width'] = 150;
$config['height'] = 50;
$config['file_name'] = $_FILES['avatar']['name'];
$this->load->library('upload',$config);
$this->upload->initialize($config);
if($this->upload->do_upload('avatar')){
$uploadData = $this->upload->data();
$picture = $uploadData['file_name'];
}else{
$picture = '';
}
}else{
$picture = '';
}
$this->form_validation->set_rules('user_pass', 'Parola', 'trim|required');
$this->form_validation->set_rules('user_mail', 'E-Posta', 'trim|required');
if ($this->form_validation->run() == FALSE) {
$this->session->set_userdata('profil_guncelle', validation_errors());
$upload_error = array('error' => $this->upload->display_errors());
redirect(base_url().'admin/users/profil/'.$id);
}else{
$data=array(
'user_pass' => $this->input->post('user_pass'),
'user_mail' => $this->input->post('user_mail'),
'avatar' => $picture
);
if ($this->Database_Model->profil_guncelle($data, $id) ==true) {
$this->session->set_flashdata('profil_guncelle', 'Bilgileriniz başarıyla güncellendi.');
redirect(base_url().'admin/users/profil/'.$id);
}
}
}
}
DATABASE MODEL
public function profil_guncelle($data, $id){
$this->db->set($data);
$this->db->where('id', $id);
if ($this->db->update('users') ===true) {
return true;
}else{
return false;
}
}
First you are set $picture become '' if $_FILES['avatar']['name'] is empty.
than when you are trying update data
$data=array(
'user_pass' => $this->input->post('user_pass'),
'user_mail' => $this->input->post('user_mail'),
'avatar' => $picture
);
of course $picture will be set to '' if the images files are empty. you change the array become :
$data=array(
'user_pass' => $this->input->post('user_pass'),
'user_mail' => $this->input->post('user_mail'),
);
if($picture != ''){
$data['avatar'] = $picture;
}
I'm curious to know in $this->upload->do_upload('img') field name is passing mandotory not.I have seen several example in stackoverflow where do_upload() not taking any argument as file field name.But in case of mine without field name file not uploaded.I want to know which is correct syntax?
2)How do i bypass the file upload validation when there is no file being uploaded.If there is no file(image) in the form then $this->upload->display_errors() will not be called.my code is below
function add()
{
if ($this->input->server('REQUEST_METHOD') === 'POST')
{
$this->form_validation->set_rules('category', 'Category Name', 'required');
if ($this->form_validation->run())
{
$data_to_store = array(
'category' => $this->input->post('category'),
'description' => $this->input->post('description'),
'parent'=>'0'
);
$last_id=$this->admin_category_model->add_category($data_to_store);
$config['upload_path'] ='./uploads/';
$config['allowed_types'] = 'gif|jpg|png|GIF|JPG|PNG';
$config['remove_spaces'] = TRUE;
$config['max_size'] = '0';
$config['file_name'] =$last_id.'_'.$_FILES['img']['name'];
$config['overwrite'] = TRUE;
$this->load->library('upload', $config);
if($this->upload->do_upload('img'))
{
$data = array('upload_data' => $this->upload->data());
$config2['image_library'] = 'gd2';
$config2['source_image'] = $data['upload_data']['full_path'];
$config2['new_image'] ='./uploads/thumb/'.$data['upload_data']['file_name'];
$config2['create_thumb'] = FALSE;
$config2['maintain_ratio'] = TRUE;
$config2['width'] = 35;
$config2['height'] = 35;
$this->load->library('image_lib',$config2);
$this->image_lib->resize();
$data_to_store = array(
'img' => $config['file_name'],
);
$this->admin_category_model->update_category($last_id,$data_to_store);
$this->session->set_flashdata('flash_message', 'Record Added');
redirect('admin_category/index');
}
else
{
$data['error']=$this->upload->display_errors();
}
}
}
$data['title']='Add Category';
$data['main_content'] = 'admin/add_category';
$this->load->view('admin/includes/template', $data);
}
1st) No, not necessary, by default it will take the name userfile.
2nd) Say for example your fieldname is img check like this:
if( $_FILES['img']['name'] != "" ){
//your upload code here
}