I had a requirement for one of my client’s sites recently to validate the file uploaded to the media library and scan it for potential viruses. On top of periodic scanning of the uploads folder, the file also needs to be scanned in real-time during the upload process.

Luckily, this can be easily done by hooking into wp_check_filetype_and_ext filter that is used by wp_check_filetype_and_ext function. This function is originally called from the _wp_handle_upload function that is used internally by WordPress whenever any file is uploaded through the media uploader.

If we check the source code of that function, we can see that WordPress validates the uploaded file against the allowed mime types, and if it’s invalid, the variable $type and $ext will be set to false. We can use that to our advantage since the filter used will also pass that variable in the $wp_check_filetype_and_ext. It certainly feels a bit hacky to me, but it gets the job done.

In essence, we can do something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php

add_filter('wp_check_filetype_and_ext', function ($wp_check_filetype_and_ext) {
    if (!ClamAV::validate($file)) {
        $wp_check_filetype_and_ext['type'] = false;
        $wp_check_filetype_and_ext['ext']  = false;
    }

    return $wp_check_filetype_and_ext;
});

I have a separate helper class that runs an instance of ClamAV to check the validity of the file, but you can replace it with any validation that you want here. That’s it!