I like the way your module creates image nodes based on the upload module. But it is not working other way round. I mean if I create a page content (for example) and upload images, by submitting (creating) the page content node, image nodes are automatically created (which is excellent) but if I go ahead and delete one of the (autocreated) image node, and see the parent node, while viewing it is not showing the deleted image but while editing, it still shows the deleted image under the upload list.

I think it has to be mutually exclusive.

Comments

agn507’s picture

This is pretty much the same problem I noticed. The reasons its doing this is because when the node is saved with the attachments the path for the file is saved by the upload module by default in files/imagename.jpg and doesnt save where the image module is saving the files.

I think this only happens if you set the image module to store the images in a folder other than "files" such as "files/images". Then the original image gets uploaded to files/image.jpg and the image derivatives that get saved by the image module are setup something like

"files/images/image.jpg"
"files/images/image.preview.jpg"
"files/images/image.thumbnail.jpg"

Now if any of these nodes get deleted only them files are removed and the database entry in the files table. There will still be an entry for the "files/image.jpg" Which is why it still shows them as being attached after deleting the image nodes. The upload module still sees an etnry in the files table for that node entry. To make problems even worse the file never actually resides in the files directory. I'm not sure if once the "image module" does its work creating the derivatives it removes the original file submitted by the upload module?

I think just making "upload image module" take into account the path set to save the images from the "image module" would do the trick. This seems to be the problem as far as I can tell.

CoolDreamZ’s picture

I agree. If an Image Node that was created by this module is deleted it should be (possibly at the users option) removed from the list of attachments on the parent node and all associated image files removed.

There is a similar problem with thumbnails showing up for un-published Image Nodes see #238984: Image thumbnails in parent post for unpublished images

CoolDreamZ’s picture

Another suggestion, on the Node deletion confirmation page there could be a warning that "Generated Nodes X,Y,Z... will also be deleted."

Alternatively could a checkbox "Delete Associated Image Nodes?" be provided?

acolonna’s picture

The problem is that there is no such thing like the nodeapi for operations on files.
For this reason we can not intercept the destruction of the attachment, done by the Upload module (to which the form part regarding attachments belongs).

We can instead check for inconsistencies, and correct them, at each update operation within the nodeapi stack.
The following code will work for small sets, it would need optimization in case of large image sets per node (queries return string representations of arrays of id's).

The following function should be called from within the nodeapi, as shown below:

function upload_image_update($node) {
  /*
    Find out inconsistent data in the db
  */
  $existing_images = array('0');
  if(!empty($node->files)) {
    foreach ($node->files as $fid => $file) {
      $existing_images[] = $fid;
    }
  }
  $missing_attachments = db_fetch_object(db_query("SELECT GROUP_CONCAT(nid SEPARATOR \",\") AS nids FROM {upload_images} WHERE oid = %d AND fid NOT IN (%s)", $node->nid, implode(',', $existing_images)));
  $missing_derivatives = db_fetch_object(db_query("SELECT GROUP_CONCAT(fid SEPARATOR \",\") AS fids FROM {image} WHERE nid IN (%s)", $missing_attachments->nids ? $missing_attachments->nids : '0'));
  $missing_files = db_query("SELECT filepath FROM {files} WHERE fid IN (%s)", $missing_derivatives->fids ? $missing_derivatives->fids : '0');
  
  /*
    Clean up the database
  */
  db_query("DELETE FROM {image} WHERE fid IN (%s)", $missing_derivatives->fids ? $missing_derivatives->fids : '0');
  db_query("DELETE FROM {files} WHERE fid IN (%s)", $missing_derivatives->fids ? $missing_derivatives->fids : '0');
  db_query("DELETE FROM {upload_images} WHERE nid IN (%s)", $missing_attachments->nids ? $missing_attachments->nids : '0');
  db_query("DELETE FROM {node} WHERE nid IN (%s)", $missing_attachments->nids ? $missing_attachments->nids : '0');
  db_query("DELETE FROM {node_revisions} WHERE nid IN (%s)", $missing_attachments->nids ? $missing_attachments->nids : '0');
  
  /*
    Clean up the file system
  */
  if(mysql_num_rows($missing_files)) {
    while($file = db_fetch_object($missing_files))
    {
      file_delete($file->filepath);
    }
  }
}

The above function should be called from within the upload_image_nodeapi function, like so:

function upload_image_nodeapi(&%node, $op, $teaser, $page) {
[...]
case 'update':
   if($node->type == 'image') {
   [...]
   } else {
      upload_image_update($node);
   }
   break;
[...]
}
acolonna’s picture

Just a side note:
When a user deletes an attachment from the node edit form, the Upload module intercepts the node form submit and, finding the checkbox value for the deletion of the file, it proceeds with removal from:
- the database (the files table);
- the filesystem (but the file doesn't really exist, because the record in the files table points to the original attachment file, which exists only until the attachment is consolidated);
- the node (to clean data up for the rest of the execution);

The last point is crucial, because this means that (unless you customize the order of modules in the database) the Upload Image module will see the $node object cleaned of removed images, because it's executed after the Upload module.

For this reason we have to "reverse-work" our way, finding out what records on the database, for the node, are missing in the node. This way we know what has been deleted (either at that time or any time before).

killes@www.drop.org’s picture

Version: 5.x-1.x-dev » 6.x-1.x-dev
killes@www.drop.org’s picture

Status: Active » Fixed

The user now gets a notice in the delete form for both the single and the mass deletion.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.