EllisLab text mark
Advanced Search
2 of 3
2
   
File upload validation
Posted: 22 March 2009 08:06 PM   [ # 16 ]   [ Rating: 0 ]
Avatar
Joined: 2009-02-19
23 posts

ahh forgot $this->. thanks

 
Posted: 28 March 2009 12:32 PM   [ # 17 ]   [ Rating: 0 ]
Joined: 2008-11-16
34 posts

Do I understand correctly that if file is not mandatory, then you can’t just use callback? The problem is that I have mandatory fields in the form and file is not mandatory, but I need to check that file is valid for upload. If it’s not valid, then I need to refill all field values (I do it with validation class) and show notification that file is not correct.

Is there a simple way of doing that?

 
Posted: 28 March 2009 12:37 PM   [ # 18 ]   [ Rating: 0 ]
Avatar
Joined: 2009-02-19
23 posts

Yup. when I put all this in the callback, if the file is not the right type, it returns the error like normal. If you do not want the file upload to be manditory, in the callback, have an if statement checking if a file was selected if now, skip and return true, if not, run the callback like normal.

 
Posted: 28 March 2009 01:50 PM   [ # 19 ]   [ Rating: 0 ]
Joined: 2008-11-16
34 posts

Hmm, really, that should work smile Spring, no vitamins, head doesn’t work smile

 
Posted: 11 April 2009 02:31 PM   [ # 20 ]   [ Rating: 0 ]
Joined: 2007-09-18
397 posts

sorry to post in an old thread, but i dont see how pistolpete’s suggestion in post#2 can work. its very simple - the output is always that no file was uploaded. been breaking my head on this the past 4 hours. some official docs on how to handle this would be appreciated by everyone im sure.

 Signature 

Attended EECI2009

 
Posted: 11 April 2009 02:44 PM   [ # 21 ]   [ Rating: 0 ]
Avatar
Joined: 2009-02-19
23 posts

Lets see some of your code. one thing that I changed was that I removed “required” from the form validation as this would return that no file was uploaded every time. instead, in the callback function the act of trying to upload the file wil check if a file was selected and if not it returns a false and an error of no file selected. so in my form rules, i only have the call back function for the image upload.

like i said post some code and we’ll see if we can work this out.

thanks!

 
Posted: 11 April 2009 03:09 PM   [ # 22 ]   [ Rating: 0 ]
Joined: 2007-09-18
397 posts

i should be thanking you grin im retrying with your suggestion of leaving out “required”. determined to get this done before the day’s end. ill post back shortly

 Signature 

Attended EECI2009

 
Posted: 11 April 2009 03:19 PM   [ # 23 ]   [ Rating: 0 ]
Joined: 2007-09-18
397 posts

ok here we go. these are two function in my controller. whether or not i pick a file for upload, i always get “You did not select a file to upload.”

im wondering - what do you use as the first parameter inthe set_rules function? the name of the field or ‘userfile’ (someone mention this was required, but what if you have multiple file upload fields?) or, $_FILES[‘prod_img’] ?

function create() {    
            
            
            
//validation
            
$this->form_validation->set_rules('prod_name''product name''trim|required');
            
$this->form_validation->set_rules('prod_img''product image''callback__do_upload');    
            
$this->form_validation->set_rules('prod_descr_long''long description''trim|required');
            
$this->form_validation->set_rules('prod_aff_link''affiliate link''trim|required');
                    
            
            if(
$this->form_validation->run() == FALSE{                
                
//send back to the view
                
$attributes['prod_name'$this->input->post('prod_name');
                
$attributes['prod_descr_long'$this->input->post('prod_descr_long');
                
$attributes['prod_aff_link'$this->input->post('prod_aff_link');    
            
                
$this->load->view('admin_view'$attributes);    
            
}
            
else {                
                $this
->M_Products->createProduct();
                
$this->load->view('admin_view'$attributes);
            
}        
          }
          
          
          
function _do_upload($file{
              $config[
'upload_path''/Applications/MAMP/htdocs/my-site/images/_uploads/';
            
            
$this->load->library('upload'$config);
                
            if (!
$this->upload->do_upload()) {
                
//print "one"; exit;
                // set the validation error using the errors provided by the upload class
                
$this->form_validation->set_message('_do_upload'$this->upload->display_errors());
                return 
FALSE;
            
}    
            
else {
                
print "two"; exit;
               
print_r($_FILES); exit;
            
}
          } 

thanks for any pointers!

 Signature 

Attended EECI2009

 
Posted: 11 April 2009 03:33 PM   [ # 24 ]   [ Rating: 0 ]
Joined: 2007-09-18
397 posts

editing my own posts here. it seems ‘userfile’ is the way to go as first param for the set_rules function. when using multiple fields, you can use this

$field_name "some_field_name";
$this->upload->do_upload($field_name

this helps alot. again id like to stress that pistolpete’s solution in post#2 (what i was basing myself on all afternoon!) does NOT work.

 Signature 

Attended EECI2009

 
Posted: 11 April 2009 08:39 PM   [ # 25 ]   [ Rating: 0 ]
Avatar
Joined: 2009-02-19
23 posts

Ah yes you do need to specify if you are not using the default userfile as the file upload id.

So did this solve what you were having issues with?

 
Posted: 12 April 2009 05:41 AM   [ # 26 ]   [ Rating: 0 ]
Joined: 2007-09-18
397 posts

ive certainly progressed, thanks! im just wondering now how to get $image_data = $this->upload->data(); back to the create() function from where the _do_upload callback is called.

i return $image_data, but its not available in create(). do you have to declare $image_data as private, public, ... ? if so, where?

thanks!

function _do_upload($file{
              $config[
'upload_path''/Applications/MAMP/htdocs/buy-arab-scarves/images/_uploads/';
            
$config['allowed_types''jpg|gif|jpeg|png';
            
$config['max_size']    '2000';
            
$this->load->library('upload'$config);
               
            
$field_name "prod_img"//see http://ellislab.com/codeigniter/user-guide/libraries/file_uploading.html
            
if (!$this->upload->do_upload($field_name)) {
                $this
->form_validation->set_message('_do_upload'$this->upload->display_errors());
                return 
FALSE;
            
}    
            
else {    
            
                
//array with data from uploaded (not processed!) image
                
$image_data $this->upload->data();
            
                
//process & resize image
                
$config['source_image'$config['upload_path'].$_FILES['prod_img']['name'];
                
$config['maintain_ratio'TRUE;
                
$config['height'200;
                
$config['create_thumb'TRUE;
                
                
$this->load->library('image_lib'$config);
                
$this->image_lib->resize();
                
                if(
$this->image_lib->resize() !== TRUE{
                    
print $this->image_lib->display_errors();
                    exit;
                
}
                              
            }
            
            
return $image_data;
          
 Signature 

Attended EECI2009

 
Posted: 12 April 2009 08:08 AM   [ # 27 ]   [ Rating: 0 ]
Avatar
Joined: 2008-05-17
1073 posts
stef25 - 11 April 2009 07:33 PM

it seems ‘userfile’ is the way to go as first param for the set_rules function. ...
again id like to stress that pistolpete’s solution in post#2 (what i was basing myself on all afternoon!) does NOT work.

This was almost a verbatim copy from one of my projects and it’s working fine there.

Do you use something like this?

$this->form_validation->set_rules('userfile''whatever''callback__do_upload'); 

I doubt whether that is working because a file upload is saved in the $_FILES array but the input fields which are processed by the form validation class are in the $_POST array.

Could you please provide the full controller and view code?

stef25 - 12 April 2009 09:41 AM

do you have to declare $image_data as private, public, ... ? if so, where?

Have a look at this post: forums/viewreply/551725/
I’d use private as this is only controller internal data.
Don’t return $image_data in your callback function, save it in a class variable.

One reason is this: user_guide/libraries/form_validation.html#callbacks

You can also process the form data that is passed to your callback and return it. If your callback returns anything other than a boolean TRUE/FALSE it is assumed that the data is your newly processed form data.

 
Posted: 12 April 2009 11:17 AM   [ # 28 ]   [ Rating: 0 ]
Joined: 2007-09-18
397 posts

pistolpete, thanks for your reply.

regarding the availability of the area from my callback function back to create() - how do you create a class variable?

below is my class Admin

print_r($this->_data); inside _do_upload() prints out the array with the image data - that works.

strangely enough, the

print "test" print_r($this->_data); 

in create() prints out “test1”. where does the “1” come from?

ive played around with public $_data, private $_data but this doesnt make a difference. im also not sure if the function __construct() is required.

any help would be much appreciated!

class Admin extends Controller {
        
        
public $_data;
    
    function 
__construct() {
            parent
::Controller();
       
}
        
        
function index() {
        
            
... some code here ...              
        
}
            
            
        
function create() {                        
            
            
print "test" print_r($this->_data);
            
            
$attributes['page_title'"Admin";
            
$attributes['products'$this->M_Products->getAllProductsSidebar();
            
$attributes['feedback'"";
            
$attributes['subtitle'"";
            
$attributes['form_open'= array('name' => 'post_new');
            
            
//validation
            
$this->form_validation->set_rules('prod_name''product name''trim|required');
            
$this->form_validation->set_rules('prod_img''product image''callback__do_upload');    
            
$this->form_validation->set_rules('prod_descr_long''long description''trim|required');
            
$this->form_validation->set_rules('prod_aff_link''affiliate link''trim|required');    
            
            if(
$this->form_validation->run() == FALSE{                
                
//send back to the view
                
$attributes['prod_name'$this->input->post('prod_name');
                
$attributes['prod_descr_long'$this->input->post('prod_descr_long');
                
$attributes['prod_aff_link'$this->input->post('prod_aff_link');    
            
                
$this->load->view('admin_view'$attributes);    
            
}
            
else {                
                $this
->M_Products->createProduct($attributes);
                
$this->load->view('admin_view'$attributes);
            
}        
          }          
          
          
function _do_upload($file{
            $config[
'upload_path''/Applications/MAMP/htdocs/my-site/images/_uploads/';
            
$config['allowed_types''jpg|gif|jpeg|png';
            
$config['max_size']    '2000';
            
$this->load->library('upload'$config);
               
            
$field_name "prod_img"//see http://ellislab.com/codeigniter/user-guide/libraries/file_uploading.html
            
if (!$this->upload->do_upload($field_name)) {
                $this
->form_validation->set_message('_do_upload'$this->upload->display_errors());
                return 
FALSE;
            
}    
            
else {    
            
                
//array with data from uploaded (not processed!) image
                //$image_data = $this->upload->data();
                
$this->_data $this->upload->data();
            
                
//process & resize image
                
$config['source_image'$config['upload_path'].$_FILES['prod_img']['name'];
                
$config['maintain_ratio'TRUE;
                
$config['height'200;
                
$config['create_thumb'TRUE;
                
                
$this->load->library('image_lib'$config);
                
$this->image_lib->resize();
                
                if(
$this->image_lib->resize() !== TRUE{
                    
print $this->image_lib->display_errors();
                    
//exit;
                
}
                print_r
($this->_data);
                
//return TRUE;                          
            
}        
          }
?> 
 Signature 

Attended EECI2009

 
Posted: 12 April 2009 01:50 PM   [ # 29 ]   [ Rating: 0 ]
Avatar
Joined: 2008-05-17
1073 posts

You access $_data before the validation ran, so $_data is empty.
So you can get the values of the uploaded file like this:

if($this->form_validation->run() == FALSE)
{                
    
....
}
else 

    print_r
($this->_data);
    ...

where does the “1” come from?

The “1” is the return value of print_r():

If you would like to capture the output of print_r(), use the return parameter. If this parameter is set to TRUE, print_r() will return its output, instead of printing it (which it does by default).

By the way:
How do you repopulate the form data if validation failed?
Have a look at the set_value() function: user_guide/libraries/form_validation.html#repopulatingform
Using this function you could omit code like that:

//send back to the view
$attributes['prod_name'$this->input->post('prod_name');
$attributes['prod_descr_long'$this->input->post('prod_descr_long');
$attributes['prod_aff_link'$this->input->post('prod_aff_link'); 

One additional comment:
Leave out the PHP closing tag: user_guide/general/styleguide.html#php_closing_tag

 
Posted: 23 October 2009 01:09 PM   [ # 30 ]   [ Rating: 0 ]
Joined: 2009-09-29
20 posts

Hey there!
Sorry to bother you guys with the same issue…
I’m basing my validation on PistolPete’s example and I’m always presented with the message:
“O campo Imagem é obrigatório.” which means: “The image field is required.”

Controller:

function enviar() {
        $this
-> validate_form();
    
}
    

     
function validate_form() {
         
        $this
->form_validation->set_error_delimiters('<p style="color:red;">''</p>');

        
$this->form_validation->set_rules('assunto''Assunto''trim|required|max_length[50]');
        
$this->form_validation->set_rules('descricao''Descrição''trim|required');
        
$this->form_validation->set_rules('userfile''Imagem''required|callback__do_upload'); 
        
        if (
$this->form_validation->run() == FALSE{
            $data[
'main_content''newsletter/newsletter_create_view';    
            
$this->load->view('includes/template'$data);    
        
else {
            
        }
            
     }
     
     
     
function _do_upload($file{
        
        $config[
'upload_path''./uploads/';
        
$config['allowed_types''gif|jpg|png';
        
$config['max_size']    '3000';
        
$config['max_width']  '1024';
        
$config['max_height']  '768';

        
$this->load->library('upload'$config);
            
        if (!
$this->upload->do_upload())
        
{
            $this
->form_validation->set_message('_do_upload'$this->upload->display_errors());
            return 
FALSE;
        
else {
            
return TRUE;
        
}
    } 

View:

<?php echo utf8_encode(form_error('assunto')); ?>
<?php 
echo utf8_encode(form_error('descricao')); ?>
<?php 
echo utf8_encode(form_error('userfile')); ?>

<form method="post" action="<?php echo site_url() . '/newsletter/enviar'; ?>" enctype="multipart/form-data">
    <
input type="text" name="assunto" value="<?php echo set_value('assunto'); ?>" size="60" />
    <
textarea name="descricao" rows="3" cols="74"><?php echo set_value('descricao'); ?></textarea>
    <
input type="file" name="userfile" />
    <
input type="submit" value="GUARDAR">
</
form

Can anyone give me a hint?
Thks a lot!!

 
2 of 3
2