11

I've noticed something strange on my site: after attaching a file to a node (via the regular file field), that file never gets deleted from the server. I remove it from the node, save that change, but I can see the file is still on the server.

This makes replacing files very difficult, because when a user tries to attach a replacement, the file name has the "_0" or "_1" suffixed to it (since the original file is still on the server and that makes the name a duplicate). That means that we would need to find all links to the file and edit each one to match the new file name/url. It's a total mess.

I'm looking online and nobody seems to have this issue -- the files ought to be deleted from the server once they're removed from the node.

Any ideas why this may be happening in my case? I'm not sure where to start looking. Certainly the 'File system' configuration page has nothing of that nature as an option that may have been checked. And the field options themselves seem to not have anything of that nature I may have inadvertently set. Any other ideas?

  • If I understand correctly it is not deleted immediately but it is marked for deletion. Once it is marked it is cleaned up on cron run. Same is the case with the tables cleanup. – junedkazi Oct 17 '12 at 17:50
  • Good thinking. I did test that out though, and the files are never deleted, not even after several cron runs. – Boriana Ditcheva Oct 17 '12 at 20:25
17

I got it! It's a revisions thing. I guess it makes sense. If you have revisions enabled for that content type, it keeps all your old files on the server (associated with old revisions), so replacing a file definitely is harder. If you try to remove it and add it again to the node, the name/link is updated, as I mentioned in my question. Since a file with that name is kept on the server and there is a name duplication, it adds those "_0", "_1" etc suffixes to future uploaded versions of that file's name.

I understand why this is happening though, since the whole point of revisioning is being able to revert to any past version of the page.

The work-around is that you can actually delete the old revision from the 'Revision' or 'Moderate' tab (if using Workbench Moderation) that contained the file you're trying to replace. Then upload it again, and the name should then match without you having to go back and edit any links pointing to that file.

Hope that makes sense and that it helps somebody else too!

| improve this answer | |
4

I had the same use case (wanting to replace files while maintaining the filename), and the following code in a custom module met this goal. This code relies on the Entity API module so it should be added as a dependency in your module .info file. Feedback welcome.

This allows for immediately deleting files after clicking 'Remove' then saving the node. Warning: this also means that when you Remove a file and save the node, you can't get that file back by rolling back to an earlier revision.

/**
 * Implements hook_node_update().
 *
 * Delete files from old node revisions.
 */
function MYMODULE_node_update($node) {
  // Array of content types to act on.
  if (in_array($node->type, array('page', 'article'))) {
    $wrapper = entity_metadata_wrapper('node', $node);
    $original_wrapper = entity_metadata_wrapper('node', $node->original);

    // Array of file fields to act on.
    foreach (array('field_public_files', 'field_private_files') as $field) {
      if (!isset($original_wrapper->{$field})) {
        continue;
      }
      $current_files = array();
      $original_files = array();
      // Get files that were attached to the original node (before update).
      foreach ($original_wrapper->{$field}->value() as $file) {
        $original_files[] = $file['fid'];
      }
      // Stop if there were no files previously attached.
      if (empty($original_files)) {
        continue;
      }
      // Get files currently attached to the node (after update).
      foreach ($wrapper->{$field}->value() as $file) {
        $current_files[] = $file['fid'];
      }
      // Delete files that were in the original node but were removed during
      // this update.
      $deleted_files = array_diff($original_files, $current_files);
      foreach ($deleted_files as $fid) {
        if ($file = file_load($fid)) {
          // Delete all usages of the file. Each node revision adds to the usage
          // count.
          file_usage_delete($file, 'file', 'node', $node->nid, 0);
          file_delete($file);
        }
      }
    }
  }
}
| improve this answer | |
  • where we should put the code. – BandOfBrothers Aug 6 '15 at 9:15
  • Not the answer original request was looking for, but I found it hit just the spot. Thanks for sharing here! – texas-bronius Jun 17 '16 at 16:17
2

I made a module that deletes orphaned files as mentioned in this thread:

https://www.drupal.org/project/fancy_file_delete

It can also force delete files manually and un-managed files as well.

| improve this answer | |
0

This might be a permissions problem on the server. Try the same on a clean install - if you are experiencing the same problem, then it's up to the server and not Drupal.

Is there anything in the logs?

| improve this answer | |
  • I just tested it for permission problems. I have a local copy of the site on my personal machine, and the problem exists there too. However, on a clean install, the files do indeed get deleted. On my problematic site, files don't get deleted even after I delete the entire node they're attached to. Any other ideas what may be causing this in my Drupal setup. I'm assuming it must be a module... – Boriana Ditcheva Oct 17 '12 at 20:26
  • At least you narrowed it down to the installation. Which modules are you using? Any custom/fork/dev modules? – Aram Boyajyan Oct 17 '12 at 20:44
0

I did not have luck with deleting old revisions or saving nodes without their attached files and coming back. These are the only things that always work:

  1. Deleting the node
  2. Removing the file through editing the node and manually deleting the file from the server.

I absolutely hate the second option which is why I'm here looking for another solution.

(I could be stepping out of bounds, too since I have a bunch of clients running D6.)

| improve this answer | |
  • I started a ticket about this a long time ago: drupal.org/node/1816584. Chime in if you'd like, and perhaps there can be a more serious discussion about this if there are additional voices. – Boriana Ditcheva Apr 10 '13 at 20:38
0

I ran into this problem as well with workbench moderation, and file field insert actually showing the old versions of uploaded files when files with the same name are re-uploaded in different revisions of a document.

To makes things run smoothly add the node's vid as a folder to to the file upload path. Normally I'm doing something like.

Folder path = assets/[node:nid]-[node:title]/[node:vid]

Yes they are ugly long folders with sub folder madness, but you can find files really easily via node ID or title, and then the sub-folder prevents name collisions so you can keep many versions of the same file with the same name. Then later you can delete the old revisions if you want to clean up space.

| improve this answer | |

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.