All anonymous signups cancelled when any user is deleted

CleaningExpo - February 6, 2009 - 21:50
Project:Signup
Version:6.x-1.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:needs work
Description

We are allowing sign-ups for an event. We had about 40 signups and I just created a user and deleted the user and it cancelled all the signups? I have no idea what happened. Can someone please help me out. Is there anyway I can get the users signed up back. It's extremely important. The site is www.NationalCleaningExpo.com the event was Prattville Alabama.

Why would this happen if I just deleted a user? This user was not associated with any of these signups and was created after the signups.

Someone please help me.

#1

dww - February 7, 2009 - 00:00
Component:Database» Code
Category:support request» bug report

Is there anyway I can get the users signed up back.

From your database backup if you have one. Otherwise no.

If what you say is true, it's a (nasty) bug. However, I thought we already fixed this bug... ;)
#321653: guest "cancel signup" deletes him from all signups.
#233512: Deleted User needs to be removed from the log

Can anyone else easily reproduce this?

#2

dww - March 3, 2009 - 00:17
Category:bug report» support request
Priority:critical» normal
Status:active» postponed (maintainer needs more info)

I just tried to reproduce this and couldn't.

- Cean D6 test site
- I added a "test1" user
- had that user and 3 others signup for an event
- viewed the signup list and saw 4 users signed up
- deleted the "test1" user
- viewed the signup list and saw 3 users signed up

Can you reproduce this on your test site?
Can you reproduce this on a clean D6 test site with nothing but core and signup.module?
Can you provide detailed information about how to reproduce it, including versions of all installed modules and any signup-related configuration?

Given that I can't reproduce it myself, I don't currently think there's a bug in the code, moving this back to a support request.

#3

CleaningExpo - April 3, 2009 - 20:04

It just happened to me again. I'm not going to lie about this. When I get time I will produce a video.

#4

dww - April 3, 2009 - 20:38

I'm not accusing you of lying, nor am I asking for a video. ;) I simply stated the facts from my end: you've reported a problem, I showed you the detailed steps of how I tried to reproduce it (and couldn't). I asked some very specific questions you could answer to make it possible for me to understand the problem you're having and find the bug (if any) that's causing it. Please just answer my questions if you're interested in resolving this. Thanks.

#5

dww - May 19, 2009 - 15:49
Category:support request» bug report
Priority:normal» critical
Status:postponed (maintainer needs more info)» active

Based on #467042: Anonymous signups cancelled when deleting a user (now marked duplicate of this), perhaps the bug only shows up for anonymous signups. Re-reading this thread, CleaningExpo never specified auth vs. anon signups, and I clearly only tried with auth signups in my testing for comment #2...

Given another independent report, and the likelihood that this is a real bug, and given that it's a data loss bug, I'm bumping this back to active + critical...

@CleaningExpo, if you're still reading this, can you confirm that it was anonymous signups that were canceled when you delete a user?

#6

katiusha - May 20, 2009 - 12:59

I've experienced this bug when I have both anonymous and non-anonymous signups to the next event in the event queue. I tried to delete various users, both signed up and not signed up for this particular event, and the result is the same, the anonymous signups are all cancelled, the ones made by registered users are ok.
Might it be related to the message I get when I try to delete a user that all the posts of the deleted user will be assigned to anonymous?... Maybe the uid is set to that of the anonymous user when this happens, and when the signup_user hook is called it deletes signups with the anonymous uid?...

#7

BenK - June 2, 2009 - 04:09

I've just experienced the exact same problem. I went to delete a user who had never signed up for anything and upon confirmation of that user's deletion, I got a long page full of messages saying numerous signups had been deleted.

This deleted all anonymous signups across my entire site (which was over 500 signups). Luckily, I had exported that list somewhat recently so I only lost a few dozen names.

Obviously, this type of loss of data is pretty scary. At this point, I'm afraid to delete any user.

Thanks,
Ben

#8

BenK - June 2, 2009 - 04:14

One more thing: I wanted to point out that all of my authenticated signups seemed to be fine. This issue appears to only effect anonymous signups.

--Ben

#9

dww - June 2, 2009 - 05:53
Title:Signups Cancelled when I deleted User» All anonymous signups cancelled when any user is deleted

Yup, this is critical. Giving a more accurate title... Hopefully shouldn't be too hard to fix. Definitely before rc4 goes out (#363238: Release signup 6.x-1.0-rc4). Anyone feel like trying to debug? (My hands are very full right now). Also, can anyone test this on D5? Thanks!

#10

ezra-g - June 3, 2009 - 00:08
Status:active» needs review

I put some debug messages in and found that on the user tab, the uid was not correctly being passed to the SELECT * FROM {signup_log} query (newsflash!). This patch corrects the offending line.

AttachmentSize
signup_delete_anonymous_signups.patch 1.2 KB

#11

ezra-g - June 3, 2009 - 00:12

this patch is without the debug messages ;).

AttachmentSize
signup_delete_anonymous_signups.patch 687 bytes

#12

dww - June 3, 2009 - 01:07
Status:needs review» fixed

