Drupal

Webform Drupal 8 - Prevent unused files from being deleted in a configuration form

Published on 22 August 2019
Code tip
Here’s a little tip if you encounter this issue: files uploaded from a form, in Drupal’s file_managed table, are deleted if they are not used.

How are uploaded files managed in Drupal from a form? This question recently came up for us... And we have no doubt that other Drupal developers and site designers have already faced this question.

After a quick review, as with Drupal 7 by the way, we confirm that files are stored in Drupal’s managed_file table.

The general philosophy in Drupal seems to be that every user file upload happens for a specific purpose, which Drupal knows. When this purpose no longer exists, the file can be deleted. The design of the file_managed table and its API is based on this design idea.

There is another philosophy, which is that files are uploaded without Drupal being aware. This could be via SSH, Dropbox, or other means. Files uploaded in this way are not “owned” by Drupal, but they can still be “known” by Drupal or certain contrib modules.

With a configuration form?

Uploaded files are added to the file_managed table. If these files are not used in an entity (node, user, paragraph, taxonomy, etc...), Drupal does not record a value in the file_usage table.

Result: After a certain amount of time, and after Cron runs... These files, which have a temporary status (column: status - in the file_managed table - value: 0 for temporary - 1 for permanent) are deleted.

The solution to get around this issue is to make the status of this file “permanent”.

The buildForm function in the form class

public function buildForm(array $form, FormStateInterface $form_state) {


$form['file_upload'] = array(
  '#type' => 'managed_file',
  '#title' => $this->t('Message icon'),
  '#default_value' => $config->get('file_upload'),
  '#upload_location' => 'public://',
);

The solution

To make this file “permanent” in the function, you need to do so in the submitForm function of the form class:

public function submitForm(array &$form, FormStateInterface $form_state) {


// set the file status to permanent
$temporary_file = $form_state->getValue('file_upload');
$file = \Drupal\file\Entity\File::load( $temporary_file[0] );
$file->setPermanent();
$file->save();

Workaround posted by Rida on our intranet!
With thanks to the whole team for sharing :)

Read more articles on Drupal