I am building a form with a required file field as such:

…

$form["my-image"] = array(
	"#title"		=> t("Provide an image here"),
	"#type"		=> "file",
	"#required"	=> true,
);
$form["#attributes"]["enctype"] = "multipart/form-data";

…

In PHP, the file is correctly transmitted in the $_FILES autoglobal, although in a somewhat awkward structure, since Drupal renames the item to 'files[my-image]', which results in the attributes of the file being spread among the name, type, tmp_name, error, and size subarray, respectively, in the $_FILES array:

$_FILES:array(1) {
  ["files"]=>
  array(5) {
    ["name"]=>
    array(1) {
      ["my-image"]=>
      string(15) "drupal_logo.png"
    }
    ["type"]=>
    array(1) {
      ["my-image"]=>
      string(9) "image/png"
    }
    ["tmp_name"]=>
    array(1) {
      ["my-image"]=>
      string(32) "C:\Programme\xampp\tmp\php6D.tmp"
    }
    ["error"]=>
    array(1) {
      ["my-image"]=>
      int(0)
    }
    ["size"]=>
    array(1) {
      ["my-image"]=>
      int(2753)
    }
  }
}

_form_validate, though, doesn't check the $_FILES autoglobal in case of a required file form element, it just checks the value for the '#value' index of the element array, which is empty for attached files in multipart forms (that's why we have to define a different enctype in the first place, duh!).

Solution:
branch the code in _form_validate to check the $_FILES autoglobal in case of a required file field.

And please, branch the code for auto-naming file elements as well while you're at it, since it would be way easier to have all the name, type, tmp_name, error, and size information in one array for the form file element, not the other way round.

Thanks a lot,
Skiller

Comments

Skiller-1’s picture

Ah well, maybe I should just state the obvious, which is that Drupal shows an error message for required file fields, ignoring the input and telling you that it is required.

yonailo’s picture

subscribing, this bug is quite annoying, I have spent all the morning trying to figure out why I was always getting "this field is required" although I was filling up the upload field.

sumgai’s picture

Is anyone planning to fix this? It would be nice.

Many thanks in advance.

keesje’s picture

Title: _form_validate doesn't handle required file field correctly » Workaround

Workaround for D5, not tested but might work in D6:

Set the #default_value property like:

  $form['file1'] = array(
      '#type' => 'file',
      //-
      -//
      '#required' => TRUE,
      '#default_value' => 'dummy',
  );

The file field validates OK, regardless if a file is uploaded or not.
The required state is only there to display the asterisk ;)

Now validate the file field yourself inside a hook_validate:

    if(!file_check_upload('file1'){
      form_set_error('file1', t('The field file 1 is required'));
    }

Since this is probably not gonna be fixed in core in current stable releases, this might be useful.

Regards,

Kees
Qrios Drupal Support

keesje’s picture

Sorry :)

stoptime’s picture

Title: Workaround » _form_validate doesn't handle required file field correctly

The above D5 validation solution doesn't seem to work on D6 (placing a dummy default value). But this seems to be doing the job in one of my modules:

Note: 'file_1' is the name of the file field I'm checking.

function my_module_build_form_validate($form, $form_state) {
	if ($_FILES['files']['name']['file_1'] == '') {
		form_set_error('file_1', t('Please upload at least one picture'));
	}
	return $form;
}
quicksketch’s picture

Status: Active » Closed (duplicate)