1

I have a simple Drupal 8 form where users can upload a picture.

The issue is that the upload_max_filesize is set to 2M on the server. So if I upload a bigger file, the form submission fails:

Fatal error: Call to a member function save() on a non-object

Here is what I have tried in the submitForm:

$validators = array(
  'file_validate_is_image' => array(),
  'file_validate_size' => array(1024 * 1024),
);

/** @var File[] $pictures */
$pictures = file_save_upload('picture_upload', $validators, 'public://');
if(null !== $pictures) {
    /** @var File $picture */
    $picture = reset($pictures);
    $picture->save();
}

This actually leads to 2 issues when trying to upload a large .jpg image:

  1. The file could not be saved because it exceeds 2 MB, the maximum allowed size for uploads.
  2. Image type not supported. Allowed types: png jpeg gif

So my questions are: why does the validator not accept a .jpg image? How would I go about avoiding the fatal error and return to the form if the file size is too big?

Edit:

I have changed my validator to this now:

$validators = array(
  'file_validate_extensions' => array('gif png jpg jpeg'),
  'file_validate_size' => array(2 * 1024 * 1024), // 2MB file size limit
);

It works now in the way that it accepts my .jpg image and doesn't accept files larger than 2MB. But how would I go about returning to the form with an error message instead of going straight to the PHP fatal error?

2

The return value from file_save_upload() is:

array Function returns array of files or a single file object if $delta != NULL. Each file object contains the file information if the upload succeeded or FALSE in the event of an error. Function returns NULL if no file was uploaded.

So you can handle it a few different ways.

$picture = reset($pictures);
if ($picture === FALSE) {
  $form_state->setErrorByName('field_name', $this->t('Error!'));
}

or

$picture = reset($pictures);
if (!$picture instanceof \Drupal\file\Entity\File) {
  $form_state->setErrorByName('field_name', $this->t('Error!'));
}

are the first that come to mind.

This code will need to be in a validate method rather than a submit method, so that you're setting errors in the right place. You can leave the ->save() logic in the submit method, safe in the knowledge that the file has been validated and exists before that code is executed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.