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?

2
  • You can lower the time value in the admin configuration. I believe 1 hour is the lowest value.
    – Kevin
    Jul 10, 2017 at 18:55
  • The lowest value is currently 6 hours. Dec 31, 2017 at 1:21

1 Answer 1

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.

4
  • 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, 2017 at 21:32
  • It's better to check the files aren't really used.
    – apaderno
    Jul 11, 2017 at 6:24
  • OK then. Where do you think is the best place to put your code in my module?
    – gbmapo
    Jul 11, 2017 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.
    – apaderno
    Jul 11, 2017 at 6:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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