How can I store validation errors related to image upload as flash massages in this Codeigniter 3 application?

房东的猫 提交于 2020-02-25 04:07:38

问题


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.

There are restrictions on image files a user can upload:

$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '2048';

I have managed to display the upload error messages that correspond to the configuration above (for your curiosity and/or use, the code is here).

For the update() method however, since there are redirects involved, all form validation messages are stored as "flash messages".

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 ($this->form_validation->run()) {
        $slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
        $slugcount = $this->Posts_model->slug_count($slug, $id);
        if ($slugcount > 0) {
            $slug = $slug."-".$slugcount;
        }
    } else {
        $slug = $this->input->post('slug');
    }

// Upload image
    $config['upload_path'] = './assets/img/posts';
    $config['allowed_types'] = 'jpg|jpeg|png';
    $config['max_size'] = '2048';

    $this->load->library('upload', $config);

    if (isset($_FILES['userfile']['name']) && $_FILES['userfile']['name'] != null) {
        // Use name field in do_upload method
        if (!$this->upload->do_upload('userfile')) {

            $errors = array('error' => $this->upload->display_errors());

            // Dysplay upload validation errors 
            // only if a file is uploaded and there are errors
            if (empty($_FILES['userfile']['name'])) {
                $errors = [];
            }

            if (!empty($errors)) {
                $data['upload_errors'] = $errors;
            }

        } else {
            $data = $this->upload->data();
            $post_image = $data[ 'raw_name'].$data[ 'file_ext'];
        }
    }
    else {
        $post_image = $this->input->post('postimage');
    }

    if ($this->form_validation->run() && empty($errors)) {
        $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());
        // this line was added later
        // but the bug persists 
        $this->session->set_flashdata('upload_errors', $errors);
        redirect('/dashboard/posts/edit/' . $slug);
    }
}

In the edit-post.php view I have:

<input type="hidden" name="postimage" id="postimage" value="<?php echo $post->post_image; ?>">
<label for="postimage">Upload an image</label>
<div class="form-group">
    <input type="file" name="userfile" id="postimage" size="20">
    <?php if ($this->session->flashdata('upload_errors')) { ?>
        <div class="error-messages">
            <?php if(isset($upload_errors)){
                 foreach ($upload_errors as $upload_error) {
                     echo $upload_error;
                 }
            }?>
        </div>
   <?php } ?>
</div>

I have not been able to add the image upload errors messages as "flash messages".

How can I do that?


回答1:


In edit-post.php you have to change:

<?php if ($this->session->flashdata('upload_errors')) { ?>

With:

<?php if ($upload_errors = $this->session->flashdata('upload_errors')) { ?>



回答2:


Try this:

$this->session->set_flashdata('errors', validation_errors());
$this->session->set_flashdata('upload_errors', $errors);

Or you can create an $errorArray from validation_errors() and $errors.




回答3:


I do the exact same thing (upload errors go into a flashdata element). Here's how it works for me:

(I'll skip the upload config... but for this example, it's stored in an array conveniently named $config)

In my controller:

$this->load->library('upload', $config);

if (!$this->upload->do_upload('userfile'))
{
   $this->session->set_flashdata('message', "An error ocurred: ".$this->upload->display_errors());
   $this->session->set_flashdata('alert_class', "alert-danger");
}

else
{
   $this->session->set_flashdata('message', "Upload successful");
   $this->session->set_flashdata('alert_class', "alert-success");

}

In my view (all my views carry this code)

<?php
if (null !== $this->session->flashdata('message'))
{ ?>
    <div class="alert <?php echo $this->session->flashdata('alert_class'); ?> text-center mb-2"><i class="fas fa-exclamation-triangle fa-fw"></i> <?php echo $this->session->flashdata('message'); ?></div>
<?php 
}
?>

In this way, if I don't set a flashdata element called message the view won't even display the DIV where alert is displayed. If, on the other hand, I do set the message element, a col-12 alert is displayed with the message I defined and styled with the alert class I want (success, warning, danger, info, etc)

This will only work for upload validation errors. In your multipart form you may also have regular validation errors which you should check for separately. You can do the same with a flash element:

$this->session->set_flashdata('message', validation_errors());

I use the same element name (message) because I'd stop upon the first error, So there would be no upload error and form validation error in the same display.




回答4:


This should work.

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');

    $form_is_valid = $this->form_validation->run()
    $errors = [];

    // Update slug (from title)
    if ($form_is_valid) {
        $slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
        $slugcount = $this->Posts_model->slug_count($slug, $id);
        if ($slugcount > 0) {
            $slug = $slug."-".$slugcount;
        }
    } else {
        $slug = $this->input->post('slug');
        $errors[] = validation_errors();
    }

// Upload image
    $config['upload_path'] = './assets/img/posts';
    $config['allowed_types'] = 'jpg|jpeg|png';
    $config['max_size'] = '2048';

    $this->load->library('upload', $config);

    if (isset($_FILES['userfile']['name']) && $_FILES['userfile']['name'] != null) {
        // Use name field in do_upload method
        if (!$this->upload->do_upload('userfile')) {

            $upload_errors = array('error' => $this->upload->display_errors());

            // Dysplay upload validation errors 
            // only if a file is uploaded and there are errors
            if (empty($_FILES['userfile']['name'])) {
                $upload_errors = [];
            }

            if (!empty($upload_errors)) {
                $data['upload_errors'] = $upload_errors;
                $errors[] = $upload_errors;
            }

        } else {
            $data = $this->upload->data();
            $post_image = $data[ 'raw_name'].$data[ 'file_ext'];
        }
    }
    else {
        $post_image = $this->input->post('postimage');
    }

    if (empty($errors)) {
        $this->Posts_model->update_post($id, $post_image, $slug);
        $this->session->set_flashdata('post_updated', 'Your post has been updated');
        redirect('/' . $slug);
    } else {
        $this->session->set_flashdata('errors', $errors);
        redirect('/dashboard/posts/edit/' . $slug);
    }
}

$this->form_vlaidation->run() is called only once. Errors are saved both (form validation & upload) in the same array. Post is updated only if $errors is empty.

You should think how you can improve the code further.




回答5:


Try this one .Add this in constructor

$this->session->keep_flashdata('errors');

and remove session data after use it in view

 $this->session->unset_userdata('errors');


来源:https://stackoverflow.com/questions/60102647/how-can-i-store-validation-errors-related-to-image-upload-as-flash-massages-in-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!