I maintain the http://drupal.org/project/user_status module, which adds some important usability enhancements for drupal sites, especially ones that require admin approval for new account requests. It lets the admin configure if the site should automatically notify users whenever accounts are activated, blocked, or deleted. Lots of people have said this should move into core, and I heartily agree. ;)

This initial patch still needs work. This is just a first draft at the unified settings UI and the default texts for everything. It doesn't actually generate any additional emails yet, but I wanted to post the patch in this state, so I could start to get some UI/usability feedback from other folks in parallel while I get the underlying functionality happening. The big change is that each of the (now up to 7) possible notification emails is in its own collapsed fieldset, all within the main "User e-mail settings" fieldset. The fieldset for the welcome message corresponding to the currently selected registration method is the only one that is expanded by default. (And yes, adding some jQuery goodness to automatically collapse/expand based on when an admin toggles the registration radios would be a slick addition someday).

Also, note that this patch is being bitten by a bug in our jQuery code on safari: http://drupal.org/node/144684 so don't let that scare you. ;) Just test on FF if you're on a mac. We'll certainly fix the jQuery before 6.0, so please don't talk about that bug in this issue.

Finally, I was thinking it might be nice to add a way for admins to override the site-wide defaults on a case-by-case basis when doing a specific action (activating, blocking, deleting, etc). That'd be mostly pretty easy on the user edit page by means of a checkbox "Notify user of this change" next to the status radios. Similarly on the confirm form for deleting the user, we could have a checkbox.

Unfortunately, this gets a little ugly using the mass edit operations at /admin/user/user. The delete case is still easy, since there's a confirm form (and you'd just have to say it was an all-or-nothing for everyone being deleted at once, not a series of checkboxes for each about-to-be-deleted user). But, the activate ("unblock") and block cases are rather hard, since you can't have the checkbox default to the right thing unless you know what the action is going to be. We could get help from jQuery again, but it's not clear how it should degrade. Perhaps we really want 2 checkboxes on this form "Notify users that are unblocked" and "Notify users that are blocked", each one defaulting to the right thing based on the site-wide settings. Then, jQuery could conditionally hide them, except when the selected action on the drop-down is to perform one of those 2 actions. Suggestions, mockups, or screenshots welcome.

However, for phase 1, I'd be totally happy to say that mass edit operations just get the site-wide defaults, period. In fact, I don't even think the checkbox on the user edit page itself is a blocker for this functionality to go in, but others might disagree. ;)

Comments

dww’s picture

StatusFileSize
new125.98 KB

screenshot of admin/user/settings when you've got "Visitors can create accounts but administrator approval is required." selected as your current registration method...

dww’s picture

StatusFileSize
new114.19 KB

and here's what the fieldset for "Account activation notification message" looks like by default.

dww’s picture

Status: Needs work » Needs review
StatusFileSize
new17.43 KB

new patch, now ready for review:

  • actually works. ;) i cleaned up, simplified, and unified the token generation and email sending. given that, adding the notifications for blocked/activated/deleted took about 4 lines of code total. ;)
  • better wording of some titles and descriptions in the admin UI based on feedback in IRC.
  • more appropriately sized defaults for the size of the text areas, based on the default texts.

the remaining TODO items:

  1. all of the welcome email sending is now sharing _user_mail_tokens(), but it isn't yet using the _user_mail_notify() goodness.
  2. the drupal_set_message() when you create an account that's pending approval is lying about having your password sent to you. see http://drupal.org/node/110474
  3. the UI changes on the account edit page (and maybe admin/user/user) for exceptions to the site-wide defaults for notifications.

however, i don't think any of those are necessarily worth holding up this patch for, so i'm setting this to CNR.

dww’s picture

StatusFileSize
new20.82 KB

this patch moves all of the email notifications under the control of _user_mail_notify(). i haven't had a chance to test it as thoroughly as i'd like, but it should be working fine. even though this version has to complicate _user_mail_notify() a little more, overall, i think this is cleaner than the previous patch.

dries’s picture

This looks like a good patch. The 'operations' aren't 100% though:

