1

I have a custom Content Entity in wich definition there is a 'file' field. The file widget works fine.
The 'Browse' button allows to select a file and uploads it to the proper server directory and the 'file_managed' and 'file_usage' tables are updated accordingly.
If I delete the entity, 'file_usage' record is deleted and in 'file_managed' table, the record has its status field set to '0'.
What I understood is that cron job removes all files in the directory with status = '0' after 6 hours.
My question is: how to have the file removed just after the submission of the delete form?

  • You can lower the time value in the admin configuration. I believe 1 hour is the lowest value. – Kevin Jul 10 '17 at 18:55
  • The lowest value is currently 6 hours. – Kari Kääriäinen Dec 31 '17 at 1:21
3

file_cron() contains the code that delete managed files. To adapt it to delete those files with their status set to 0, this is what I would use.

$file_storage = \Drupal::entityTypeManager()->getStorage('file');
$fids = Drupal::entityQuery('file')->condition('status', 0)->execute();
$files = $file_storage->loadMultiple($fids);

foreach ($files as $file) {
  $references = \Drupal::service('file.usage')->listUsage($file);
  if (empty($references) && file_exists($file->getFileUri())) {
    $file->delete();
  }
}

This code returns you all the files matching those conditions. You can also use the following code to get them in batches of 100 per time.

$file_storage = \Drupal::entityTypeManager()->getStorage('file');
$fids = Drupal::entityQuery('file')->condition('status', 0)->range(0, 100)->execute();
$files = $file_storage->loadMultiple($fids);

foreach ($files as $file) {
  $references = \Drupal::service('file.usage')->listUsage($file);
  if (empty($references) && file_exists($file->getFileUri())) {
    $file->delete();
  }
}

I didn't check, but it is probable you can also filter the returned file entities by the bundle using them.

  • I understand. But as I know that the file I want to remove can't be used elsewhere, wouldn't it be simpler to use directly $file->delete()? – gbmapo Jul 10 '17 at 21:32
  • It's better to check the files aren't really used. – kiamlaluno Jul 11 '17 at 6:24
  • OK then. Where do you think is the best place to put your code in my module? – gbmapo Jul 11 '17 at 6:35
  • I would say in the submission handler of the delete form, or in a submission handler of the delete form, if that form is not created from your module. – kiamlaluno Jul 11 '17 at 6:54

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.