Looks like an undocumented API change between D5 and D6 core. :/ Alas. Reviewed, tested, and committed to HEAD and DRUPAL-6--1. Thanks!

#13

moshe weitzman - June 4, 2009 - 11:14

I am curious what the API change was.

#14

dww - June 4, 2009 - 16:17

@moshe: See patch #11. The contents of the $edit argument passed into hook_user() are totally different between D5 and D6.

#15

dhochman - June 13, 2009 - 00:07

I don't see a new dev version of the signup module that might include this patch given the date of this issue. I'm not equipped to do a patch, so I need to wait for the next version of signup. Do you know when we can expect it? Thanks!

#16

System Message - June 27, 2009 - 00:10
Status:fixed» closed

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

#17

wesley_2mpact - October 23, 2009 - 14:10
Version:6.x-1.0-rc3» 6.x-1.x-dev
Priority:critical» normal
Status:closed» needs work

I would like to reopen this, becaus I believe this is not 100% fixed yet. I have a scenario where this bug still persists.
With Drupal core this fix works just fine, but with (some) add-on modules it doesn't work. I've lowered the priority to normal since it now only affects some very specific add-on modules.

First, the fix in the patch:

<?php
function signup_user($type, &$edit, &$user, $category = NULL) {
  switch (
$type) {
    case
'delete':
     
$uids = array();
      if (
is_array($edit['accounts'])) {
       
// A multi-user delete from Admin > User management > Users.
       
$uids = $edit['accounts'];
      }
      else {
       
// A single-user delete from the edit tab on the user's profile.
       
$uids[] = $edit['_account']->uid;
      }
      foreach (
$uids as $uid) {
       
$query = db_query("SELECT * FROM {signup_log} WHERE uid = %d", $uid);
        while (
$signup = db_fetch_object($query)) {
         
signup_cancel_signup($signup);
        }
      }
      break;
  }
?>

Now the bit that was a fix for this problem, but I think isn't.
<?php
     
else {
       
// A single-user delete from the edit tab on the user's profile.
       
$uids[] = $edit['_account']->uid;
      }
?>

The problem is that this fix relies on the $edit array to be correctly set. If add-on modules use the user_delete hook function the edit-array will NOT be properly set. I've checked this with some add-on modules (not many use this hook function) and they all implement it like this:
<?php
  user_delete
(array(), $uid);
?>

Take a look at the API documentation: http://api.drupal.org/api/function/user_delete/6
The signup_user function is (in this case) called with a blank $edit-array.
I think that the $user object would be a more reliable source for getting the uid, as it is loaded in the user_delete function:
<?php
     
else {
       
// A single-user delete from the edit tab on the user's profile.
       
$uids[] = $user->uid;
      }
?>

I've not made a patch because I'm not sure that using $user is more reliable then using $edit.
I currently have Signup running with this small change on all of our sites. If any problems arrise I will report here.

Any more ideas on this? Any other functions/hooks that are connected?

#18

wesley_2mpact - November 2, 2009 - 16:19

This is the patch containing the changes I made. I've added an extra check on the $uids array to make sure it is an array and that contains some data.

AttachmentSize
signup_delete_anonymous_signups.patch 945 bytes

#19

flaviovs - November 4, 2009 - 19:25

I'm in the process of using this module on a project I'm currently working on, and just stumbled upon this issue.

I didn't dig into the code yet, but a simple question popped up on my head when looking at the code above: since it doesn't make sense to delete the anonymous "user", what about skipping signup cancellation if we find the anonymous user uid? E.g.:

<?php
     
foreach ($uids as $uid) {
        if (
$uid == 0 ) continue; // Skip anonymous user
       
$query = db_query("SELECT * FROM {signup_log} WHERE uid = %d", $uid);
        while (
$signup = db_fetch_object($query)) {
         
signup_cancel_signup($signup);
        }
?>

Shouldn't this be enough to solve this problem?

#20

wesley_2mpact - November 20, 2009 - 08:17

No it won't...

Preventing the deletion of the anonymous user is a very good idea, but won't solve the problem I still see.

The problem is that the $uid used in the module might not have been set at all because it is taken from the $edit array. Other modules invoking the user_delete function don't set this $edit array. So the $uid will always be blank (or 0) in that case. Even if a valid user is being deleted! The $uid you can get from the $user object, which is also passed in to the signup_user function, is always correctly set.
The patch I made changes the logic to use the $user object instead of the $edit array.

I have got this patch running on all of our sites and since then the signups are working correctly. I have got 2 modules enabled that use the user_delete hook and all anonymous signups were deleted when this hook was called with a valid non-anonymous user... Offcourse, if you don't use any extra modules that invoke the user_delete function everything will work correctly to. (and very few modules use this hook)

Do you understand the problem now? Or am I not explaining it good enough?

#21

dww - November 20, 2009 - 16:57

#18 looks pretty good to me. Yeah, using $user is probably better.

However, we should swap the order of the is_array() and !empty() checks, to ensure we don't try to test is_array() on a variable that doesn't exist.

Thanks for the fix!

 
 

Drupal is a registered trademark of Dries Buytaert.