+      _user_mail_notify($notify ? 'admin' : 'welcome', $account, $pass);

For example, I had to look at _user_mail_notify() to understand what 'admin' was about, and how it was different from 'welcome'. I'd go for slightly longer operations that are a bit more descriptive. For example, rename these to 'welcome-admin' and 'welcome-user'. 'pass' could be 'password-request'. The difference between 'activated' and 'approved' might also be subtle. This is all minor stuff, but if we can make it a bit more self-explanatory, that would be great.

Would this allow us the simplify the way we compute the $mail_id?

Change $rval to $result -- that's more consistent with the rest of core.

We'll want to add a brief entry to the CHANGELOG.txt.

This patch might also help Gabor -- he was working on a related patch to make sure that e-mails can be sent in the user's preferred language, rather than the administrator's preferred language. This means we'll want to pass in, or resolve, the $account's preferred language too. Gabor can probably help with this -- either before or after this patch lands.

dww’s picture

Status: Needs review » Needs work

well, the reason (perhaps bad) that i stuck with the cryptic stuff was to match all the existing variable names for these settings, to avoid any upgrade issues... same with the complication on setting $mail_id... i just didn't want to change anything, so existing code or settings that are dealing with these mail messages wouldn't break.

if you'd rather, i could use more verbose $op flags at the call sites, and just make a big switch statement at the top of _user_mail_notify() to set the $mail_id, variable names to lookup, and default notification behavior for each operation separately, to make it more clear but still comply with the old names/values for everything.

or, for a slightly more radical change, we could rename all the $op flags to be verbose, then *change* all the $mail_id and variable names completely, and forget about sites that have already customized these settings. then, the code to _user_mail_notify() wouldn't need a switch at all, and all the mail_ids and variable names would just be directly derived from the $op. i suppose i could add a db update to rename the old variables to their new equivalents, to be really kind to sites that are upgrading...

just let me know what you'd prefer.

thanks,
-derek

hunmonk’s picture

subscribing

dww’s picture

Status: Needs work » Needs review
StatusFileSize
new22.68 KB
  • uses more verbose $op values at all call sites. there's now a giant switch statement to map these back into the same variable names and mail ids we always used to use, to avoid the need for a db update, etc.
  • s/$rval/$result/
  • adds CHANGELOG.txt entry

if you'd rather remove the switch, change all the mail ids and variables to the new verbose names, and add a DB update, we can do that, too. just set back to CNW with clear direction on exactly how you want it. ;)

feedback on the specific choices for the new verbose names would be good, too, if you don't like these:

 *  'register-admin-created': Welcome message for users created by the admin
 *  'register-welcome': Welcome message when users can register themselves
 *  'register-pending-approval': Welcome message, users pending admin approval
 *  'password-reset': Password recovery request
 *  'status-active': Account activated
 *  'status-blocked': Account blocked
 *  'status-deleted': Account deleted

thanks,
-derek

dries’s picture

I think that removing the switch, might be a nice code cleanup. What do *you* think?

dww’s picture

StatusFileSize
new26.16 KB

well, removing the switch is obviously nice. ;) the downsides are a) requires a DB update, and b) makes some of the variable names a lot longer, which therefore tends to cause various parts of the source to overflow the nice 80 chars i try to stay under. ;) however, i guess those aren't good enough reasons for the added potential confusion. so, here's a new patch:

  • all $op values renamed to use underscores, not hyphens, to facilitate using them directly in variable names, etc
  • renames all variable names (and therefore, FAPI elements on the settings page) to match their corresponding $op values
  • renames all mail IDs to match the $op values (though using hypens instead of underscores to be consistent with other mail id strings in core).
  • renames "status_active" to "status_activated" at the request of webchick
  • adds system_update_6017() to rename the old values to the new names (and deletes the old variables, of course).

i tested the upgrade path and a lot of other stuff, but more thorough testing (especially the actual emails themselves) would be helpful. otherwise, i think this should pretty much be RTBC at this point.

dries’s picture

This looks good. Thanks dww.

