Index: user_status.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/user_status/user_status.module,v retrieving revision 1.9.2.8 diff -u -p -r1.9.2.8 user_status.module --- user_status.module 24 Jan 2008 05:09:46 -0000 1.9.2.8 +++ user_status.module 23 Mar 2008 19:01:19 -0000 @@ -27,7 +27,7 @@ function user_status_help($section) { drupal_set_message(t('None of these notifcations will be sent unless you specify a valid site !email_address on the !site_information settings page.', array('!email_address' => ''. t('E-mail address') .'', '!site_information' => l(t('Site information'), 'admin/settings/site-information'))), 'error'); } $output .= '

'. t('This page allows you to configure if automatic emails should be set to users when their account is activated, blocked, or deleted. For each account status, you can control if a notification should be sent, and if so, you define what the subject and body of the resulting email will be.') .'

' - . '

'. t('For any of the settings below, you can use placeholders which will be substituted with the current values for the user and site.') .' '. t('Available variables are:') .' %username, %site, %uri, %uri_brief, %mailto, %date, %edit_uri, %login_uri.

' + . '

'. t('For any of the settings below, you can use placeholders which will be substituted with the current values for the user and site.') .' '. t('Available variables are:') .' %username, %site, %uri, %uri_brief, %mailto, %date, %edit_uri, %user_uir, %login_uri.

' . '

'. t('If your site requires administrator approval for new users and you enable the automatic emails below whenever an account is activated, it is highly recommended that you change the text of the welcome message when users first register. By default, they will be sent a temporary password and one-time login URL that will not work, since their account will initially be blocked. It is better to put the initial login information into the notification email when their account is finally approved, so that users are never sent a temporary password and one-time login URL that will not work. You can modify this text at the !user_settings page.', array('!user_settings' => l(t('User settings'), 'admin/user/settings'))) .'

