Sometimes, it might be necessary to add validation code to a filefield field. For example, in case you allow uploading a very specific file type, you might want to check that the user is uploading a valid file and not just one with the correct file extension. In order to do so, a validator must be added to filefield.

This can be done by changing (altering) the code of the form, which includes the filefield. Therefore, you have to implement hook_form_alter() in a custom module:

function example_form_alter(&$form, $form_state, $form_id) {
  if ($form_id != 'ID_OF_YOUR_FORM')
    return;

  $form['FIELDNAME'][0]['#upload_validators']['example_FUNCTIONNAME'] = array();

  return $form;
}

Now, the validator function must be provided, too.

function example_FUNCTIONNAME($field) {
  // variable for error messages
  $errors = array();

  // do some processing on the field
  $filepath = $field->filepath;

  ...

  // in case of error, add error message
  $errors[] = t('Validation failed, because...');

  return $errors;
}

It is important that your module gets processed after the modules filefield and CCK. If your module is processed before, the filefield code won't be present in the $form variable in hook_form_alter(...) and it is impossible to add a validation handler. The processing order of modules is controlled by their weight stored in the {system} table. The example module must have a larger value than content (CCK) and filefield. See http://drupal.org/node/110238 for details on how to adjust the weight value.

Comments

hatsch’s picture

hi there,
i need to validate a file field. this is my first custom module, so maybe i just miss something very trivial...
actually there is no real validation yet but i just return $errors[] = t('Validation Error'); so in my understanding there should be an error everytime i save the node
unfortunately the code doesn't seem to work.

function upload_duration_form_alter(&$form, $form_state, $form_id) {
//if ($form_id != 'page_node_form')
//  return;
$form['field_videoclip'][0]['#upload_validators']['upload_duration_ckeckduration'] = array();
return $form;
function upload_duration_checkduration($field) {
$errors = array();
$errors[] = t('Validation Error');
return $errors;

thank you for any suggestions?

edit:
i set the module weight to 99 with the util module.

hatsch’s picture

i don't know exactly what was wrong with my code, but the additional validation is now working. thanks for your code snipplets :)

geantbrun’s picture

Hi,
I have the same problem as you Hatsch (except that it still does not work...). Did the same as you, set the weight of my module to 99, commented the line testing the form_id (just to be sure that it's not an issue related to that). I do not get any validation error as I would expect it. Like if the upload validation function is never called.
Any idea?

hatsch’s picture

no sorry.
overlooked my code again, and i can't see any difference.

hope you find a solution..

greets

cesabal’s picture

Hi, thanks for this. really helped to my.

I have a question:

The element of my form is a container, so i wrote $form[$field_name][$node_lang][$max_key]['#upload_validators']['custom_function'] = array($node_id);

$max_key because the element input type file is the last element of the array, the others are the just uploaded files.

Once it has completed loading the file, how to modify elements of the form?, keep in mind that the load is done without refreshing the page.

sachintonte’s picture

i am using this same code.. for my validation

but this is not working please let me know what i do

sachintonte’s picture

i am using #upload_validators, but this is not working,
Please let me knoe.. is it working in drupal 7 or not

or for this upload_validators need any file extention in php.ini file .. Please let me knoe

Bilmar’s picture

Currently users only get the message "the file in the x field was unable to be uploaded" for all errors.

I was wondering if it is possible to customize these messages depending on what is not allowing the upload, ie "the file is too large to be uploaded."

I would appreciate any support!

Anonymous’s picture

I want to specify a certain file type as well, but I'd also like to set a minimum size for an image field. Yes, minimum. Need to make sure the registrants submit a large enough photo to work with. Does anyone have ideas on how to do that?
Thanks

adamtyoung’s picture

I'm trying to do this with a regular CCK text field and so far have had no luck. Anyone else get this to work?

Adam Young
Vancouver, BC
http://www.adamtyoung.ca

thatjustin’s picture

It seems like there is the need for a general file upload validation scheme. In my example, I am looking for a way to take the output of ImageMagick's identify to check the dpi/resolution (not dimensions) of an uploaded file.
As in:

$ identify -verbose 021.png|grep Resolution
  Resolution: 72x72

And I believe that this may be the way forward. Anyone else have any insight. (crossposted to http://drupal.org/node/890540#comment-5205044 )

Thanks!

gajanannehul’s picture

Hi,

$form['FIELDNAME'][0]['#upload_validators']['example_FUNCTIONNAME'] = array();

the above code is working for first image only, anybody knows how to make it work for image with multivalue.

Thanks in advance!!!

umed91’s picture

Hi,

For an image field with multiple values, I tried to use it like this

foreach ($form['FIELDNAME']['widget'] as $index => $widget){
$form['FIELDNAME']['widget'][$index]['#upload_validators']['example_FUNCTIONNAME'] = [];
}

but I am getting an error like, Error: Cannot use a scalar value as an array

I am on drupal 9.5.10