The one thing that comes to mind is this: do we properly tell the administrator that we sent a mail to the user? It might be good to check the different actions, and to sprinkle some "A mail with instructions has been sent to the user." in the drupal_set_message() calls. This could help prevent that the administrator manually sends another e-mail. I haven't checked -- chances are that this isn't necessary.

dww’s picture

actually, i'd like to see a separate cleanup of the drupal_set_message() stuff associated with all of this. in some cases, the text of the message should itself be another setting. see http://drupal.org/node/110474. it wouldn't hurt to check over the watchdog() calls related to all of this, too. however, i don't think either is required before the feature/api freeze, those are just minor usability enhancements. so, i'd prefer to see this patch go in, and i promise i'll get the other stuff in well before the first beta.

thanks,
-derek

gábor hojtsy’s picture

Well, this patch is very good in itself. Jose prepared a patch with similar values in terms of Drupal core code cleanup. (http://drupal.org/node/82499) Centralizing token handling and email sending for $account-s (as opposed to email sending to an email address) is very good. Our motivation was to send mail to users *in their language*. Dries pointed out that Jose's very similar code centralizing solution presented there results in code cleanup but does not help contrib modules, who would like to send (notification or any other kind of) emails to users.

This patch is in a similar position. It expands on what Drupal core offers, but does not open the possibility to contrib modules actually. The question is how much code a contrib module like project module would share with Drupal core to send mails to $account-s. Maybe your _user_mail_tokens() abstraction is just that, and the inner workings of _user_mail_notify() is not for contrib modules.

But what if we would move out all user notification email settings to a separate settings screen? Would that clutter up the admin panel? I am not sure. It would allow for exact tracking of what should be the defaults of checkboxes though (no cross dependent settings on the same form), and it would also allow contrib modules to cleanly alter that form and add new notification mail settings if need be, not to have user notification email settings scattered elsewhere. The question is how much logic can they reuse from the notification code. Now they can reuse the tokens but not reuse the variable based email sending code.

Let me repeat that this patch is good as is, and seems to be a very solid solution for Drupal core in itself. Maybe we think a bit ahead :)

dww’s picture

thinking ahead is good. ;) yeah, helping contrib with this wasn't on my radar, since this patch started as my attempt to just move one of my contribs into core so i wouldn't have to maintain it myself anymore. ;) that said, yeah, we should probably make user_mail_tokens() a publically-facing API (without the leading underscore), so that other people can use it, too. i guess eaton and greggles aren't going to push for token API in D6 core, so i wasn't even thinking of doing a partial solution like this, but i guess we could do a little better than nothing with this patch.

the actual code for _user_mail_notify() is very specific to user.module. first of all, it doesn't do much at all. what it does depends almost entirely on _user_mail_text(), which is also private to user.module (unless http://drupal.org/node/145164 happens). so, i'd be happy keeping that private.

in terms of the UI, if you put all the email stuff on a separate page, i'm a little worried, since for example, the settings you care about customizing depend on your user registration policy (open, admin-only, requires approval). if you look closely, my patch automatically expands the right fieldset based on the current value of that variable (and with a little jquery we could even consider dynamically expanding/collapsing the fieldsets if you change the radio on the fly). they really are related, so i'd rather not sprinkle them onto different pages if at all possible. i agree that the fieldset of fieldsets isn't the most elegant, but in this case, i think it's probably about as clean a solution as we can get...

contribs *can* hook_form_alter() this settings page themselves, and they can insert their own fieldsets into the user email settings fieldset using the same basic design. and, just like user_status.module has done for a long time, they can use hook_user to know when to trigger a certain action (e.g. maybe the D6 port of user_status.module in contrib will *just* be for automatic notifications on role changes -- http://drupal.org/node/98107)...

Crell’s picture

Subscribing, since I think this will have a big impact on inactive_user, which I recently inherited. :-)

gábor hojtsy’s picture

Hm, ok. Open the built in token list code as an API function and let contrib use its own mail sending then. We will see how the language improvements can build on this. If nothing else, we can easily language enable Drupal core by adding a few lines into the user mail notify function and changing the t() calls in the mail text function, as it is in Jose's patch.

dww’s picture

StatusFileSize
new25.66 KB

