We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 16868
    • 24 Posts
    AFAIK Formit doesn’t provide a way to limit file size and type for file upload in forms. So I made a custom validator and want to post it here to get comments and maybe even help others.

    I have zero PHP skills so any comments on my snippet would be very welcome!

    One remaining problem is upload only fails on the server side, so users only find out their file has been rejected after waiting for it to upload. To warn about file size I tried using a ’maxlength’ on the input and then this before the input (both had zero effect):

    <input type='hidden' name='MAX_FILE_SIZE' value='".$max_file_size."'>


    As for client-side file type checking, Javascript seems the best (only?) practical way for now.

    Any suggestions?

    Anyway here’s the custom validator snippet:

    Going from these resources:

    http://codingpad.maryspad.com/2011/03/08/modx-revolution-for-complete-beginners-part-9-using-formit-for-contact-forms/

    http://codingpad.maryspad.com/2011/03/09/modx-revolution-adding-an-attachment-field-to-a-formit-form/

    http://modxcms.com/forums/index.php/topic,56385.0.html

    http://rtfm.modx.com/display/ADDON/FormIt.Validators#FormIt.Validators-CustomValidators

    I created this:

    <?php
      //Set allowed extensions and filesize
    $allowedextensions = 'jpg,JPG,jpeg,JPEG,doc,docx,pdf,PDF,txt,png,PNG,zip';
    $maxfilesize = 12582912; //Size limit in bytes
    
      //Set error messages
      //Coded max file size is bigger than the stated size for flexibility 
    $error_oversize = 'File size is limited to 10MB.'; 
    $error_wrongtype = 'File type not supported.';
      
      // Get file name and size.
      //'document' is the name of the input on the form
    $filename = basename( $_FILES['document']['name'] ); 
    $filesize = filesize( $_FILES['document']['tmp_name'] );
    
      // Get file's extension
    $ext = pathinfo($filename, PATHINFO_EXTENSION);
      
      //Fill an array with the allowed extensions  
    $ext_array = explode(',', $allowedextensions);
    
      //Check the extension against the allowed set
      //&& check file is not over size
    if( (in_array($ext, $ext_array)) && ($filesize < $maxfilesize) )
    {
      //Succeed
      return true;
    }
    else 
    {
      if (!in_array($ext, $ext_array))
      {
    	$errormsg = $error_wrongtype;
      }
      if ($filesize > $maxfilesize)
      {
    	$errormsg = $error_oversize;
      }
    	//Fail and generate error message
      $validator->addError('document',$errormsg);
      return false;
    }
    ?>

      • 36448
      • 58 Posts
      Thanks leekohlbradley, it's a great customValidators snippet!

      I improved it a little bit - here my snippet (maxFileSize) with a parameter for the file size:

      <?php
            //Set allowed extensions and filesize
          $allowedextensions = 'jpg,jpeg,png,gif,tif,doc,docx,xls,xlsx,ods,ots,odg,odp,pdf,txt,rtf,zip';
            //Size limit in Mega bytes
          $maxfilesize = (float)$param * 1048576; // byte to mb
           
            //Set error messages
            //Coded max file size is bigger than the stated size for flexibility
          $error_oversize = 'File size is limited! max. ' .$maxfilesize/1048576 . 'MB!';
          $error_wrongtype = 'File type not supported! only: ' .$allowedextensions;
             
            // Get file name and size.
            //'document' is the name of the input on the form
          $filename = basename( $_FILES['document']['name'] );
          $filesize = filesize( $_FILES['document']['tmp_name'] );
      
            // if without document
          if ($filename == '') {
            return true;
          }
           
            // Get file's extension
          $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
             
            //Fill an array with the allowed extensions 
          $ext_array = explode(',', $allowedextensions);
           
            //Check the extension against the allowed set
            //&& check file is not over size
          if( (in_array($ext, $ext_array)) && ($filesize <= $maxfilesize) )
          {
            //Succeed
            return true;
          }
          else
          {
            if (!in_array($ext, $ext_array))
            {
              $errormsg = $error_wrongtype;
            }
            if ($filesize > $maxfilesize)
            {
              $errormsg = $error_oversize;
            }
              //Fail and generate error message
            $validator->addError($key,$errormsg);
            return false;
          }
      


      FormIt call, e.g. file size 4.5MB max:
      [[!FormIt?
      ....
      &customValidators=`maxFileSize`
      &validate=`document:maxFileSize=`4.5``
      ....
      ]]
      [ed. note: krischel last edited this post 11 years, 10 months ago.]
        • 8822
        • 203 Posts
        I have a massive issue with people attaching large images in my formit form - a completely blank page is simply displayed! I am trying therefore to restrict the file size that people are allowed to upload and so far have only come across the above as a solution - unfortunately i can't get it to work - i have created a snippet maxFileSize, added in &customerValidators and &validate (changing the name document to upload-image1) and have the following specified in my formit form:

        	<div>
         <label for="image-upload1"  class="formlabels">Upload Image 1:</label>
                      <input name="image-upload1" type="file" class="forminputs" id="image-upload1"  value="[[!+fi.image-upload1]]"/><br/><span class="validationerror">[[!+fi.error.image-upload1]]</span>
        	</div>	


        what am i missing?
          • 31255
          • 118 Posts
          Ok, tried that Jo`s snippet. Bigger file is sended. No error messages.
          Here`s my sendfile formit call:
          [[!FormIt? &hooks=`spam,email,redirect`
          &customValidators=`maxFileSize`
          &validate=`document:maxFileSize=`2``
          &emailTpl=`f5.laheta-tiedosto-lahetys.tpl`
          &emailSubject=`Tiedosto sivuilta`
          &emailTo=`[[+addressTo]]`
          &redirectTo=`x` ]]


          Send file field in form:
          <label for="liite">Valitse tiedosto:
          <input id="liite" type="file" name="liite" value="[[+fi.liite]]" />
          </label>


          I think I`m missing something, but what?

          I took extra mark at the end of this: &validate=`document:maxFileSize=`2`
          (no good, form stopped sending) [ed. note: valokammi last edited this post 10 years, 1 month ago.]
            Tassu, webmaster of Valokammi
            • 28120
            • 380 Posts
            I just hit the same problem.

            The script is hard coded so the file field name must be "document"

            <input id="liite" type="file" name="document" value="[[+fi.liite]]" />


            I renamed my field to "document" because life's too short to edit the script.
            • Only an idea but I think you need to change the syntax of your &validate parameter:
              &validate=`document:maxFileSize=`2``

              To:
              &validate=`document:maxFileSize=^2^`
                Garry Nutting
                Senior Developer
                MODX, LLC

                Email: [email protected]
                Twitter: @garryn
                Web: modx.com
                • 48071
                • 1 Posts
                Good morning,

                I have modified the script to get the name of the input field via $key. Reason: I needed to use more than one file input field within the same form.

                <?php
                //Set allowed extensions and filesize
                    $allowedextensions = 'jpg,jpeg,png,gif,tif,doc,docx,xls,xlsx,ods,ots,odg,odp,pdf,txt,rtf,zip';
                      //Size limit in Mega bytes
                    $maxfilesize = (float)$param * 1048576; // byte to mb
                    
                      //Set error messages
                      //Coded max file size is bigger than the stated size for flexibility
                    $error_oversize = 'File size is limited! max. ' .$maxfilesize/1048576 . 'MB!';
                    $error_wrongtype = 'File type not supported! only: ' .$allowedextensions;
                        
                      // Get file name and size.
                    $filename = basename( $_FILES[$key]['name'] );
                    $filesize = filesize( $_FILES[$key]['tmp_name'] );
                 
                      // if without document
                    if ($filename == '') {
                      return true;
                    }
                      
                      // Get file's extension
                    $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
                        
                      //Fill an array with the allowed extensions 
                    $ext_array = explode(',', $allowedextensions);
                      
                      //Check the extension against the allowed set
                      //&& check file is not over size
                    if( (in_array($ext, $ext_array)) && ($filesize <= $maxfilesize) )
                    {
                      //Succeed
                      return true;
                    }
                    else
                    {
                      if (!in_array($ext, $ext_array))
                      {
                        $errormsg = $error_wrongtype;
                      }
                      if ($filesize > $maxfilesize)
                      {
                        $errormsg = $error_oversize;
                      }
                        //Fail and generate error message
                      $validator->addError($key,$errormsg);
                      return false;
                    }


                changed
                $filename = basename( $_FILES['document']['name'] );
                    $filesize = filesize( $_FILES['document']['tmp_name'] );


                to

                $filename = basename( $_FILES[$key]['name'] );
                    $filesize = filesize( $_FILES[$key]['tmp_name'] );


                and using @gary nuttings advice used the following:

                 
                &customValidators=`maxFileSize`
                   &validate=`
                cover:maxFileSize=^1.5^,
                   document:maxFileSize=^1.5^
                


                I hope that helps someone