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>';
} ?>
Related
I am working on a basic blog application with Codeigniter 3.1.8 and Bootstrap 4. The application has user (author) accounts.
Once logged in, the author can edit his/her account info, including the email address:
Adding is_uniqueto the email field (in order to prevent duplicate email addresses on account info edit, not just creation) causes this bug:
When I try to update the email using an email already assigned an author, including myself, the validation error message The Email is already taken appears.
In the controller I have this update method:
public function update() {
// Only logged in users can update user profiles
if (!$this->session->userdata('is_logged_in')) {
redirect('login');
}
$id = $this->input->post('id');
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
$data['author'] = $this->Usermodel->editAuthor($id);
$this->form_validation->set_rules('first_name', 'First name', 'required');
$this->form_validation->set_rules('last_name', 'Last name', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email|is_unique[authors.email]');
$this->form_validation->set_message('is_unique', 'The %s is already taken');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
// Upload avatar
$config['upload_path'] = './assets/img/authors';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '1024';
$this->load->library('upload', $config);
if (!$this->upload->do_upload('userfile')) {
$uerrors = array('uerrors' => $this->upload->display_errors());
// if NO file is uploaded,
if (empty($_FILES['userfile']['name'])) {
// force upload validation and
$uerrors = [];
// use the existing avatar (if any)
$avatar = $this->input->post('avatar');
}
$data['uerrors'] = $uerrors;
} else {
$data = array('upload_data' => $this->upload->data());
$avatar = $_FILES['userfile']['name'];
$this->session->set_userdata('user_avatar', $avatar);
}
if(!$this->form_validation->run() || !empty($uerrors)) {
$this->load->view('partials/header', $data);
$this->load->view('dashboard/edit-author');
$this->load->view('partials/footer');
} else {
$this->Usermodel->update_user($avatar, $id);
$this->session->set_flashdata('user_updated', 'Your account details have been updated');
redirect(base_url('/dashboard/manage-authors'));
}
}
In the view with the edit form:
<div class="form-group <?php if(form_error('email')) echo 'has-error';?>">
<input type="text" name="email" id="email" class="form-control" value="<?php echo set_value('email', $author->email); ?>" placeholder="Email">
<?php if(form_error('email')) echo form_error('email'); ?>
</div>
Where is my mistake?
This is how the is_unique works, it checks the table for any duplicate entries as it has no way of knowing what id is being edited. Is this a bug? Maybe.
But you can make your own validation function and make a call to it. Like so -
public function update() {
$id = $this->input->post('id');
// ...
// ...
// ...
$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email|callback__checkemail['.$id.']'); // pass id
// ...
// ...
// ...
}
function _checkemail($email, $id){
// don't need to $this->input->post('email') as it is a validation for the same ↑↑(set_rules), if you need anything else then $this->input->post('input_field')
if( !$id ){
$this->db->where('email', $email);
$num = $this->db->count_all_results('authors');
}else{
$this->db->where('email', $email);
$this->db->where_not_in('id', $id); // not in current id in edit mode
$num = $this->db->count_all_results('authors');
}
// You'd probably want to do DB queries↑↑ in model
// You can also combine the queries into one as they seem repetitive
if ($num > 0) {
$this->form_validation->set_message('_checkemail','Email already exists!'); //set message to the callbacked function(ie _checkemail) not the input field here.
return FALSE;
} else {
return TRUE;
}
}
See if it helps you.
I am working on a basic blog application with Codeigniter 3.1.8 and Bootstrap 4.
The posts, of course, have main images. There is a default image if no image is uploaded by the user but, if an image is uploaded, there are only 3 types allowed: jpg, jpeg and png.
Wanting to warn the user in case she/he tries to upload other file formats, I did this in the Posts controller:
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if(!$this->upload->do_upload()){
$data['uerrors'] = $this->upload->display_errors();
if ($data['uerrors']) {
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post');
$this->load->view('partials/footer');
} else {
$post_image = 'default.jpg';
}
} else {
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
In the view I have:
<?php foreach ($uerrors as $uerror): ?>
<span><?php echo $uerror; ?></span>
<?php endforeach; ?>
Yet, I get a Undefined variable: uerrors error.
Here is the entire create() method:
public function create() {
// Only logged in users can create posts
if (!$this->session->userdata('is_logged_in')) {
redirect('login');
}
$data = $this->get_data();
$data['tagline'] = "Add New Post";
if ($data['categories']) {
foreach ($data['categories'] as &$category) {
$category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
}
}
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('desc', 'Short description', 'required');
$this->form_validation->set_rules('body', 'Body', 'required');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if($this->form_validation->run() === FALSE){
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post');
$this->load->view('partials/footer');
} else {
// Create slug (from title)
$slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug, null);
if ($slugcount > 0) {
$slug = $slug."-".$slugcount;
}
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if(!$this->upload->do_upload()){
$data['uerrors'] = $this->upload->display_errors();
if ($data['uerrors']) {
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post');
$this->load->view('partials/footer');
} else {
$post_image = 'default.jpg';
}
} else {
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
$this->Posts_model->create_post($post_image, $slug);
$this->session->set_flashdata('post_created', 'Your post has been created');
redirect('/');
}
}
Where is my mistake?
Your upload code looks okay, but you need to update these following changes.
Pass data to your 'dashboard/create-post' view as you have passed to your 'partials/header' view. Your 'dashboard/create-post' view is not getting any upload error messages, so it is saying 'Undefined variable: uerrors'. So, your upload code should be like this -
if(!$this->upload->do_upload()){
$data['uerrors'] = $this->upload->display_errors();
if ($data['uerrors']) {
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post', $data);
$this->load->view('partials/footer');
} else {
$post_image = 'default.jpg';
}
} else {
$post_image = $this->upload->data('file_name');
}
As CodeIgniter Documentation says, 'display_errors()' returns string, not array, you don't have to loop through the error. Just echo it on your 'dashboard/create-post' view.
For your convenience, make your upload task in different method so that you can re-use this in update method also. As example -
private function uploadFile(){
if ($_FILES['userfile']['name'] === '') {
return array(
'status' => TRUE,
'message' => 'No file selected.',
'file_name' => 'default.jpg'
);
}
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if(!$this->upload->do_upload('userfile')){
return array(
'status' => FALSE,
'message' => $this->upload->display_errors('<p class="text-danger ">', '</p>'),
'file_name' => ''
);
}else{
return array(
'status' => TRUE,
'message' => 'File uploaded successfully',
'file_name' => $this->upload->data('file_name')
);
}
}
Then your entire create method should look like this -
public function create() {
// Only logged in users can create posts
if (!$this->session->userdata('is_logged_in')) {
redirect('login');
}
$data = $this->get_data();
$data['tagline'] = "Add New Post";
if ($data['categories']) {
foreach ($data['categories'] as &$category) {
$category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
}
}
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('desc', 'Short description', 'required');
$this->form_validation->set_rules('body', 'Body', 'required');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if($this->form_validation->run() === FALSE){
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post');
$this->load->view('partials/footer');
} else {
$upload = $this->uploadFile();
if($upload['status'] === FALSE){
$data['upload_error'] = $upload['message'];
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post', $data);
$this->load->view('partials/footer');
}else{
// Create slug (from title)
$slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug, null);
if ($slugcount > 0) {
$slug = $slug."-".$slugcount;
}
$this->Posts_model->create_post($upload['file_name'], $slug);
$this->session->set_flashdata('post_created', 'Your post has been created');
redirect('/');
}
}
}
And finally add this line of code on your 'dashboard/create-post' view file, right after file input button.
<?php if(isset($upload_error)) echo $upload_error; ?>
I think all should work.
There are three things I picked up here
1) not passing $data to the correct view as mentioned before
2) expecting array instead of string on the view ie wrong data type
3) lastly function do_upload() expects parameter string $field. This is missing that's why you are having only the no upload selected error. If this parametre is set codeigniter really throws wrong filetype error. I did this to test
on my view
<form action="http://localhost:8000/welcome/create" method="post" enctype="multipart/form-data">
<input type="file" name="lname" ><br>
<input type="submit" value="Submit">
</form>
then in my controller
if(!$this->upload->do_upload("lname")){
Upload a wrong file type to test this error. You may need to go an extra length to detect the filetype for the actual upload file.
I have succeeded to display the upload errors (if upload is attempted, otherwise a default image is used) by modifying create() this way:
public function create() {
// Only logged in users can create posts
if (!$this->session->userdata('is_logged_in')) {
redirect('login');
}
$data = $this->get_data();
$data['tagline'] = "Add New Post";
if ($data['categories']) {
foreach ($data['categories'] as &$category) {
$category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
}
}
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('desc', 'Short description', 'required');
$this->form_validation->set_rules('body', 'Body', 'required');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if($this->form_validation->run() === FALSE){
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post');
$this->load->view('partials/footer');
} else {
// Create slug (from title)
$slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug, null);
if ($slugcount > 0) {
$slug = $slug."-".$slugcount;
}
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
if(!$this->upload->do_upload()){
$errors = array('error' => $this->upload->display_errors());
// Display upload validation errors
// only if a file is uploaded and there are errors
if (empty($_FILES['userfile']['name'])) {
$errors = [];
}
if (empty($errors)) {
$post_image = 'default.jpg';
} else {
$data['upload_errors'] = $errors;
}
} else {
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
if (empty($errors)) {
$this->Posts_model->create_post($post_image, $slug);
$this->session->set_flashdata('post_created', 'Your post has been created');
redirect('/');
} else {
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post');
$this->load->view('partials/footer');
}
}
}
In the create-post.php view I have:
<?php if(isset($upload_errors)){
foreach ($upload_errors as $upload_error) {
echo $upload_error;
}
}?>
This error tells you that a variable doesn't exist or was not initialized. Looking at this code
$data['uerrors'] = $this->upload->display_errors();
if ($data['uerrors']) {
I think that you probably have a $uerrors variable somewhere (not shown in this code) which was not initialized. Note that I do not believe that the array index 'uerrors' would cause you trouble in the chunk above, because, first of all you define it and second, if you reference an array item which does not exist, then you will get a different error message from the one quoted in the question.
Your question is a bit vague. Whatever, the only condition in which the variable $uerrors will set is when create() method will execute which I believe would get executed on POST request. Besides, you didn't mention which part of view is this:
<?php foreach ($uerrors as $uerror): ?>
<span><?php echo $uerror; ?> </span>
<?php endforeach; ?>
If it's dashboard/create-post view then try passing $data directly to this view instead of passing it to partials/header
Note: I just checked the codeigniter View/Controller samples and I found it to be a good practice to check variable using isset() function call, so instead of executing foreach loop directly, do this:
<? if (isset($uerrors)): ?>
<? foreach ($uerrors as $uerror): ?>
<span><?= $uerror; ?></span>
<? endforeach; ?>
<? endif; ?>
You need to initialize $data['uerrors'] as null because you are using it on the front end
$data['uerrors'] = '';
or check the value is not empty on the frontend.
Frontend, you can do this as:
<?php if (isset($uerrors) && $uerrors != '') {
foreach ($uerrors as $uerror) {
echo '<span>' . $uerror . '</span>';
}
} ?>
Your controller will be:
$data = array();
// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
/*You need to initialize $data['uerrors'] as null because you are using it on front end*/
$data['uerrors'] = '';
if (!$this->upload->do_upload('FilePath')) {
$data['uerrors'] = $this->upload->display_errors();
$this->load->view('partials/header', $data);
$this->load->view('dashboard/create-post');
$this->load->view('partials/footer');
} else {
if (isset($_POST{'your_file'})) {
/*'check your images here that you are receiving from front end'*/
} else {
/*If there is no image, then default image is*/
$post_image = 'default.jpg';
}
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
You can further find useful posts on How to upload image in CodeIgniter?
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
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 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');
}