Welcome Guest, Not a member yet? Register   Sign In
Uploading an image with form_validation
#1

[eluser]Xeoncross[/eluser]
This is an updated version of the awesome topic by Jatinder Thind. I made some changes to support the new form_validation class and I registered "upload_data" about the uploaded file for use later (like you plan to resize the image or something).

Because of the way it is setup, as soon as the form validation is run - it will auto-upload the file for you then you can get details about it like this:

Code:
$full_path = $this->upload_data['full_path'];

Add this to the controller uploading the file
Code:
/*
     * Check to make sure the image is valid - then upload it.
     */
    function valid_image($str) {
        
        //Check for image upload
        if(!isset($_FILES['image'])) {
            $this->form_validation->set_message('valid_image', 'Image required');
            return false;
        }
        
        //Check for file size
        if($_FILES['image']['size'] == 0) {
            $this->form_validation->set_message('valid_image', 'Image required');
            return false;
        }
        
        //Check for upload errors
        if($_FILES['image']['error'] != UPLOAD_ERR_OK) {
            $this->form_validation->set_message('valid_image', 'Upload failed');
            return false;
        }
        
        //Check for valid image upload
        $imginfo = getimagesize($_FILES['image']['tmp_name']);
        if(!$imginfo) {
            $this->form_validation->set_message('valid_image', 'Only image files are allowed');
            return false;
        }
        
        //Check for valid image types
        if( !($imginfo[2] == 1 || $imginfo[2] == 2 || $imginfo[2] == 3) ) {
            $this->form_validation->set_message('valid_image', 'Only GIF, JPG and PNG files accepted');
            return false;
        }
        
        //Check for existing image
        if(file_exists($this->_upload_dir. $_FILES['image']['name'])) {
            $this->form_validation->set_message('valid_image', 'Image by this name already exists');
            return false;
        }
        
        //Everything checks out - so upload!
        $error = $this->do_upload();
        
        //If we had problems uploading
        if($error) {
            $this->form_validation->set_message('valid_image', $error);
            return FALSE;
        }
        
        return TRUE;
    }


    /**
     * Uploads the image for the post
     * @return unknown_type
     */
    private function do_upload() {
        
        $config['upload_path'] = $this->_upload_dir; //../uploads/';
        $config['allowed_types'] = 'gif|jpg|png';
        $config['max_size']    = '4000';
        $config['max_width']  = 0;
        $config['max_height']  = 0;
        
        $this->load->library('upload', $config);
    
        //If failed the upload
        if ( ! $this->upload->do_upload('image')) {
            return $this->upload->display_errors('', '');
        }
        
        //Register data about the file in this object
        $this->upload_data = $this->upload->data();
        
        return FALSE;
    }

Add this to your HTML form
Code:
<!-- For image upload -->
<input type="hidden" name="valid_image" />

And finally, add this rule to your config file or to right before you check the form.
Code:
$this->form_validation->set_rules('valid_image', 'image', 'callback_valid_image');
//and
$this->_upload_dir = APPPATH. 'uploads/';

This form only supports the uploading of ONE image but could be changed to support many if you needed.
#2

[eluser]xwero[/eluser]
I wouldn't put the do_upload in the validation function, it would be the same as storing each post value after it passes the validation.

Setting class variables, _upload_dir in this case, are better done in a method because if the class variable changes you can change this in method and none of you code needs to change.
#3

[eluser]Xeoncross[/eluser]
True, it is better if you move the do_upload() function call to the actual method calling the validation - but I have it like this because it is "plug and play" for someone to just paste into there controller.

Also, you should not set new variables from methods - they should all be defined in the class so that people working on this class don't get weird results when they happen to create a variable named the same thing. Doing it this way makes sure that everyone knows what variables are in effect just by looking at the constructor or class.

Especially since CI passes these values into libraries and models it loads!




Theme © iAndrew 2016 - Forum software by © MyBB