Drupal
22/08/2019

Webform Drupal 8 - Eviter la suppression des fichiers non utilisés dans un formulaire de configuration

Astuce de code
Voici une petite astuce si vous rencontrez ce problème : les fichiers téléversés à partir d'un formulaire, dans la table file_managed de Drupal sont supprimés s'ils ne sont pas utilisés.

Comment sont administrés les fichiers téléversés dans Drupal, à partir d'un formulaire ? Cette question s'est posée à nous récemment... Et nous ne doutons pas que d'autres développeur·euse·s ou concepteur·rice·s de sites Drupal n'aient pas déjà été confronté·e·s à cette question.

Après une rapide observation, comme pour Drupal 7 au passage, nous confirmons que les fichiers sont stockés dans la table managed_file de Drupal.

La philosophie générale de Drupal semble être que tout téléchargement de fichier utilisateur s'effectue dans un but spécifique, ce que Drupal connaît. Lorsque cet objectif cesse d'exister, le fichier peut être supprimé. La conception de la table file_managed et de son API est basée sur cette idée de conception. 

Il existe une philosophie différente, c'est-à-dire que les fichiers sont téléchargés sans que Drupal soit au courant. Cela peut être via ssh, dropbox ou d'autres moyens. Les fichiers téléchargés de cette manière ne sont pas "la propriété" de Drupal, mais ils peuvent toujours être "connus" de Drupal ou de certains modules contrib. 

Avec un formulaire de configuration ?

Les fichiers téléversés sont ajoutés à la table file_managed. Si ces fichiers ne sont pas utilisés dans une entité (node, utilisateur, paragraph, taxonomie, etc...), drupal n'enregistre pas une valeur dans la table file_usage.

Résultat : Après un certain temps, et après le passage du Cron... Ces fichiers, qui ont un statut temporaire (colonne : status - dans la table file_managed - valeur : 0 pour temporaire - 1 pour permananent) sont supprimés.

La solution pour contourner ce problème est de rendre le statut de ce fichier "permanent".

La fonction buildForm de la classe du formulaire

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://',
);

La solution

Pour rendre ce fichier "permanent" dans la fonction - il faudrait le faire dans la fonction submitForm de la classe du formulaire :

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();

Solution de contournement posté par Rida sur notre intranet !
Avec la participation de toute l'équipe pour son partage :)