Currently it's quite hard to write a module that deletes nodes of a user when the user gets deleted. This is, because node_delete() depends on node_load(), which depends on an existing entry in the user table - but the user module deletes this entry *before* it invokes the user hook.

Attached is a simple patch, which does nothing more, but invoking the hook *before* deleting the entries in the user tables.

I ran over this while working on content profile. I have already working code without this patch - ported from d5, but it's a complicated, ugly workaround, that basically re-implements node_load() and node_delete().

This patch would allow me to replace this (long) hack by some simple code. Actually it would save about 90 loc! (related content profile patch

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

Status: Needs review » Active
fago’s picture

Status: Active » Needs review
catch’s picture

Category: task » bug
Status: Active » Needs review

This is a bug.

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

quite reasonable.

Gábor Hojtsy’s picture

Version: 6.x-dev » 7.x-dev

I checked Drupal all the way back to 4.7's user_confirm_delete_submit() including 5.x's user_delete() and this hook call was at the end all the time. I am not going to change a long time established API in the last minute, sorry. I can see good use for this in 7.x though.

fago’s picture

That's bad. So we have to keep the ugly workarounds... :((

I know that this is the behaviour for quite a long time - but that doesn't make it better :(
I also know it's late for 6.x - sry.

fago’s picture

so, what is about 7.x?

cburschka’s picture

Title: simplify node deletion on user deletion » Invoke hook_user before deleting user from database

Re-roll.

Note that this patch will collide with the PDO monster. I suggest revisiting it after that is committed, because this one is far easier to reroll.

cburschka’s picture

d.o. is still randomly swallowing attachments.

KarenS’s picture

Status: Reviewed & tested by the community » Needs work

Why not add a new 'pre delete' hook instead? Then you don't break long-standing code and this becomes something that could be back-ported. Plus there are times when you might *want* a hook that is triggered after the user has been deleted, since that is the way it has always worked.

pushyamitra’s picture

Yes, I agree. It would be nice to have a 'pre delete' hook.

Also, it would be great if acts like 'validate' operation, and user doesn't have to be deleted if this hook registers an error.
This way a module could do some validation, and _not_ delete user if some validation fails.

fago’s picture

@pushyamitra: hm, this won't cover my use case as then I don't know if the user is really deleted. So only a real 'pre delete' would help here.

moshe weitzman’s picture

Status: Needs work » Reviewed & tested by the community

I think the most recent patch is useful and consistent with core. Validation is a different matter and doesn't cover fago's original use case.

leanazulyoro’s picture

I'm just learning the more advanced aspects of drupal, i'm creating a module and i came up with this, i have to delete nodes that a user submmited when the user is deleted. fago, when you created this issue you said that "currently it's quite hard to write a module that deletes nodes of a user when the user gets deleted" but you didn't say it's imposible... is really a way to do this? i mean without patches any patches. the module nodeprofile does it and i tried with no success to copy the exact same method that is used there. again: is there a way to do this?

by the way, my drupal version is 5.9

Dries’s picture

Status: Reviewed & tested by the community » Fixed

I didn't break any tests so I've committed this to CVS HEAD. Thanks all.

If this patch breaks existing modules, I'd like to better understand their use case.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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

mistergroove’s picture

In my humble opinion wouldn't it be better if there was a pre and post hook for all major user operations (delete, load, save)? There are many situations you might want to run your delete or save etc code before and after the operation. This would save a lot of people juggling with module weights also. I'm a relative noob to the drupal so if theres reasons for not having these please excuse my ignorance.

NancyDru’s picture

Version: 7.x-dev » 6.x-dev
Priority: Normal » Critical
Status: Closed (fixed) » Needs review

I'm sorry, but I have to re-open this and mark it critical against 6.x. My site and module is completely broken because of failed deletes. This needs to go back to D6 at least.

Dublin Drupaller’s picture

+1 for implementing this. I too have a module that needs a pre-delete user hook.

if it's possible, can the developer (or any other developers who have become stuck by this) who marked this as ignored indicate a workaround?

cheers

dub

sphism’s picture

Yeah i've just come up against this problem:

//hook_user()
.
..
//todo- this doesn't work because the user gets deleted, all their nodes are set to uid = 0, then we search for all their nodes
    case 'delete':
      //delete all user nodes
      $query = db_query("SELECT nid FROM {node} WHERE uid = %d", $account->uid);
      while ($row = db_fetch_object($query)){
        drupal_set_message('toonix_users_user > delete > all users nodes '.$row->nid);
        node_delete($row->nid);
      }
      break;
..
.

I can't patch core (it's a big project). So i'm not entirely sure what to do here... any suggestions?

KarenS’s picture

Status: Needs review » Patch (to be ported)

Gabor doesn't want to alter existing behavior in D6, which I understand since that could unexpected break other things. My suggestion in #10 still stands, we could add a second hook that will be invoked before the user is deleted and any modules that need that can use it.

I'll take another stab at getting Gabor to look at this idea even though it is an API change because it is a critical issue and there really is no way to do it other than hacking core.

NancyDru’s picture

@Karen: That would work for me. And I do understand Gabor's point of view, and agree with him. For me at least, this is no longer critical because I lost that account, partially because of this issue. However, we could use this in the Web Links module, which does have an option to take over a deleted user's content.

catch’s picture

Priority: Critical » Major

Downgrading to 'major'.

hargobind’s picture

Since neither the patch above or the "pre delete" operation was ever implemented in 6.x, I'm writing this note to link people to a possible workaround to handle "pre delete" actions for anyone else who finds this thread.

I've made a comment about this behavior in the API page for hook_user(). That comment also includes a workaround using hook_form_alter().

Status: Patch (to be ported) » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.