new patch:

  • user_mail_tokens() is now a public-facing API call, not private to user.module
  • fixed a bug in the DB update (forgot i had renamed the "register-welcome" op to be less ambiguous).
  • since i hate it when DB updates do queries but don't actually tell you, i changed it to populate $ret with info on each of the variables we're setting and deleting (just the names, not the values)

so, update.php now returns the following for 6017:

system module

Update #6017

  • variable_set(user_mail_register_admin_created_subject)
  • variable_del(user_mail_admin_subject)
  • variable_set(user_mail_register_admin_created_body)
  • variable_del(user_mail_admin_body)
  • variable_set(user_mail_register_pending_approval_subject)
  • variable_del(user_mail_approval_subject)
  • variable_set(user_mail_register_pending_approval_body)
  • variable_del(user_mail_approval_body)
  • variable_set(user_mail_register_no_approval_required_subject)
  • variable_del(user_mail_welcome_subject)
  • variable_set(user_mail_register_no_approval_required_body)
  • variable_del(user_mail_welcome_body)
  • variable_set(user_mail_password_reset_subject)
  • variable_del(user_mail_pass_subject)
  • variable_set(user_mail_password_reset_body)
  • variable_del(user_mail_pass_body)

if folks think that's too much noise, it'd be easy to rip out the 2 lines that do this...

dww’s picture

StatusFileSize
new26.64 KB

whoops, last patch didn't include the CHANGELOG.txt diff.

gábor hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

I tested the patch and it works nicely (although my local testing machine is not set up to send emails, you reuse drupal_mail() so there should not be any problem). By looking through at the code, documentation is in place, you solved Dries' concerns, so I think this is ready to go in. The language issue will be solved based on this.

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed! :)

dww’s picture

excellent, thanks folks!

dww’s picture

Status: Fixed » Needs review
StatusFileSize
new921 bytes

whoops:

modules/comment/comment.js
----------------------------
revision 1.2
date: 2007-05-20 12:34:47 +0000;  author: dries;  state: Exp;  lines: +2 -2;  co
mmitid: 74414650400f4567;
- Patch #144859 by dww: added optional e-mail notifications when user are approved, blocked, or deleted.

which included this diff:

diff -u -p -r1.1 -r1.2
--- modules/comment/comment.js  17 May 2007 21:05:38 -0000  1.1
+++ modules/comment/comment.js  20 May 2007 12:34:47 -0000  1.2
@@ -1,4 +1,4 @@
-// $Id: comment.js,v 1.1 2007/05/17 21:05:38 dries Exp $
+// $Id: comment.js,v 1.2 2007/05/20 12:34:47 dries Exp $
 if (Drupal.jsEnabled) {
   $(document).ready(function() {
     var parts = new Array("name", "homepage", "mail");
@@ -26,7 +26,7 @@ Drupal.comment.getCookie = function(name
       if (end == -1) {
         end = document.cookie.length;
       }
-      returnValue = unescape(document.cookie.substring(offset, end));
+      returnValue = decodeURIComponent(document.cookie.substring(offset, end).r
eplace(/\+/g, '%20'));
     }
   }

which wasn't anywhere in this patch. not sure what that's about, but it should probably be undone. attached patch is just the reverse of this diff, so it should apply cleanly to undo revision 1.2.

thanks,
-derek

webchick’s picture

Status: Needs review » Fixed

I think that's ok... it was part of the fix for http://drupal.org/node/141131.

Anonymous’s picture

Status: Fixed » Closed (fixed)
ianr’s picture

The problem is that this only solves half the problem, the other half is something like admin_notify, so that they admin actually knows when they have new users to approve!

dww’s picture

Huh? Core notifies the site admin via email when there are new users pending approval... I don't see why http://drupal.org/project/user_register_notify needs to exist at all. Perhaps it could provide the flexibility to notify multiple admins (a user-approval team of some sort), but then again, you could always make the site admin email address a mailing list. Anyway, this thread is *not* the place to discuss it, please don't re-open old issues like this. This issue is about moving user_status.module into core, which we did, and it's now fixed and closed. Let's leave it that way. ;) Thanks.