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]
  • #16 / Aug 05, 2009 10:58am

    Johan André

    412 posts

    It’s almost impossible to read when you don’t use code-tags…

  • #17 / Aug 05, 2009 10:59am

    GlennJ

    65 posts

    Sorry, my first post was too long and it lost the end code tag, should be ok now…

  • #18 / Aug 05, 2009 1:30pm

    devbro

    81 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…


    So you basically moved their order of if-statement.

    Can you give me the html form that it did caused the code to break please.

  • #19 / Aug 05, 2009 1:35pm

    GlennJ

    65 posts

    The validation line was

    $this->form_validation->set_rules('agree', 'lang:main_agree_terms', 'trim|required');

    This is validating a standard HTML checkbox.

    The reason it didn’t work before is that if a checkbox is *not* checked it will not be included in the $_POST variable. So you need to check to see if the field is a file upload, if not - process as normal (even if it doesn’t exist in $_POST).

    That make sense?

  • #20 / Aug 05, 2009 1:46pm

    devbro

    81 posts

    The validation line was

    $this->form_validation->set_rules('agree', 'lang:main_agree_terms', 'trim|required');

    This is validating a standard HTML checkbox.

    The reason it didn’t work before is that if a checkbox is *not* checked it will not be included in the $_POST variable. So you need to check to see if the field is a file upload, if not - process as normal (even if it doesn’t exist in $_POST).

    That make sense?

    I got it. Thanks for the explanation. I implement the update to the code.

  • #21 / Aug 06, 2009 6:27pm

    Chicken's Egg

    39 posts

    GlennJ, you saved my day! I discovered this evening that a select box which had the rule ‘required’ was not stopping the form from being submitted when the other input fields were filled in correctly. I felt so happy when I found your solution! But there is one thing I don’t understand. Wenn I saw the new code, I was afraid that if I would upload a file other fields would not be validated anymore. But that is certainly not the case. It worked like te charm. But, how come?

    Below is also some new code. I altered the function file_size_max() once again. The function now watches the server settings too. If the maximum file size the website developer allows, crosses the limits of the server configuration, his value is overwritten by the value given by the server.

    // FUNCTION: file_size_max
      // Checks if the filesize of the uploaded file isn't to big.
      //
      // @Author: devbro (21 July 2009)
      // @Author: Chicken Egg (6 August 2009) (edited)
      //
      // @access  public
      // @param   $file        array     File-information
      // @param   $max_size    integer   Filesize in Kb
      // @return  bool
      function file_size_max($file,$max_size)
      {
        // Check if $max_size is valid
        if (preg_match("/[^0-9]/", $max_size))
        {
          return FALSE;
        }
    
        // Check if the given maximum filesize is also accepted by the server.
        // If not -> alter the value to its maximum
           // Step 1: Take the minimum: post_max_size or upload_max_filesize
           $max_server_upload_size = min($this->_let_to_num(ini_get('post_max_size')), $this->_let_to_num(ini_get('upload_max_filesize')));
           // Step 2: Calculate the max upload size given by the webmaster in bits.
           $max_user_upload_size   = $max_size * 1024;
           // Step 3: Decide which one to use.
           $max_size = min($max_server_upload_size,$max_user_upload_size);
    
        // 1 KB = 1024 bits
        if($file['size'] > $max_size)
        {
          $max_size /= 1024;
          $this->set_message('file_size_max',"%s is too big. (max allowed is $max_size KB)");
          return FALSE;
        }
        return TRUE;
      }
    
      // FUNCTION: _let_to_num()
      // This function transforms the php.ini notation for
      // numbers (like '2M') to an integer. (bits)
      //
      // Author: gilthans dot NO dot SPAM at gmail dot com
      // Published: 03-Dec-2007 06:52
      // Source: php.net - <a href="http://www.php.net/manual/en/ini.core.php#79564">http://www.php.net/manual/en/ini.core.php#79564</a>
      //
      // @param    $v           string      String container filesize in letters.
      // @output                integer     Filesize in bits.
      private function _let_to_num($v)
      {
        $l = substr($v, -1);
        $ret = substr($v, 0, -1);
        switch(strtoupper($l)){
          case 'P':
            $ret *= 1024;
          case 'T':
            $ret *= 1024;
          case 'G':
            $ret *= 1024;
          case 'M':
            $ret *= 1024;
          case 'K':
            $ret *= 1024;
            break;
        }
        return $ret;
      }
  • #22 / Aug 06, 2009 6:38pm

    devbro

    81 posts

    There is an issue here check this link:
    http://ca3.php.net/manual/en/features.file-upload.errors.php

    lookup these:
    UPLOAD_ERR_INI_SIZE
    UPLOAD_ERR_FORM_SIZE

    As you can see if the file size is already violated then the file will not be available.

    Will it be ok if I use your _let_to_num($v) in the new version of the code?

  • #23 / Aug 07, 2009 5:29am

    quest13

    35 posts

    It seems to solve most of the upload issues in a simple and effective way. Please can you clarify on following points as I am new to php and CI.


    1.Should I save this extension of class validation as a separate file in library ? or simply I can paste it on the ‘form_validation’ library ?


    2.In view, we give set_value for text type. How to give set_value for file type ? Is it the same like text type ?

    I tried it by creating a separate file and included in the library.It didn’t work.( I did include that library in controller)and I tried set_value and that too didn’t work.

    Any help in this regard from any one of you is highly appreciated.

    Thanks in advance.

  • #24 / Aug 07, 2009 6:14am

    GlennJ

    65 posts

    1) You should extend the the class, don’t change the CI code as you’ll have a nightmare if you want to upgrade to the latest version.

    2) You can’t set the value of a file field, due to security reasons (e.g. you could set it to a file they didn’t specify and grab it from their system!).

  • #25 / Aug 07, 2009 8:22am

    Chicken's Egg

    39 posts

    Will it be ok if I use your _let_to_num($v) in the new version of the code?

    Of course, but you might be even more interested in this one:

    function let_to_bit($sValue)
      {
        // Split value from name
        if(!preg_match('/([0-9]+)([ptgmkb]{1,2}|)/ui',$sValue,$aMatches))
        { // Invalid input
          return FALSE;
        };
        if(empty($aMatches[2]))
        { // No name -> Enter default value
          $aMatches[2] = 'KB';
        };
        if(strlen($aMatches[2]) == 1)
        { // Shorted name -> full name
          $aMatches[2] .= 'B';
        }
        $iBit   = (substr($aMatches[2], -1) == 'B') ? 1024 : 1000;
        // Calculate bits:
        switch(strtoupper(substr($aMatches[2],0,1))){
          case 'P':
            $aMatches[1] *= $iBit;
          case 'T':
            $aMatches[1] *= $iBit;
          case 'G':
            $aMatches[1] *= $iBit;
          case 'M':
            $aMatches[1] *= $iBit;
          case 'K':
            $aMatches[1] *= $iBit;
            break;
        }
    
        // Return the value in bits
        return $aMatches[1];
      }
    
      // The following lines were used to test the above function:
      echo '1 '.let_to_bit('')    . '
    '; // returns FALSE
      echo '2 '.let_to_bit('2')   . '
    '; // returns 2048
      echo '3 '.let_to_bit('2K')  . '
    '; // returns 2048
      echo '4 '.let_to_bit('2L')  . '
    '; // returns 2048
      echo '5 '.let_to_bit('2Kb') . '
    '; // returns 2000
      echo '6 '.let_to_bit('2KB') . '
    '; // returns 2048

    I wrote the function for your extension, so please feel free to use it if you like.

  • #26 / Aug 07, 2009 8:59am

    devbro

    81 posts

    2.In view, we give set_value for text type. How to give set_value for file type ? Is it the same like text type ?

    To approach this and reduce the headache of uploading files on each form_validation failure you can do this:

    1. if file had no problem copy it to temp folder and keep the link to it in session.
    2. on your form if the link is specified then make the field optional.

  • #27 / Aug 08, 2009 6:42am

    quest13

    35 posts

    I was away from code igniter forum for the past one month as I was busy doing a project in wordpress. I found a tremendous difference between CI and wordpress or any other framework as a matter of fact,in terms of forum response and technical bench strength. The response from CI is just overwhelming.I sometimes wonder whether someone is already started replying my question when I just start typing in the forum ! The response is so quick and so prompt.
    I have become a die-hard fan of CI now.

    Thanks once again for my file upload validation query. But I still have one problem.In my view page, I have only “name” and “file” mentioned, not the size. But in file_required function, it checks for the ‘size’(===0).It means I have to tell about the size also in my view page as a mandatory requirement ?

    Thanks

  • #28 / Aug 08, 2009 7:10am

    GlennJ

    65 posts

    The size is handled automatically, all you need is the file field in you view. PHP will then generate a global variable with all the details of the uploaded file(s), ‘size’ is one of the attributes.

    See http://us3.php.net/manual/en/reserved.variables.files.php for more information.

  • #29 / Aug 08, 2009 1:55pm

    devbro

    81 posts

    For Those of you that like this class and are using it I have a news 😊
    The new version of the code is now completed. you can check it out at:
    http://devbro.com/testing/ci_form_validation/

    I have added a few new rules:
    file_min_size
    file_disallowed_type
    file_image_mindim
    file_image_maxdim

    let me know what you think of the new code.

  • #30 / Aug 09, 2009 5:46pm

    Chicken's Egg

    39 posts

    Great work Devbro. I’m Looking forward to upgrade to version 2. :p

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

ExpressionEngine News!

#eecms, #events, #releases