ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Extended form_validation: now with file checking :)

July 21, 2009 7:36pm

Subscribe [25]
  • #1 / Jul 21, 2009 7:36pm

    devbro

    81 posts

    I have been thinking of doing this for a long time and finally did 😊.
    http://devbro.com/testing/ci_form_validation/


    I extended the form_validation to now have ability to check $_FILES (file uploading).

    here is the way it can be used:

    $this->form_validation->set_rules('image','Image','file_required|file_size_max[500]|file_allowed_type[image]');

    I added 3 set of rules so far:
    1. file_required: same as required
    2. file_size_max: define maximum file size in KB
    3. file_allowed_type: what type of file to expect.

    So what do you think? is there any way to improve it further?

  • #2 / Jul 29, 2009 4:15pm

    Wuushu

    103 posts

    Has anyone tried this? Sounds very good!

  • #3 / Jul 29, 2009 4:20pm

    devbro

    81 posts

    i used it myself in two projects already. so far no problem and it saves me writing callback_ with file upload.

  • #4 / Jul 29, 2009 5:19pm

    Johan André

    412 posts

    I’m gonna try this one out!
    If it works good (which I’m sure it will do) you are truly awesome!

  • #5 / Jul 29, 2009 10:08pm

    devbro

    81 posts

    I moved the location of the source code:
    http://devbro.com/testing/ci_form_validation/

    hope it helps.

  • #6 / Jul 31, 2009 12:13pm

    GlennJ

    65 posts

    Nice one! Just what I was looking for, will give this a go now.

  • #7 / Jul 31, 2009 12:22pm

    GlennJ

    65 posts

    Change line 95 to

    $result = $rule($postdata['name']);

    and you’ll get rid of the PHP notice :coolsmile:

  • #8 / Jul 31, 2009 1:38pm

    devbro

    81 posts

    Change line 95 to

    $result = $rule($postdata['name']);

    and you’ll get rid of the PHP notice :coolsmile:

    The issue is that if I do that then I would have problem if more fields are needed for that validation rule. also if there are more validations they will all fail.

  • #9 / Jul 31, 2009 1:45pm

    GlennJ

    65 posts

    All $_FILE entries have the [‘name’] field, so I don’t see the problem?

  • #10 / Jul 31, 2009 2:00pm

    devbro

    81 posts

    what if meta_data, size, temp_dir are the indexes that are needed? in case of allowed types name is no longer needed, just the mime type. If some sort of content checking is needed then temp_dir is needed.

    I was thinking of passing the field name instead but there may be things that need to be modified half way. Something like xss_clean or fix_mime_type or change_filename

  • #11 / Aug 02, 2009 11:51am

    Chicken's Egg

    39 posts

    Thank you for sharing this code devbro! I like your library-extension. However, I did make some changes too. If you don’t mind, I’ll post them here. :red:

    I added a few lines to the function file_max_size() to make sure that the $max_size variable actually is an integer.

    // Check if $max_size is valid
        if (preg_match("/[^0-9]/", $max_size))
        {
          return FALSE;
        }

    And I changed the function file_allowed_type() in order to make it possible to allow a few file-types. The file-types are seperated by commas. So a validation rule in my controller can look like file_allowed_type[word,jpeg].

    // FUNCTION: file_allowed_type
      // Checks if an uploaded file has a certain file type
      //
      // @Author: devbro (21 July 2009)
      // @Author: chicken's egg (2 August 2009) (edited)
      //
      // @access  public
      // @param   $file        array     File-information
      // @param   $type        string    Allowed filetype(s)
      // @return  bool
      function file_allowed_type($file,$sType)
      {
        /*
         three types allowed:
         1. mime type image/gif
         2. general mime type image application
         3. file ext pdf,xls
        */
        // Create an array of allowed filetype
        $aTypes = explode(',',$sType);
    
        // Validate file-type
        foreach($aTypes AS $key => $sType)
        {
          $sType = trim($sType);
          if(strpos($file['type'],$sType)!==FALSE)
          {
            return TRUE;
          }
        }
        // File-type not found? Invalid filetype
        $this->set_message('file_allowed_type',"%s cannot be {$file['type']}.(should be %s)");
        return FALSE;
      }

    Which brings me to a question. Why are we using $file[‘type’]? I discovered that the value of $file[‘type’] - at least on my Windows XP computer - is prescribed by the file-extension. So this function gives the same results, but is easier to handle as most of us do know file-extensions better then mime-types.

    // FUNCTION: file_allowed_type
      // Checks if an uploaded file has a certain extension.
      //
      // @Author: chicken's egg (2 August 2009)
      //
      // @access  public
      // @param   $file        array     File-information
      // @param   $type        string    Allowed filetype(s)
      // @return  bool
      function file_allowed_type($file,$sType)
      {
        // Create an array of allowed file-type
        $aTypes = explode(',',strtolower(trim($sType)));
        // Take the extension of the uploaded file
        $sExtension = strtolower(substr($file['name'],(strrpos($file['name'],".") + 1)));
        // Check if it is an allowed filetype
        if(in_array($sExtension,$aTypes))
        {
          return TRUE;
        }
        // Filetype not found? Invalid filetype
        $this->set_message('file_allowed_type',"%s cannot be {$file['type']}.(should be %s)");
        return FALSE;
      }
  • #12 / Aug 02, 2009 12:57pm

    devbro

    81 posts

    nice suggestions chicken egg. I am working on a new set of updates right now. If it is ok with you I will incorporate suggestions into my new code.

    My reason for using mime_type was my laziness in the first place. I am planning to at least modify that to look at ext as well. the only issue that I have right now is that some ext and mime_types dont match. lookup mp3 upload in the forum and you get what i mean.

  • #13 / Aug 02, 2009 6:27pm

    Chicken's Egg

    39 posts

    Of course it’s ok to use may code. I am using yours aswell. 😊

    Yes mp3 is a tricky one. May be an array with the file-extensions as keys and the mime-types as values is an idea, but that would also mean that you would limit the usability of the file-validation-class to the most common used file-types on the internet. For example:

    $aFiletypes = array(
          'bmp'  => 'image/bmp',
          'doc'  => 'application/msword',
          'gif'  => 'image/gif',
          'jpeg' => 'image/jpeg',
          'jpg'  => 'image/jpeg',
          'mid'  => 'audio/midi',
          'midi' => 'audio/midi',
          'mp3'  => 'audio/mpeg',
          'pdf'  => 'application/pdf',
          'txt'  => 'text/plain',
          'xls'  => 'application/vnd.ms-excel',
          'zip'  => 'application/zip',
        );
  • #14 / Aug 02, 2009 6:49pm

    devbro

    81 posts

    there is already a similar array in the config folder.

    Here are the stuff that I have in mind:
    1. disallow_file_type rule
    2. fix_mime_type
    3. get size from strings ‘10MB’ and ‘4KB’
    4. change_file_name (if i do this then no more rename or move after upload->do_upload() 😛 )

  • #15 / Aug 05, 2009 10:55am

    GlennJ

    65 posts

    I noticed a bug which stops checkboxes being validated.

    This is my fix, showing top and bottom of the function

    function _execute($row, $rules, $postdata = NULL, $cycles = 0)
        {
            if(isset($_FILES[$row['field']]['size']))
            {// it is a file so process as a file
    
                $postdata = $_FILES[$row['field']];
    else
            {
                parent::_execute($row, $rules, $postdata,$cycles);        
            }
    
        }

    Seems to work ok so far…

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases