Mr Treublaan 1-3
1097 DP Amsterdam
The Netherlands

Multiple files upload in a custom Drupal form programmatically.

Native, clean example Drupal code
01 Sep, 2020 Drupal

Home Blog Multiple files upload in ...

Drupal multiple file upload custom form

Last blog post I shared how to implement rich text in a custom Drupal 9 form, I faced similar issue with files in OpenLucius: couldn't find native, clean and complete working example for multiple files upload. So I figured it out, here is the example code:

Previously I mostly relied on contrib modules for multiple file uploads in Drupal forms, like Plupload. First of all, at the moment that module isn't available in Drupal 9.

Furthermore, such contrib modules are great: they gave me a kick-start. But to get to 100% of requirements was always kinda hard and with upgrades they can be a showstopper, I'd like to stay as lean and native as possible.

So the more native, the better. I was really glad I found the native form api element '#type' => 'managed_file' and its option to upload multiple files '#multiple' => TRUE, which basically provides this Drupal AJAX form element:

Drupal multiple file uploads

End-user functions

When implemented correctly this form element generates an ajax-based form in which end-user can:

  • upload files without page refresh;
  • have a preview of which files will be saved;
  • even delete them before submitting the form.

The Drupal code

For a fully working version, please check the ol_messages module in the Drupal social intranet distro OpenLucius.

So, extracted from OpenLucius, here is the example Drupal code. Also see code explanation underneath.

Explaining most important Drupal code for multiple files upload in custom form

Load Services via Dependency injection

drupal multiple file upload custom form dependency injection

This is an example on how to inject Services via Dependency Injection in a Drupal Form, OpenLucius uses these Services to facilitate everything. In this gist I added the needed code from those services in helper functions.

Build the multiple files upload Drupal form

drupal multiple file upload custom form build
  1. Set default form values. For the multiple files upload we need $hdd_file_location, which is pretty self explanatory, no? :)
  2. You can also facilitate the edit mode within same form, I stubbed some code for that here.
  3. Facilitate message_id, also needed for edit mode.
  4. Define the name field (title) for the message.
  5. Implement a rich text editor, more details here.
  6. Here is where the multiple-files-upload-magic starts: define a field with '#type' => 'managed_file'
  7. Define the required '#upload_location'
  8. Essential: define '#multiple' => TRUE
  9. Also required to make sure no harmful files can be uploaded, not even in temporary file directory. This is facilitated in a helper function in this gist, as said normally done via a Drupal Service.

Facilitate submitted values in submitForm()

drupal multiple file upload custom form get values
  1. Get name (title) of the message, with an extra XSS security checkMore on Drupal security
  2. Get the body value of the rich text editor, check this blog for detailed info.
  3. Security check for body value.
  4. Here is where the multiple files code starts: put the submitted files data in $files variable.
  5. Save the files via a helper function, which most of the times lives in a Service: since multiple modules probably want to save files. And you want it to be testable and overrideable. Want a working example? Check ol_messages module code in OpenLucius distro.

Save uploaded files permanent and attach them to an entity

drupal multiple file upload custom save file entity
  1. Drupal will provide an array with file id's via the formSubmit(), we loop through those here.
  2. Set all individual files to Permanent with Drupal core function setPermanent(). (!) If you don't do this, the uploaded files will stay in temporary file directory and will be deleted on ~next cron run!
  3. Get the file name via Drupal core function getFilename().
  4. Now the file is 'physically' uploaded to the disk, you need to do something with it, else it just sits there like an orphan. In OpenLucius we implemented a custom entity (ol_file) which we use to facilitate files in all kinds of ways in different groups: as an attachment, as a chat item, as a file repository item, as a comment attachment and more.
  5. This bulky code facilitates a nice message for end-user. I put some effort in here so user will get most accurate feedback as possible after uploading a file.

Lastly, some helper functions

drupal multiple file upload custom helper functions

As said, these normally live in Services. But to keep this example compact I put them in this gist.

  1. To facilitate edit mode: get current message data.
  2. Build file location. In OpenLucius we have some extra subfolders like group id and user id, to keep file directories a clean as possible.
  3. Allowed file extensions, you could load this from Drupal core settings. But this gives more flexibility: you can change allowed extensions per file upload field.

Wrap up

OK, that's it for now. I hope this will kick-start a multiple files upload implementation in your Drupal project in a native, clean way. So it's flexible, scalable and future-proof!

Written by Joris Snoek | Sep 01, 2020
Let's Talk

Please tell me all about your project!
Mail , or send a message:

Got some more time?

Related content
09 May, 2023 Drupal

Save time, frustration, and potential content loss.


07 Jun, 2021 Drupal

Programmatically in multiple Views


02 Jun, 2021 Drupal