Skip Navigation

[Resolved] custom field type file validation

This thread is resolved. Here is a description of the problem and solution.

Problem:

I am having an issue with restricting file types to PDF and DOCX in a custom form on my WordPress website. The file type validation code I am using does not seem to work.

Solution:

Go to the Form edit screen and uncheck "Use the WordPress Media Library manager for image, video, audio, or file fields". Then, use the following code snippet by adding it to your theme's functions.php file or a custom plugin:

add_filter('cred_form_validate', 'cred_filetype_size_validation', 10, 2);

function cred_filetype_size_validation($field_data, $form_data) {                    
    list($fields, $errors) = $field_data;

    if (14 == $form_data['id']) {
        $file_type_uploaded = $_FILES['wpcf-documento-obra-escritor']['type'];
 
        if (!('application/pdf' == $file_type_uploaded) || ($file_type_uploaded == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')) {
            $errors['documento-obra-escritor'] = 'Sorry, the file you have uploaded is not of the correct type.';   
        } 
    }

    return array($fields, $errors);
}

Make sure to replace 14 with your form's actual ID.

Relevant Documentation:

https://toolset.com/documentation/programmer-reference/cred-api/#cred_form_validate

This support ticket is created 2 years, 3 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

This topic contains 6 replies, has 2 voices.

Last updated by sergioC-13 2 years, 3 months ago.

Assisted by: Christopher Amirian.

Author
Posts
#2610647

Tell us what you are trying to do?
im trying to restrict the type of file upload in cred forms but it doesnt.
The field form should allow only pdf and docx documents.
Right now im using the hook cred_save_data.
The weard thing is i've created for a client the same form and i tried it before and that one works just fine.
What is the link to your site?
right now im in a local environment.
Here the file field in the form:
<div class="form-group">
<label for="%%FORM_ID%%_documento-obra-escritor">[cred_i18n name='documento-obra-escritor-label']
Documento obra escritor (PDF, DOCX)[/cred_i18n]</label>
[cred_field field='documento-obra-escritor' force_type='field' class='form-control' output='bootstrap']
</div>
Here is the functions involved:
function wrc_get_form_ids() {
$create_user = get_option('create_user_wrc');

$update_user = get_option('update_user_wrc');
$delete_user = get_option('delete_user_wrc');

$create_literary_work = get_option('create_literary_work_wrc');
$update_literary_work = get_option('update_literary_work_wrc');
$create_moderate_work = get_option('moderate_literary_work_wrc');

$form_ids = array(
'create_user_wrc' => $create_user,
'update_user_wrc' => $update_user,
'delete_user_wrc' => $delete_user,
'create_literary_work_wrc' => $create_literary_work,
'update_literary_work_wrc' => $update_literary_work,
'moderate_literary_work_wrc'=> isset($moderate_literary_work) ? $moderate_literary_work : null
);
return $form_ids;
}
function cred_filetype_size_validation($field_data, $form_data){
$form_ids = wrc_get_form_ids();
// Field data are field values and errors
list($fields,$errors)=$field_data;
$allow_types = array(
'pdf' => 'application/pdf',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
);

if (( $form_ids['update_literary_work_wrc'] == $form_data['id']) && !empty($_FILES['wpcf-documento-obra-escritor']['name'])) {

//Retrieve file type and size
$file_type_uploaded = $_FILES['wpcf-documento-obra-escritor']['type'];
$file_size_uploaded = $_FILES['wpcf-documento-obra-escritor']['size'];

if ( !in_array($file_type_uploaded, $allow_types) || $file_size_uploaded > 100000 ) {

$errors['documento-obra-escritor'] = 'Lo sentimos, solo se aceptan archivos DOCX ó PDF y no deben exceder los 100KB.';

}

}
if (( $form_ids['create_literary_work_wrc'] == $form_data['id']) && (isset($_FILES['wpcf-documento-obra-escritor']['type'])) && (isset($_FILES['wpcf-documento-obra-escritor']['size']))) {

//Retrieve file type
$file_type_uploaded=$_FILES['wpcf-documento-obra-escritor']['type'];

if ( !in_array($file_type_uploaded,$allow_types) ) {

$errors['documento-obra-escritor']='Lo sentimos, solo se aceptan archivos DOCX ó PDF:';

}

}
if (( $form_ids['moderate_literary_work_wrc'] == $form_data['id']) && (isset($_FILES['wpcf-documento-obra-escritor']['type'])) && (isset($_FILES['wpcf-documento-obra-escritor']['size']))) {

$file_type_uploaded=$_FILES['wpcf-documento-obra-escritor']['type'];

if ( !in_array($file_type_uploaded,$allow_types) ) {

$errors['documento-obra-escritor']='Lo sentimos, solo se aceptan archivos DOCX ó PDF:';

}

}

return array($fields,$errors);
}
add_filter('cred_save_data','cred_filetype_size_validation',10,2);

PD: i realized this problem because now i'm creating a form where only you could upload mp4 video and i'm having the same problem.
Thanks in advance.

#2610855

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

This will need a real test scenario to be able to judge the code and how it works.

I created a clean installation of Toolset and WordPress which you can log in to here:

hidden link

Enable the plugins you need and you can add your code in the Toolset custom code feature:
https://toolset.com/documentation/programmer-reference/adding-custom-code/using-toolset-to-add-custom-code/

Now regarding the current code, I suggest the improvements below:

- Add an initial check to see if the wpcf-documento-obra-escritor field exists in the $_FILES array before trying to access it. This could help prevent PHP warnings if the field does not exist.

- Add error logging for the file type and size that are captured from the $_FILES array.

- Check the actual MIME type of the uploaded file using the finfo_file function and logs the result.

- Simplify the file type and size validation by performing it for each form type in a loop, rather than having separate if statements for each form type.

Here is a sample of the improvements above (Not tested, that needs to be done in the clean installation)

function cred_filetype_size_validation($field_data, $form_data) {
    $form_ids = wrc_get_form_ids();
    // Field data are field values and errors
    list($fields,$errors) = $field_data;
    $allow_types = array(
        'pdf' => 'application/pdf',
        'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    );

    // Check if the file upload field exists in the $_FILES array
    if(isset($_FILES['wpcf-documento-obra-escritor'])) {
        $file = $_FILES['wpcf-documento-obra-escritor'];

        // Log the file type and size
        error_log("File type: " . $file['type']);
        error_log("File size: " . $file['size']);

        // Check the actual MIME type of the uploaded file
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime_type = finfo_file($finfo, $file['tmp_name']);
        finfo_close($finfo);
        error_log("Actual MIME type: " . $mime_type);

        // Perform the file type and size validation for each form type
        foreach($form_ids as $form_type => $form_id) {
            if ($form_id == $form_data['id'] && !empty($file['name'])) {
                if (!in_array($file['type'], $allow_types) || $file['size'] > 100000) {
                    $errors['documento-obra-escritor'] = 'Lo sentimos, solo se aceptan archivos DOCX ó PDF y no deben exceder los 100KB.';
                }
            }
        }
    }

    return array($fields, $errors);
}
add_filter('cred_save_data', 'cred_filetype_size_validation', 10, 2);


Please note that the error_log function in PHP will output to the server's error log by default. The location of this log varies depending on your server configuration. If you want to output to a specific file, you can specify that as a second parameter in the error_log function, like so: error_log("message", 3, "/path/to/my/error.log");.


Also, keep in mind that this code still assumes that your form IDs are being correctly retrieved with the wrc_get_form_ids function. If you're still having problems, you may want to check that this function is working as expected.

Thanks.

#2610861

Hello and thanks for your response Christopher,
I just have created in your installation : 1- custom field with the following slug 'documento-obra-escritor' inside the Settings for custom field for writers group.
2- created a simple post form with a title field and the one for the file type.
This form should create in this scenario a post.
3- added the custom function in SETTINGS-> CUSTOM CODE with the actual form's ID (14)
Now, i've tried to see if the validation loading a file accours but nothing. i could load a video, creating obviously the post with no error shown.
Thanks in advace

#2611071

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

I checked and as you checked the option below in the Form edit screen:

Use the WordPress Media Library manager for image, video, audio, or file fields

The form delegates the functionality to WordPress Media Library and the uploading and everything happens there.

If you turn off that option then the code I added to the custom code in Toolset should work.

Thanks.

#2611081

Hello Christopher,
I just tried to fill up the form after unchecked that option 'WordPress Media Library...' the result form me was the same. the form still allows me to load for example, the video witout say anything in the form's error messages.
I am missing something?

#2611299

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

The custom code was not active, I activated it and it works now.

Here is the code and you can adapt it to your use-case:

/**
 * New custom code snippet (replace this with snippet description).
 */

toolset_snippet_security_check() or die( 'Direct access is not allowed' );

add_filter('cred_form_validate','cred_filetype_size_validation',10,2);
function cred_filetype_size_validation($field_data, $form_data)
{   		         
    // Field data are field values and errors 
    list($fields,$errors)=$field_data;
  
    //Run the rest of code for this CRED ONLY and IF the file is upload type and size are set.
    if ( ( 14 == $form_data['id']) ) {

        //Retrieve file type
        $file_type_uploaded = $_FILES['wpcf-documento-obra-escritor']['type'];

      
        //Validate files uploaded, make sure its PDF file type
        if (!(  ('application/pdf' == $file_type_uploaded) || ($file_type_uploaded == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') )) {
              
            $errors['documento-obra-escritor']='Sorry the file you have uploaded is not of the correct type.';   
                  
        } 
   
    }
    //return result
    return array($fields,$errors);
}
#2611321

My issue is resolved now. Thank you Christopher!