Steps to reproduce:
- Do a fresh install of Drupal.
- Log out
- Register a new user (with setting requiring administrator approval of new account - which is default).
- See the Mail notifiying the new user that his account is awaiting approval.
- See the mail notifying the site admin of a new user having registered.
- Log in as admin and activate the new user.
- No mail is being sent to the user.
The new user therefore has no way of logging into the site.
I tested this on a local install and on an installation on a dedicated server with different settings for the sites e-mail-address using different smtp-servers. The behavior remained the same.
Marking this as critical for now until others had a chance of testing this on their setups.
Comment | File | Size | Author |
---|---|---|---|
#61 | 892950-user-activation-mail-5.patch | 3.66 KB | reglogge |
#58 | 892950-user-activation-mail-4.patch | 4.08 KB | reglogge |
#57 | 892950-user-activation-mail-3.patch | 3.1 KB | reglogge |
#56 | 892950-user-activation-mail-2.patch | 3.24 KB | reglogge |
#48 | account-with-test-37.patch | 3.02 KB | dixon_ |
Comments
Comment #1
reglogge CreditAttribution: reglogge commentedThis seems to have to do with the user's preferred language not being set after account creation.
drupal_mail in function _user_mail_notify in user.module doesn't get passed the $language parameter so no mail gets sent.
When I change the function in the way the patch shows, the mail gets sent.
This is surely the wrong way to go about this, so please don't use this patch. But it's a lead at least for more gifted developers...
Comment #2
scor CreditAttribution: scor commentedHow about this one? Does it work?
Comment #3
scor CreditAttribution: scor commenteduploading the right patch.
Comment #4
reglogge CreditAttribution: reglogge commentedNo, the patch in #3 doesn't work, at least on my local installation.
The mail notifying the user that his account is awaiting approval gets sent, but the later mail with the account details never arrives (I don't know if it's being sent at all).
Comment #5
reglogge CreditAttribution: reglogge commentedforgot to change status...
Comment #6
McGo CreditAttribution: McGo commentedI can not confirm the bug as it is described. The current D7 CVS Head is working. almost. This is what i did:
- Installed D7 Core from CVS
- Created an account and received the welcome message (your account is waiting for approval) to the new user and the mail for the webmasters account to approve the new user.
- logged in as webmaster (uid 1) and headed to admin/people
- Select the new user and choose "Unblock the selected User".
I then receive the confirmation mail as the new user with a link pointing to /user. BUT: The user has no chance to set a password, because the link in the mail is malformed. I figured out, the the default mail text in user.module uses the wrong variable. Please review the patch attached (ok, it is very simple).
Comment #8
reglogge CreditAttribution: reglogge commentedThe patch in #6 was not created from drupal root, so it cannot apply. New patch attached.
Can somebody else test the original issue?
EDIT: Moved this patch to a new issue since it is a different problem: #893276: Need tests for activation link in new user e-mail
Comment #9
reglogge CreditAttribution: reglogge commentedSorry if this gets confusing. These are now two separate issues:
I created a spinoff issue for the wrong link in the users e-mail that was reported in #6. See here #893276: Need tests for activation link in new user e-mail.
Please disregard the patches from #6 and #8 !
So the status of this issue is therefore back at #6 where McGo stated that he could not reproduce the original issue with the mail not being sent.
I still can not send the after-activation mails from both a local install and from a dedicated server. The initial notification mails upon registering are being sent.
The Drupal install was the standard installation.
Comment #10
AaronBaumanI cannot reproduce the issue reported in the OP.
To investigate this issue I added a watchdog() call inside _user_mail_notify(), and the call to drupal_mail() around line 3338 in user.module,v 1.1195 is indeed called.
Further, I added watchdog() calls at the end of _user_mail_text(), and verified that it returns the correct values.
Can you provide more detail about exactly what you did to create this issue?
Do you have non-default language settings?
In order to test, I used the "bulk operations" on admin/people to unblock, block, and re-block, as well as editing the user directly at user/%uid/edit.
Can you provide evidence that this is an issue at the Drupal layer and not the server or mail delivery layer?
ie. check that the smtp log shows the welcome email but not the approval email; check your mail client's spam folder; etc.
Comment #11
AaronBaumanalso: there is no patch to review yet. All the patches in this issue address #893276.
Switching back to active.
Comment #12
reglogge CreditAttribution: reglogge commentedThanks aaronbauman for looking into this. I am conducting further tests on yet another server and no, I cannot rule out this having to to with the server or the mail delivery layer. However, the first mail to the user (notifying him of the fact that his account will have to be activated by an admin) did go out, which led me to suspect drupal as the culprit.
Comment #13
reglogge CreditAttribution: reglogge commentedI did further test with trying to send other system mails.
The exact steps were:
- Checked out Drupal head from cvs
- Created fresh database
- Created a fresh installation with profile "Standard"
- Set admin credentials
- No further changes to the site configuration (especially no language settings - the site runs in english)
- Logged out
- Registered as a new user - MAIL GOT SENT (mail notifying me that an administrator would have to approve the account).
- I logged in as admin and activated the account - NO MAIL GOT SENT to the user.
- Logged out again
- I then requested a new password with the username of the new user - MAIL GOT SENT (notifying the new user of a request to reset the password).
This worked consistently for multiple users.
Additionally I then canceled selected user accounts with all settings that enable user notification of an account cancellation. These mails also did NOT GET SENT.
So at least on my install I get some mails consistently being sent and others consistently not being sent.
Logs: I also checked the mail server logs and found log entries for the mails that were sent but nothing (also no errors) for the mails that did not get sent.
IMHO that points in the direction of something being wrong with Drupal rather than with the server or the mail-agent. What exactly this is, I don't know.
Comment #14
reglogge CreditAttribution: reglogge commentedI tested this on two different platforms:
1.) Locally on a mac with a Macports LAMP-Stack (Apache/2.2.15 (Unix) mod_ssl/2.2.15 OpenSSL/1.0.0a DAV/2 PHP/5.2.13)
2.) Remotely on a Debian Lenny Server (Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny9 with Suhosin-Patch)
Comment #15
reglogge CreditAttribution: reglogge commentedI think I've found something:
The sending of notification mail on status changes to the user is triggered by this code (line 509ff in user-module):
$edit['status'] however is never set, only in three simpletests (dblog.test (line 190), drupal_web_test_case.php (line 970) and trigger.test (line 582)). In a fresh Drupal install $edit['status'] is therefore not set and the sending of mails is not triggered.The sending of confirmation mails can only be triggered for users created by simpletests because the tests themselves set $edit['status'].In phpMyadmin the content of the data-column in user.table is given as '[BLOB - 0Bytes]' on my install - a further indication of nothing being in there. Also it says there: ' A serialized array of name value pairs that are related to the user. Any form values posted during user edit are stored and are loaded into the $user object during user_load(). Use of this field is discouraged and it will likely disappear in a future...'Again. I don't really know if this makes sense or if I'm totally wrong here.EDIT: This was total crap. The right explanation (I hope) is in #18.
Comment #16
reglogge CreditAttribution: reglogge commentedWell, I'll be damned...
Further tests reveal: The problem happens only after navigating to the user's edit page and activating the user from /user/[uid]/edit?destination=admin/people. When I activate the user there, NO MAIL gets sent.
Unblocking a single user from /admin/people results in the MAIL BEING SENT.
Comment #17
reglogge CreditAttribution: reglogge commentedChanged title of issue to reflect current status.
- All mails are being sent when the status change is made with the bulk operations on /admin/people
- No mails are being sent when the status change is made from /user/[uid]/edit
This affects all mails notifying users of status changes between blocked/activated
Comment #18
reglogge CreditAttribution: reglogge commentedProblem probably pinpointed:
In user_profile_form_submit in user.pages.inc there is the following code:
$edit is being filled with the values from $form_state with array_intersect_key().
The value for status in both $edit and $account is now identical.
Then how can this if-statement from user_save() in user.module ever be TRUE?
For testing purposes I deleted
&& $edit['status'] != $account->status
from the if-statement in user_save() and then the mail gets sent.Not sure how to fix this though.
Comment #19
reglogge CreditAttribution: reglogge commentedRegarding #10: I added a watchdog() call to write out the contents of $edit and $account to user_profile-form-submit right after
$edit = array_intersect_key((array) $account, $form_state['values']);
and found that the status-values in both arrays are indeed identical before user_save gets called. It is therefore logical that the if-statement in user_save (see #18) will never trigger the sending of the activation mail.The callback-function from /admin/people uses a different way to save users:
Here there is no change being made to $edit and therefore the activation-mail gets sent.
Comment #20
reglogge CreditAttribution: reglogge commentedThe patch shows the behavior explained in #18 and #19. It adds a first watchdog() call right before user_save gets called from user_profile_form_submit and shows the values of $edit['status'] and $account->status as they are being passed on to user_save.
The second watchdog() call is from user_save itself after the if-statement triggering the sending of mails returns FALSE, which it shouldn't.
The values are always identical so the mail never gets sent.
The patch is for illustration purposes only, of course.
I've tried playing around with removing $edit from the call to user_save, but with no luck. Anyways this seems to have several ramifications which I don't really get :-(
Comment #21
reglogge CreditAttribution: reglogge commentedand the right patch... Ignore the one above.
Comment #22
sunProper title. It doesn't look like these patches attempt to fix the bug?
Comment #23
reglogge CreditAttribution: reglogge commentedNope, they don't fix it but prove that the bug exists after several commenters couldn't reproduce it.
Comment #24
sunThe proper way to prove that an expectation is not met is to write a test for it (or fix existing ones). I'd recommend to start doing just that.
Comment #25
reglogge CreditAttribution: reglogge commentedDo you mean something like this?
The test creates two new users, blocks them and then activates the one from /admin/people and the other one from his /user/edit page.
In both cases we test for whether blocking/unblocking works and whether mails are being sent to the users.
The test fails on user unblocking from /user/[uid]/edit.
It's the first test I wrote, so bear with me...
Comment #26
reglogge CreditAttribution: reglogge commentedDang, left some cruft in the test.
Better patch here...
The test should fail BTW.
Comment #28
brian_c CreditAttribution: brian_c commentedI've been able to reproduce this problem locally, and may have a fix.
Here is the code in question again for reference, same as #18:
For user_save() to send an email when a user is activated, $account->status must equal 0, and $edit->status must equal 1 at the time of the call to user_save(), so that user_save() can determine that the status has just been changed (Again, this is pointed out in #18)
The problem is that entity_form_submit_build_entity() in the above code overwrites the values of $account with values from $form_state (ie, destroying the previous state of $account), before user_save() is called. This makes it impossible to detect what has changed.
ADDITIONALLY, I believe the parameter order for array_intersect_key() is backwards; array_intersect_key() populates the return array using values from the FIRST parameter (which is $account here), but we want $edit to be populated using values from the newly submitted form data in $form_state. The only reason the current code works (insofar as saving the data properly) is because entity_form_submit_build_entity() copies all the $form_state data into $account prior to the array_intersect_key() call.
So, my solution is twofold:
1) Reverse the parameter order of array_intersect_key(), to populate $edit from $form_state values instead of $account values
2) Don't call entity_form_submit_build_entity() until after user_save()
The code above, with these two changes:
With these changes, activating a user account now sends the email properly on my local install.
I'm afraid I don't really know my way around creating patches or tests, but I am attending the Copenhagen code sprint tomorrow (webchick invited me in person, so I can hardly say no ;) to hopefully learn just that, so I will make it my mission to get a patch for this change created and tested. (Unless someone else beats me to it)
Comment #29
brian_c CreditAttribution: brian_c commentedComment #30
reglogge CreditAttribution: reglogge commentedAnd here's the patch with the test and the proposed solution from #28.
Comment #32
brian_c CreditAttribution: brian_c commentedWell nuts. I was worried that moving entity_form_submit_build_entity() might have unintended consequences.
Or, is it possible that the test itself causes problems? I have no idea.
1) Is it possible we try the change by itself, without the new test? Or is that strictly forbidden?
2) I will also try a different approach, preserving the value of $account in a separate value, and passing that to user_save()
Comment #33
brian_c CreditAttribution: brian_c commentedOK, I'm attempting to re-submit the patch with the test removed, to see how that affects the results.
Comment #34
reglogge CreditAttribution: reglogge commentedNo, it's not the new test that fails, it's a load of other ones.
Comment #35
brian_c CreditAttribution: brian_c commentedOK, I have a new approach here, preserving the original status value and then restoring it, leaving everything else unchanged. This tests OK locally (email sends properly).
Here is the code:
Can you try to make a new patch with this?
I am attempting to get setup here with CVS properly so I can make my own patches, but that might take a while.
Comment #37
reglogge CreditAttribution: reglogge commentedOk, first of all I refactored the test to now run from within the existing test "User administration".
This test fails upon activating a blocked user from /user/[uid]/edit because no mail gets sent to the user.
The patch only contains the refactored test.
I will test the change from #35 next.
Comment #38
reglogge CreditAttribution: reglogge commentedpinging bot.
Comment #40
nodestroy CreditAttribution: nodestroy commentedcreated patch from #35. worked for me on local installation
Comment #41
brian_c CreditAttribution: brian_c commentedHa, I JUST finished downloading the whole 2.5GB Xcode, installed to get CVS, and finally rolled my very own first patch... and you beat me to it. ;)
To give an update, there's about 3-4 of us here at the CPH code sprint looking into this bug. We have another approach to try after this one too, which may be a "better" solution that simply saving and restoring the status flag.
Comment #42
Volx CreditAttribution: Volx commentedHi,
I have a slightly different approach. The problem in the code was that $account is just a reference to $form_state['user']. So changes to $account change it everywhere an thus overwrite the original status, I cloned $form_state['user'] into account and used $edit as a reference to that and changed it from there.
The array_interset_key() call actually does the same as entity_form_submit_build_entity, so I removed it. My patch includes the test from #37.
Comment #43
Volx CreditAttribution: Volx commentedComment #44
reglogge CreditAttribution: reglogge commentedAnd here is the patch from #35 combined with the new test from #37.
If everyone agrees that the new test is sufficient for testing this issue, development could proceed from here.
Let's see what the bot says...
Comment #45
fagohm, just preserving the status seems like a hack for this special use-case to me. Attached patch tries to fix the problem in general.
Comment #46
reglogge CreditAttribution: reglogge commented@fago: could you reroll your patch including the test from #37 so we can test whether your approach actually solves the issue?
Comment #47
brian_c CreditAttribution: brian_c commentedYes agreed, #35 is definitely a workaround. I tried to get more at the root problem in #28 but clearly don't know what I'm mucking with, hence my more "minimal changes possible" approach in #35.
Volx has a better approach in #42 with more general solution, I think similar or identical to fago's approach in #45.
Volx's solution has passed the entire test suite on his local, including reglogge's test in #37.
Comment #48
dixon_Here is fago's patch with the tests from regloggle in #37.
Comment #49
Volx CreditAttribution: Volx commentedI revoke my comment that we can remove the array_intersect_key() line, so that makes my patch equivalent to patch #48.
Comment #50
fago#42 has inconsistent variable naming for $edit - an array of values - and the user account. $edit should always be what it is, and not sometimes something else.
Comment #51
realityloopFollowing the steps in original post the patch at #48 is successfully sending emails to the new user once the account is activated
Comment #52
webchickComment #53
sunComments should wrap at 80 chars.
These are the only two mail assertions in here.
1) This patch does not test whether the mail that is sent is the welcome mail (NOT the activation mail).
2) The test should parse + use the link from the mail that is sent.
Powered by Dreditor.
Comment #54
webchickTagging.
Comment #55
reglogge CreditAttribution: reglogge commentedThis test could/should be written here #893276: Need tests for activation link in new user e-mail. Or should we mark this other issue as a duplicate then?
Comment #56
reglogge CreditAttribution: reglogge commentedWell, here are the new tests with the suggestions from #53.
I test whether the activation mail contains the string /user/reset/[uid] which should be a safe enough indication of the correct link being included.
Setting #893276: Need tests for activation link in new user e-mail to duplicate.
Comment #57
reglogge CreditAttribution: reglogge commentedLast patch had too many parameters in assertTrue() messing up the output of the test results.
Fixed.
Comment #58
reglogge CreditAttribution: reglogge commentedCleaning up code and adding t() to messages.
Comment #60
reglogge CreditAttribution: reglogge commented#58: 892950-user-activation-mail-4.patch queued for re-testing.
Comment #61
reglogge CreditAttribution: reglogge commentedSimpler test after having found assertMailString() in drupal_web_test_case.php :-)
Comment #62
sunThanks!
Watch out, your local working copy is outdated. A 'cvs update' is required.
For all these URLs, we should be checking the entire, absolute URL, i.e.:
url('user/reset/' . $uid, array('absolute' => TRUE))
And, at the right point, we want to actually use ("click") that URL/link -- that's why we should rather use pattern/regex matching here, so we get the full URL including the mail- and user-specific token.
Can we remove these unrelated changes, please? There's still no clear direction about whether we want t() in assertion messages or not. That's discussed in a (very long) separate issue already.
Powered by Dreditor.
Comment #63
sun.core CreditAttribution: sun.core commentedOnly touching tests, so demoting to normal.
Comment #64
Tor Arne Thune CreditAttribution: Tor Arne Thune commented