I have a Content Type with a FileField (Image, in particular). When one of these values is deleted, then Drupal deletes the underlying file as well (as long as no other nodes reference the same file).

I don't want the underlying files to be deleted, I want them to remain in the filesystem. Are there any hooks or other techniques I can use to make sure it remains after its FileField value is deleted?

  • What exactly are you trying to acomplish? Why do you need to keep the old file if you're going to allow it to be replaced anyway? It feels like there may be a better solution than hacking core, or unlinking Filefields. – Citricguy Feb 7 '12 at 2:58

This has already been answered: https://stackoverflow.com/questions/2101754/drupal-filefield-remove-file-from-node-but-leave-on-server

  • That's a nice start. I'll have to see if Drupal 7 works in a similar way. – Greg Apr 13 '11 at 5:41
up vote 0 down vote accepted

It's an ugly hack, but this is the simplest way I found to prevent a file from being deleted. It works by hooking file_delete and then removing the uri property from the $file variable. Without the uri, Drupal is unable to delete the file.

// Think twice before using this ugly hack.
// It probably breaks something and kills kittens.
function mymodule_file_delete($file) {
  $path = drupal_realpath($file->uri);
  if (!is_dir($path) && is_file($path)) {
    if (preg_match('/insert_regex_here/', $path)) {
      $file->uri = NULL;
    }
  }
}

The other alternatives I considered were:

  • Hacking core
    Although hacking core is taboo, it would be a cleaner solution than the hook I use above.
  • Using file_usage_add() on each file I want to retain
    Doesn't fit my use case very well - tens of thousands of files created and deleted independently of Drupal. Synchronizing all those files with file_usage_add would be daunting.
  • Use Media module to reference the file paths
    Media seems like overkill and it isn't stable yet. Plus I'm not sure if it would do what I need.
  • I ended up hacking core (edited drupal_unlink()) because it was the simplest solution and didn't have the potential side-effects that could come from abusing hook_file_delete. I'm still open to better suggestions. – Greg Apr 15 '11 at 4:34
  • For those who really think that they want to hack core: Open includes/file.inc and look for the function drupal_unlink. Add return FALSE; as the first line and NO files will be deleted. Better yet, add a conditional statement that checks the $uri to ensure that it is a file that you don't want to delete. – Greg Feb 7 '12 at 3:48

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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