'; break; } @@ -108,6 +108,30 @@ function user_status_deleted_body() { return t("%username,\n\nYour account on %site has been deleted.\n"); } +function theme_user_status_activated_admin_body($variables) { + return strtr(t("User %username <%mailto> has been approved.\n%user_uri\n"), $variables); +} + +function theme_user_status_blocked_admin_body($variables) { + return strtr(t("User %username <%mailto> has been blocked.\n%user_uri\n"), $variables); +} + +function theme_user_status_deleted_admin_body($variables) { + return strtr(t("User %username <%mailto> has been deleted.\n"), $variables); +} + +function theme_user_status_activated_admin_subject($variables) { + return strtr(t('User %username approved at %site'), $variables); +} + +function theme_user_status_blocked_admin_subject($variables) { + return strtr(t('User %username blocked at %site'), $variables); +} + +function theme_user_status_deleted_admin_subject($variables) { + return strtr(t('User %username deleted at %site'), $variables); +} + /** * Form to modify default values for emails to users during account status modification * @@ -146,6 +170,14 @@ function user_status_settings_form() { '#rows' => 10, '#description' => t('In addition to the variables described above, %login_url (a one-time login URL) is available in the notification message. If the "%reset_password" box is checked, you may also use %password.', array('%reset_password' => t('Reset password when account is activated'))), ); + $form['activate_status']['user_status_activated_notify_list'] = array( + '#type' => 'textfield', + '#title' => t('Additional users to notify when an account is activated'), + '#default_value' => variable_get('user_status_activated_notify_list', ''), + '#description' => t('Comma-separated list of either email addresses or usernames to notify whenever an account is activated.'), + '#autocomplete_path' => 'user/autocomplete', + '#size' => 72, + ); $form['block_status'] = array( '#type' => 'fieldset', @@ -172,6 +204,15 @@ function user_status_settings_form() { '#cols' => 72, '#rows' => 5, ); + $form['block_status']['user_status_blocked_notify_list'] = array( + '#type' => 'textfield', + '#title' => t('Additional users to notify when an account is blocked'), + '#default_value' => variable_get('user_status_blocked_notify_list', ''), + '#description' => t('Comma-separated list of either email addresses or usernames to notify whenever an account is blocked.'), + '#autocomplete_path' => 'user/autocomplete', + '#size' => 72, + ); + $form['delete_status'] = array( '#type' => 'fieldset', @@ -198,11 +239,43 @@ function user_status_settings_form() { '#cols' => 72, '#rows' => 5, ); + $form['delete_status']['user_status_deleted_notify_list'] = array( + '#type' => 'textfield', + '#title' => t('Additional users to notify when an account is deleted'), + '#default_value' => variable_get('user_status_deleted_notify_list', ''), + '#description' => t('Comma-separated list of either email addresses or usernames to notify whenever an account is deleted.'), + '#autocomplete_path' => 'user/autocomplete', + '#size' => 72, + ); + $form['#validate']['user_status_settings_validate'] = array(); return system_settings_form($form); } /** + * Form validation handler to check the notification list settings. + */ +function user_status_settings_validate($form_id, $form_values) { + foreach (array('activated', 'blocked', 'deleted') as $key) { + $errors = array(); + $name = 'user_status_'. $key .'_notify_list'; + if (!empty($form_values[$name])) { + foreach (explode(',', $form_values[$name]) as $value) { + $value = trim($value); + if (!db_num_rows(db_query("SELECT uid FROM {users} WHERE LOWER(name) = LOWER('%s')", $value))) { + if (!valid_email_address($value)) { + $errors[] = check_plain($value); + } + } + } + if (!empty($errors)) { + form_set_error($name, t('The following values are neither existing user names on this site, nor valid e-mail addresses:' . theme('item_list', $errors))); + } + } + } +} + +/** * Sends user an email based on the account modification * * @param string $op @@ -214,6 +287,10 @@ function user_status_user($op, &$edit, & if ($op == 'update' || $op == 'delete') { // We might send the email, so just set all of this up once. $from = variable_get('site_mail', ini_get('sendmail_from')); + if (!valid_email_address($from)) { + watchdog('user_status', t('Site e-mail not configured, can not send notifications.', WATCHDOG_ERROR)); + return false; + } $headers = array( 'X-Mailer' => 'Drupal User Status module http://drupal.org/project/user_status', ); @@ -222,16 +299,14 @@ function user_status_user($op, &$edit, & switch ($op) { case 'update': if (isset($edit['status']) && $edit['status'] != $user->status) { - if (valid_email_address($user->mail) && valid_email_address($from)) { - switch ($edit['status']) { + switch ($edit['status']) { case 0: if (variable_get('user_status_blocked_enable', FALSE)) { // Do not generate new password and 1-time login when blocking. $variables = _user_status_get_variables($user, FALSE); - $subject = strtr(variable_get('user_status_blocked_subject', user_status_blocked_subject()), $variables); - $body = strtr(variable_get('user_status_blocked_body', user_status_blocked_body()), $variables); - return drupal_mail('user_status_blocked', $user->mail, $subject, $body, $from, $headers); + _user_status_notify_user('blocked', $user, $variables, $from, $headers); } + _user_status_notify_admin('blocked', $variables, $from, $headers); break; case 1: @@ -239,31 +314,139 @@ function user_status_user($op, &$edit, & // Since the user is now active, generate a new temporary // password and 1-time login URL. $variables = _user_status_get_variables($user, TRUE); - $subject = strtr(variable_get('user_status_activated_subject', user_status_activated_subject()), $variables); - $body = strtr(variable_get('user_status_activated_body', user_status_activated_body()), $variables); - return drupal_mail('user_status_active', $user->mail, $subject, $body, $from, $headers); + _user_status_notify_user('activated', $user, $variables, $from, $headers); + _user_status_notify_admin('activated', $variables, $from, $headers); + } + else { + // If we're *only* notifying the admin, don't reset the password. + $variables = _user_status_get_variables($user, FALSE); + _user_status_notify_admin('activated', $variables, $from, $headers); } break; - } // end status switch - } // end email if + } // end status switch } // end status if break; case 'delete': + // Do not generate new password and 1-time login when deleting. + $variables = _user_status_get_variables($user, FALSE); if (variable_get('user_status_deleted_enable', FALSE)) { - if (valid_email_address($user->mail) && valid_email_address($from)) { - // Do not generate new password and 1-time login when deleting. - $variables = _user_status_get_variables($user, FALSE); - $subject = strtr(variable_get('user_status_deleted_subject', user_status_deleted_subject()), $variables); - $body = strtr(variable_get('user_status_deleted_body', user_status_deleted_body()), $variables); - return drupal_mail('user_status_deleted', $user->mail, $subject, $body, $from, $headers); - } + _user_status_notify_user('deleted', $user, $variables, $from, $headers); } + _user_status_notify_admin('deleted', $variables, $from, $headers); break; } return false; } +function _user_status_get_user_body($keyword, $variables) { + switch($keyword) { + case 'activated': + return strtr(variable_get('user_status_activated_body', user_status_activated_body()), $variables); + case 'blocked': + return strtr(variable_get('user_status_blocked_body', user_status_blocked_body()), $variables); + case 'deleted': + return strtr(variable_get('user_status_deleted_body', user_status_deleted_body()), $variables); + } +} + +function _user_status_get_user_subject($keyword, $variables) { + switch($keyword) { + case 'activated': + return strtr(variable_get('user_status_activated_subject', user_status_activated_subject()), $variables); + case 'blocked': + return strtr(variable_get('user_status_blocked_subject', user_status_blocked_subject()), $variables); + case 'deleted': + return strtr(variable_get('user_status_deleted_subject', user_status_deleted_subject()), $variables); + } +} + +function _user_status_get_admin_body($keyword, $variables) { + switch($keyword) { + case 'activated': + return theme('user_status_activated_admin_body', $variables); + case 'blocked': + return theme('user_status_blocked_admin_body', $variables); + case 'deleted': + return theme('user_status_deleted_admin_body', $variables); + } +} + +function _user_status_get_admin_subject($keyword, $variables) { + switch($keyword) { + case 'activated': + return theme('user_status_activated_admin_subject', $variables); + case 'blocked': + return theme('user_status_blocked_admin_subject', $variables); + case 'deleted': + return theme('user_status_deleted_admin_subject', $variables); + } +} + +/** + * Helper that notifies the user for a given user action. + */ +function _user_status_notify_user($keyword, $user, $variables, $from, $headers) { + $mail_key = 'user_status_'. $keyword; + $body = _user_status_get_user_body($keyword, $variables); + $subject = _user_status_get_user_subject($keyword, $variables); + _user_status_mail($mail_key, $user->mail, $subject, $body, $from, $headers); +} + +/** + * Helper that optionally notifies admins for a given user action. + */ +function _user_status_notify_admin($keyword, $variables, $from, $headers) { + $mail_key = 'user_status_'. $keyword .'_notify_list'; + $notify_list = variable_get($mail_key, ''); + if (!empty($notify_list)) { + $body = _user_status_get_admin_body($keyword, $variables); + $subject = _user_status_get_admin_subject($keyword, $variables); + foreach (explode(',', $notify_list) as $value) { + $value = trim($value); + $query = db_query("SELECT mail FROM {users} WHERE LOWER(name) = LOWER('%s')", $value); + $result = db_fetch_object($query); + if (!empty($result)) { + _user_status_mail($mail_key, $result->mail, $subject, $body, $from, $headers); + } + elseif (valid_email_address($value)) { + _user_status_mail($mail_key, $value, $subject, $body, $from, $headers); + } + else { + watchdog('user_status', t('Value %value in %setting_name is no longer a valid user.', array('%value' => $value, '%setting_name' => $mail_key)), WATCHDOG_ERROR); + } + } + } +} + +/** + * Helper that actually sends a given notification email and logs it. + */ +function _user_status_mail($mailkey, $mail, $subject, $body, $from, $headers) { + drupal_mail($mailkey, $mail, $subject, $body, $from, $headers); + watchdog('user_status', t('Sent %message_type message to %mail', array('%message_type' => _user_status_get_text_from_key($mailkey), '%mail' => $mail))); +} + +/** + * Return the human-readable text for a given mail key. + */ +function _user_status_get_text_from_key($mailkey) { + switch ($mailkey) { + case 'user_status_activated': + return t('User activated'); + case 'user_status_activated_notify_list': + return t('User activated notification list'); + case 'user_status_blocked': + return t('User blocked'); + case 'user_status_blocked_notify_list': + return t('User blocked notification list'); + case 'user_status_deleted': + return t('User deleted'); + case 'user_status_deleted_notify_list': + return t('User deleted notification list'); + } +} + /** * Return an array of substitution variables for email bodies and subjects. * @@ -287,6 +470,7 @@ function _user_status_get_variables($use '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $user->uid .'/edit', NULL, NULL, TRUE), + '%user_uri' => url('user/'. $user->uid, NULL, NULL, TRUE), ); if ($reset_password) { if (variable_get('user_status_reset_password', FALSE)) {