summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/bootstrap.inc14
-rw-r--r--includes/mail.inc202
-rw-r--r--modules/contact/contact.module120
-rw-r--r--modules/locale/locale.module26
-rw-r--r--modules/user/user.module142
5 files changed, 335 insertions, 169 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index a2aa44742..e1b28aca7 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -1030,9 +1030,17 @@ function language_list($field = 'language', $reset = FALSE) {
// Init language list
if (!isset($languages)) {
- $result = db_query('SELECT * FROM {languages} ORDER BY weight ASC, name ASC');
- while ($row = db_fetch_object($result)) {
- $languages['language'][$row->language] = $row;
+ if (variable_get('language_count', 1) > 1) {
+ $result = db_query('SELECT * FROM {languages} ORDER BY weight ASC, name ASC');
+ while ($row = db_fetch_object($result)) {
+ $languages['language'][$row->language] = $row;
+ }
+ }
+ else {
+ // One language only, the locale tables might not even
+ // be in place, so use the default language only.
+ $default = language_default();
+ $languages['language'][$default->language] = $default;
}
}
diff --git a/includes/mail.inc b/includes/mail.inc
index 05fa4411a..dcbebd660 100644
--- a/includes/mail.inc
+++ b/includes/mail.inc
@@ -2,81 +2,183 @@
// $Id$
/**
- * Send an e-mail message, using Drupal variables and default settings.
- * More information in the <a href="http://php.net/manual/en/function.mail.php">
- * PHP function reference for mail()</a>
+ * Compose and optionally send an e-mail message.
+ *
+ * Sending an e-mail works with defining an e-mail template (subject, text
+ * and possibly e-mail headers) and the replacement values to use in the
+ * appropriate places in the template. Processed e-mail templates are
+ * requested from hook_mail() from the module sending the e-mail. Any module
+ * can modify the composed e-mail message array using hook_mail_alter().
+ * Finally drupal_mail_send() sends the e-mail, which can be reused
+ * if the exact same composed e-mail is to be sent to multiple recipients.
+ *
+ * Finding out what language to send the e-mail with needs some consideration.
+ * If you send e-mail to a user, her preferred language should be fine, so
+ * use user_preferred_language(). If you send email based on form values
+ * filled on the page, there are two additional choices if you are not
+ * sending the e-mail to a user on the site. You can either use the language
+ * used to generate the page ($language global variable) or the site default
+ * language. See language_default(). The former is good if sending e-mail to
+ * the person filling the form, the later is good if you send e-mail to an
+ * address previously set up (like contact addresses in a contact form).
*
- * @param $mailkey
- * A key to identify the mail sent, for altering.
+ * Taking care of always using the proper language is even more important
+ * when sending e-mails in a row to multiple users. Hook_mail() abstracts
+ * whether the mail text comes from an administrator setting or is
+ * static in the source code. It should also deal with common mail tokens,
+ * only receiving $params which are unique to the actual e-mail at hand.
+ *
+ * An example:
+ *
+ * @code
+ * function example_notify($accounts) {
+ * foreach ($accounts as $account) {
+ * $params['account'] = $account;
+ * // example_mail() will be called based on the first drupal_mail() parameter.
+ * drupal_mail('example', 'notify', $account->mail, user_preferred_language($account), $params);
+ * }
+ * }
+ *
+ * function example_mail($key, &$message, $params) {
+ * $language = $message['language'];
+ * $variables = user_mail_tokens($params['account'], $language);
+ * switch($key) {
+ * case 'notice':
+ * $message['subject'] = t('Notification from !site', $variables, $language->language);
+ * $message['body'] = t("Dear !username\n\nThere is new content available on the site.", $variables, $language->language);
+ * break;
+ * }
+ * }
+ * @endcode
+ *
+ * @param $module
+ * A module name to invoke hook_mail() on. The {$module}_mail() hook will be
+ * called to complete the $message structure which will already contain common
+ * defaults.
+ * @param $key
+ * A key to identify the e-mail sent. The final e-mail id for e-mail altering
+ * will be {$module}_{$key}.
* @param $to
- * The mail address or addresses where the message will be send to. The
+ * The e-mail address or addresses where the message will be sent to. The
* formatting of this string must comply with RFC 2822. Some examples are:
* user@example.com
* user@example.com, anotheruser@example.com
* User <user@example.com>
* User <user@example.com>, Another User <anotheruser@example.com>
- * @param $subject
- * Subject of the e-mail to be sent. This must not contain any newline
- * characters, or the mail may not be sent properly.
- * @param $body
- * Message to be sent. Accepts both CRLF and LF line-endings.
- * E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
- * smart plain text wrapping.
+ * @param $language
+ * Language object to use to compose the e-mail.
+ * @param $params
+ * Optional parameters to build the e-mail.
* @param $from
* Sets From, Reply-To, Return-Path and Error-To to this value, if given.
- * @param $headers
- * Associative array containing the headers to add. This is typically
- * used to add extra headers (From, Cc, and Bcc).
- * <em>When sending mail, the mail must contain a From header.</em>
- * @return Returns TRUE if the mail was successfully accepted for delivery,
- * FALSE otherwise.
+ * @param $send
+ * Send the message directly, without calling drupal_mail_send() manually.
+ * @return
+ * The $message array structure containing all details of the
+ * message. If already sent ($send = TRUE), then the 'result' element
+ * will contain the success indicator of the e-mail.
*/
-function drupal_mail($mailkey, $to, $subject, $body, $from = NULL, $headers = array()) {
- $defaults = array(
- 'MIME-Version' => '1.0',
- 'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
+function drupal_mail($module, $key, $to, $language, $params = array(), $from = NULL, $send = TRUE) {
+ $default_from = variable_get('site_mail', ini_get('sendmail_from'));
+
+ // Bundle up the variables into a structured array for altering.
+ $message = array(
+ 'id' => $module .'_'. $key,
+ 'to' => $to,
+ 'from' => isset($from) ? $from : $default_from,
+ 'language' => $language,
+ 'params' => $params,
+ 'subject' => '',
+ 'body' => array()
+ );
+
+ // Build the default headers
+ $headers = array(
+ 'MIME-Version' => '1.0',
+ 'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
'Content-Transfer-Encoding' => '8Bit',
- 'X-Mailer' => 'Drupal'
+ 'X-Mailer' => 'Drupal'
);
- // To prevent e-mail from looking like spam, the addresses in the Sender and
- // Return-Path headers should have a domain authorized to use the originating
- // SMTP server. Errors-To is redundant, but shouldn't hurt.
- $default_from = variable_get('site_mail', ini_get('sendmail_from'));
if ($default_from) {
- $defaults['From'] = $defaults['Reply-To'] = $defaults['Sender'] = $defaults['Return-Path'] = $defaults['Errors-To'] = $default_from;
+ // To prevent e-mail from looking like spam, the addresses in the Sender and
+ // Return-Path headers should have a domain authorized to use the originating
+ // SMTP server. Errors-To is redundant, but shouldn't hurt.
+ $headers['From'] = $headers['Reply-To'] = $headers['Sender'] = $headers['Return-Path'] = $headers['Errors-To'] = $default_from;
}
if ($from) {
- $defaults['From'] = $defaults['Reply-To'] = $from;
+ $headers['From'] = $headers['Reply-To'] = $from;
}
- $headers = array_merge($defaults, $headers);
-
- // Bundle up the variables into a structured array for altering.
- $message = array('#mail_id' => $mailkey, '#to' => $to, '#subject' => $subject, '#body' => $body, '#from' => $from, '#headers' => $headers);
+ $message['headers'] = $headers;
+
+ // Build the e-mail (get subject and body, allow additional headers) by
+ // invoking hook_mail() on this module. We cannot use module_invoke() as
+ // we need to have $message by reference in hook_mail().
+ if (function_exists($function = $module .'_mail')) {
+ $function($key, $message, $params);
+ }
+
+ // Invoke hook_mail_alter() to allow all modules to alter the resulting e-mail.
drupal_alter('mail', $message);
- $mailkey = $message['#mail_id'];
- $to = $message['#to'];
- $subject = $message['#subject'];
- $body = $message['#body'];
- $from = $message['#from'];
- $headers = $message['#headers'];
- // Allow for custom mail backend
+ // Concatenate and wrap the e-mail body.
+ $message['body'] = is_array($message['body']) ? drupal_wrap_mail(implode("\n\n", $message['body'])) : drupal_wrap_mail($message['body']);
+
+ // Optionally send e-mail.
+ if ($send) {
+ $message['result'] = drupal_mail_send($message);
+ }
+
+ return $message;
+}
+
+/**
+ * Send an e-mail message, using Drupal variables and default settings.
+ * More information in the <a href="http://php.net/manual/en/function.mail.php">
+ * PHP function reference for mail()</a>. See drupal_mail() for information on
+ * how $message is composed.
+ *
+ * @param $message
+ * Message array with at least the following elements:
+ * - id
+ * A unique identifier of the e-mail type. Examples: 'contact_user_copy',
+ * 'user_password_reset'.
+ * - to
+ * The mail address or addresses where the message will be sent to. The
+ * formatting of this string must comply with RFC 2822. Some examples are:
+ * user@example.com
+ * user@example.com, anotheruser@example.com
+ * User <user@example.com>
+ * User <user@example.com>, Another User <anotheruser@example.com>
+ * - subject
+ * Subject of the e-mail to be sent. This must not contain any newline
+ * characters, or the mail may not be sent properly.
+ * - body
+ * Message to be sent. Accepts both CRLF and LF line-endings.
+ * E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
+ * smart plain text wrapping.
+ * - headers
+ * Associative array containing all mail headers.
+ * @return
+ * Returns TRUE if the mail was successfully accepted for delivery,
+ * FALSE otherwise.
+ */
+function drupal_mail_send($message) {
+ // Allow for a custom mail backend.
if (variable_get('smtp_library', '') && file_exists(variable_get('smtp_library', ''))) {
include_once './' . variable_get('smtp_library', '');
- return drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $headers);
+ return drupal_mail_wrapper($message);
}
else {
- // Note: e-mail uses CRLF for line-endings, but PHP's API requires LF.
- // They will appear correctly in the actual e-mail that is sent.
-
$mimeheaders = array();
- foreach ($headers as $name => $value) {
+ foreach ($message['headers'] as $name => $value) {
$mimeheaders[] = $name .': '. mime_header_encode($value);
}
return mail(
- $to,
- mime_header_encode($subject),
- str_replace("\r", '', $body),
+ $message['to'],
+ mime_header_encode($message['subject']),
+ // Note: e-mail uses CRLF for line-endings, but PHP's API requires LF.
+ // They will appear correctly in the actual e-mail that is sent.
+ str_replace("\r", '', $message['body']),
join("\n", $mimeheaders)
);
}
@@ -127,7 +229,7 @@ function drupal_wrap_mail($text, $indent = '') {
/**
* Transform an HTML string into plain text, preserving the structure of the
- * markup. Useful for preparing the body of a node to be sent by email.
+ * markup. Useful for preparing the body of a node to be sent by e-mail.
*
* The output will be suitable for use as 'format=flowed; delsp=yes' text
* (RFC 3676) and can be passed directly to drupal_mail() for sending.
diff --git a/modules/contact/contact.module b/modules/contact/contact.module
index cb628bbac..4ffa19545 100644
--- a/modules/contact/contact.module
+++ b/modules/contact/contact.module
@@ -360,48 +360,37 @@ function contact_mail_user(&$form_state, $recipient) {
* Process the personal contact page form submission.
*/
function contact_mail_user_submit($form, &$form_state) {
- global $user;
+ global $user, $language;
$account = user_load(array('uid' => arg(1), 'status' => 1));
- // Compose the body:
- $message[] = "$account->name,";
- $message[] = t("!name (!name-url) has sent you a message via your contact form (!form-url) at !site.", array('!name' => $user->name, '!name-url' => url("user/$user->uid", array('absolute' => TRUE)), '!form-url' => url($_GET['q'], array('absolute' => TRUE)), '!site' => variable_get('site_name', 'Drupal')));
- $message[] = t("If you don't want to receive such e-mails, you can change your settings at !url.", array('!url' => url("user/$account->uid", array('absolute' => TRUE))));
- $message[] = t('Message:');
- $message[] = $form_state['values']['message'];
-
- // Prepare all fields:
+
+ // Send from the current user to the requested user.
$to = $account->mail;
$from = $user->mail;
- // Format the subject:
- $subject = '['. variable_get('site_name', 'Drupal') .'] '. $form_state['values']['subject'];
-
- // Prepare the body:
- $body = drupal_wrap_mail(implode("\n\n", $message));
+ // Save both users and all form values for email composition.
+ $values = $form_state['values'];
+ $values['account'] = $account;
+ $values['user'] = $user;
- // Send the e-mail:
- drupal_mail('contact-user-mail', $to, $subject, $body, $from);
+ // Send the e-mail in the requested user language.
+ drupal_mail('contact', 'user_mail', $to, user_preferred_language($account), $values, $from);
- // Send a copy if requested:
+ // Send a copy if requested, using current page language.
if ($form_state['values']['copy']) {
- drupal_mail('contact-user-copy', $from, $subject, $body, $from);
+ drupal_mail('contact', 'user_copy', $from, $language, $values, $from);
}
- // Log the operation:
flood_register_event('contact');
watchdog('mail', '%name-from sent %name-to an e-mail.', array('%name-from' => $user->name, '%name-to' => $account->name));
-
- // Set a status message:
drupal_set_message(t('The message has been sent.'));
-
- // Jump to the user's profile page:
+
+ // Back to the requested users profile page.
$form_state['redirect'] = "user/$account->uid";
- return;
}
/**
- * Site-wide contact page
+ * Site-wide contact page.
*/
function contact_site_page() {
global $user;
@@ -504,45 +493,68 @@ function contact_mail_page_validate($form, &$form_state) {
* Process the site-wide contact page form submission.
*/
function contact_mail_page_submit($form, &$form_state) {
+ global $language;
+
+ $values = $form_state['values'];
// E-mail address of the sender: as the form field is a text field,
// all instances of \r and \n have been automatically stripped from it.
- $from = $form_state['values']['mail'];
-
- // Compose the body:
- $message[] = t("!name sent a message using the contact form at !form.", array('!name' => $form_state['values']['name'], '!form' => url($_GET['q'], array('absolute' => TRUE))));
- $message[] = $form_state['values']['message'];
-
- // Load the category information:
- $contact = db_fetch_object(db_query("SELECT * FROM {contact} WHERE cid = %d", $form_state['values']['cid']));
-
- // Format the category:
- $subject = t('[!category] !subject', array('!category' => $contact->category, '!subject' => $form_state['values']['subject']));
-
- // Prepare the body:
- $body = drupal_wrap_mail(implode("\n\n", $message));
-
- // Send the e-mail to the recipients:
- drupal_mail('contact-page-mail', $contact->recipients, $subject, $body, $from);
-
- // If the user requests it, send a copy.
- if ($form_state['values']['copy']) {
- drupal_mail('contact-page-copy', $from, $subject, $body, $from);
+ $from = $values['mail'];
+
+ // Load category properties and save form values for email composition.
+ $contact = db_fetch_object(db_query("SELECT * FROM {contact} WHERE cid = %d", $values['cid']));
+ $values['contact'] = $contact;
+
+ // Send the e-mail to the recipients using the site default language.
+ drupal_mail('contact', 'page_mail', $contact->recipients, language_default(), $values, $from);
+
+ // If the user requests it, send a copy using the current language.
+ if ($values['copy']) {
+ drupal_mail('contact', 'page_copy', $from, $language, $values, $from);
}
- // Send an auto-reply if necessary:
+ // Send an auto-reply if necessary using the current language.
if ($contact->reply) {
- drupal_mail('contact-page-autoreply', $from, $subject, drupal_wrap_mail($contact->reply), $contact->recipients);
+ drupal_mail('contact', 'page_autoreply', $from, $language, $values, $contact->recipients);
}
- // Log the operation:
flood_register_event('contact');
- watchdog('mail', '%name-from sent an e-mail regarding %category.', array('%name-from' => $form_state['values']['name'] ." [$from]", '%category' => $contact->category));
-
- // Update user:
+ watchdog('mail', '%name-from sent an e-mail regarding %category.', array('%name-from' => $values['name'] ." [$from]", '%category' => $contact->category));
drupal_set_message(t('Your message has been sent.'));
- // Jump to home page rather than back to contact page to avoid contradictory messages if flood control has been activated.
+ // Jump to home page rather than back to contact page to avoid
+ // contradictory messages if flood control has been activated.
$form_state['redirect'] = '';
- return;
+}
+
+/**
+ * Implementation of hook_mail().
+ */
+function contact_mail($key, &$message, $params) {
+ $language = $message['language'];
+ switch ($key) {
+ case 'page_mail':
+ case 'page_copy':
+ $contact = $params['contact'];
+ $message['subject'] .= t('[!category] !subject', array('!category' => $contact->category, '!subject' => $params['subject']), $language->language);
+ $message['body'][] = t("!name sent a message using the contact form at !form.", array('!name' => $params['name'], '!form' => url($_GET['q'], array('absolute' => TRUE, 'language' => $language))), $language->language);
+ $message['body'][] = $params['message'];
+ break;
+ case 'page_autoreply':
+ $contact = $params['contact'];
+ $message['subject'] .= t('[!category] !subject', array('!category' => $contact->category, '!subject' => $params['subject']), $language->language);
+ $message['body'][] = $contact->reply;
+ break;
+ case 'user_mail':
+ case 'user_copy':
+ $user = $params['user'];
+ $account = $params['account'];
+ $message['subject'] .= '['. variable_get('site_name', 'Drupal') .'] '. $params['subject'];
+ $message['body'][] = "$account->name,";
+ $message['body'][] = t("!name (!name-url) has sent you a message via your contact form (!form-url) at !site.", array('!name' => $user->name, '!name-url' => url("user/$user->uid", array('absolute' => TRUE, 'language' => $language)), '!form-url' => url($_GET['q'], array('absolute' => TRUE, 'language' => $language)), '!site' => variable_get('site_name', 'Drupal')), $language->language);
+ $message['body'][] = t("If you don't want to receive such e-mails, you can change your settings at !url.", array('!url' => url("user/$account->uid", array('absolute' => TRUE, 'language' => $language))), $language->language);
+ $message['body'][] = t('Message:', NULL, $language->language);
+ $message['body'][] = $params['message'];
+ break;
+ }
}
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index f0ab48650..55f980795 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -190,25 +190,33 @@ function locale_locale($op = 'groups') {
* Implementation of hook_user().
*/
function locale_user($type, $edit, &$user, $category = NULL) {
- if ($type == 'form' && $category == 'account' && variable_get('language_count', 1) > 1 && variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) == LANGUAGE_NEGOTIATION_PATH) {
+ global $language;
+
+ // If we have more then one language and either creating a user on the
+ // admin interface or edit the user, show the language selector.
+ if (variable_get('language_count', 1) > 1 && ($type == 'register' && user_access('administer users') || $type == 'form' && $category == 'account' )) {
$languages = language_list('enabled');
$languages = $languages['1'];
- if ($user->language == '') {
- $user->language = language_default('language');
- }
+
+ // If the user is being created, we set the user language to the page language.
+ $user_language = $user ? user_language($user) : $language;
+
$names = array();
foreach ($languages as $langcode => $language) {
$names[$langcode] = t($language->name) .' ('. $language->native .')';
}
- $form['locale'] = array('#type' => 'fieldset',
- '#title' => t('Interface language settings'),
+ $form['locale'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Language settings'),
'#weight' => 1,
);
- $form['locale']['language'] = array('#type' => 'radios',
+
+ $form['locale']['language'] = array(
+ '#type' => 'radios',
'#title' => t('Language'),
- '#default_value' => $user->language,
+ '#default_value' => $user_language->language,
'#options' => $names,
- '#description' => t('Selecting a different locale will change the interface language of the site.'),
+ '#description' => t('Sets the default site interface and e-mail language for this account.'),
);
return $form;
}
diff --git a/modules/user/user.module b/modules/user/user.module
index baab4e935..ca867d1be 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -1232,9 +1232,11 @@ function user_pass_validate($form, &$form_state) {
}
function user_pass_submit($form, &$form_state) {
+ global $language;
+
$account = $form_state['values']['account'];
- // Mail one time login URL and instructions.
- $mail_success = _user_mail_notify('password_reset', $account);
+ // Mail one time login URL and instructions using current language.
+ $mail_success = _user_mail_notify('password_reset', $account, $language);
if ($mail_success) {
watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail));
drupal_set_message(t('Further instructions have been sent to your e-mail address.'));
@@ -1420,12 +1422,14 @@ function user_register_submit($form, &$form_state) {
return;
}
else {
+ // Add plain text password into user account to generate mail tokens.
+ $account->password = $pass;
if ($admin && !$notify) {
drupal_set_message(t('Created a new user account for <a href="@url">%name</a>. No e-mail has been sent.', array('@url' => url("user/$account->uid"), '%name' => $account->name)));
}
else if (!variable_get('user_email_verification', TRUE) && $account->status && !$admin) {
// No e-mail verification is required, create new user account, and login user immediately.
- _user_mail_notify('register_no_approval_required', $account, $pass);
+ _user_mail_notify('register_no_approval_required', $account);
user_authenticate($account->name, trim($pass));
$form_state['redirect'] = '';
return;
@@ -1433,7 +1437,7 @@ function user_register_submit($form, &$form_state) {
else if ($account->status || $notify) {
// Create new user account, no administrator approval required.
$op = $notify ? 'register_admin_created' : 'register_no_approval_required';
- _user_mail_notify($op, $account, $pass);
+ _user_mail_notify($op, $account);
if ($notify) {
drupal_set_message(t('Password and further instructions have been e-mailed to the new user <a href="@url">%name</a>.', array('@url' => url("user/$account->uid"), '%name' => $account->name)));
}
@@ -1445,7 +1449,7 @@ function user_register_submit($form, &$form_state) {
}
else {
// Create new user account, administrator approval required.
- _user_mail_notify('register_pending_approval', $account, $pass);
+ _user_mail_notify('register_pending_approval', $account);
drupal_set_message(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, your password and further instructions have been sent to your e-mail address.'));
}
@@ -1704,49 +1708,68 @@ function user_build_content($account) {
return $account->content;
}
-/*** Administrative features ***********************************************/
+/**
+ * Implementation of hook_mail().
+ */
+function user_mail($key, &$message, $params) {
+ $language = $message['language'];
+ $variables = user_mail_tokens($params['account'], $language);
+ $message['subject'] .= _user_mail_text($key. '_subject', $language, $variables);
+ $message['body'][] = _user_mail_text($key. '_body', $language, $variables);
+}
-function _user_mail_text($messageid, $variables = array()) {
+/**
+ * Returns a mail string for a variable name.
+ *
+ * Used by user_mail() and the settings forms to retrieve strings.
+ */
+function _user_mail_text($key, $language = NULL, $variables = array()) {
+ $langcode = isset($language) ? $language->language : NULL;
- // Check if an admin setting overrides the default string.
- if ($admin_setting = variable_get('user_mail_'. $messageid, FALSE)) {
+ if ($admin_setting = variable_get('user_mail_'. $key, FALSE)) {
+ // An admin setting overrides the default string.
return strtr($admin_setting, $variables);
}
- // No override, return with default strings.
else {
- switch ($messageid) {
+ // No override, return default string.
+ switch ($key) {
case 'register_no_approval_required_subject':
- return t('Account details for !username at !site', $variables);
+ return t('Account details for !username at !site', $variables, $langcode);
case 'register_no_approval_required_body':
- return t("!username,\n\nThank you for registering at !site. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n-- !site team", $variables);
+ return t("!username,\n\nThank you for registering at !site. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n-- !site team", $variables, $langcode);
case 'register_admin_created_subject':
- return t('An administrator created an account for you at !site', $variables);
+ return t('An administrator created an account for you at !site', $variables, $langcode);
case 'register_admin_created_body':
- return t("!username,\n\nA site administrator at !site has created an account for you. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n-- !site team", $variables);
+ return t("!username,\n\nA site administrator at !site has created an account for you. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n-- !site team", $variables, $langcode);
case 'register_pending_approval_subject':
- return t('Account details for !username at !site (pending admin approval)', $variables);
+ case 'pending_approval_admin_subject':
+ return t('Account details for !username at !site (pending admin approval)', $variables, $langcode);
case 'register_pending_approval_body':
- return t("!username,\n\nThank you for registering at !site. Your application for an account is currently pending approval. Once it has been approved, you will receive another e-mail containing information about how to log in, set your password, and other details.\n\n\n-- !site team", $variables);
+ return t("!username,\n\nThank you for registering at !site. Your application for an account is currently pending approval. Once it has been approved, you will receive another e-mail containing information about how to log in, set your password, and other details.\n\n\n-- !site team", $variables, $langcode);
+ case 'register_pending_approval_admin_body':
+ return t("!username has applied for an account.\n\n!edit_uri", $variables, $langcode);
case 'password_reset_subject':
- return t('Replacement login information for !username at !site', $variables);
+ return t('Replacement login information for !username at !site', $variables, $langcode);
case 'password_reset_body':
- return t("!username,\n\nA request to reset the password for your account has been made at !site.\n\nYou may now log in to !uri_brief clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.", $variables);
+ return t("!username,\n\nA request to reset the password for your account has been made at !site.\n\nYou may now log in to !uri_brief clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.", $variables, $langcode);
case 'status_activated_subject':
- return t('Account details for !username at !site (approved)', $variables);
+ return t('Account details for !username at !site (approved)', $variables, $langcode);
case 'status_activated_body':
- return "!username,\n\nYour account at !site has been activated.\n\nYou may now log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\nOnce you have set your own password, you will be able to log in to !login_uri in the future using the following username:\n\nusername: !username\n";
+ return t("!username,\n\nYour account at !site has been activated.\n\nYou may now log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\nOnce you have set your own password, you will be able to log in to !login_uri in the future using the following username:\n\nusername: !username\n", $variables, $langcode);
case 'status_blocked_subject':
- return t('Account details for !username at !site (blocked)', $variables);
+ return t('Account details for !username at !site (blocked)', $variables, $langcode);
case 'status_blocked_body':
- return "!username,\n\nYour account on !site has been blocked.";
+ return t("!username,\n\nYour account on !site has been blocked.", $variables, $langcode);
case 'status_deleted_subject':
- return t('Account details for !username at !site (deleted)', $variables);
+ return t('Account details for !username at !site (deleted)', $variables, $langcode);
case 'status_deleted_body':
- return "!username,\n\nYour account on !site has been deleted.";
+ return t("!username,\n\nYour account on !site has been deleted.", $variables, $langcode);
}
}
}
+/*** Administrative features ***********************************************/
+
function user_admin_check_user() {
$form['user'] = array('#type' => 'fieldset', '#title' => t('Username'));
$form['user']['test'] = array('#type' => 'textfield', '#title' => '', '#description' => t('Enter a username to check if it will be denied or allowed.'), '#size' => 30, '#maxlength' => USERNAME_MAX_LENGTH);
@@ -3090,12 +3113,12 @@ function theme_user_signature($signature) {
* @param $account
* The user object of the account being notified. Must contain at
* least the fields 'uid', 'name', and 'mail'.
- * @param $password
- * Optional string containing the user's current password (if known).
+ * @param $language
+ * Language object to generate the tokens with.
* @return
* Array of mappings from token names to values (for use with strtr()).
*/
-function user_mail_tokens($account, $password = NULL) {
+function user_mail_tokens($account, $language) {
global $base_url;
$tokens = array(
'!username' => $account->name,
@@ -3104,17 +3127,40 @@ function user_mail_tokens($account, $password = NULL) {
'!uri' => $base_url,
'!uri_brief' => substr($base_url, strlen('http://')),
'!mailto' => $account->mail,
- '!date' => format_date(time()),
- '!login_uri' => url('user', array('absolute' => TRUE)),
- '!edit_uri' => url('user/'. $account->uid .'/edit', array('absolute' => TRUE)),
+ '!date' => format_date(time(), 'medium', '', NULL, $language->language),
+ '!login_uri' => url('user', array('absolute' => TRUE, 'language' => $language)),
+ '!edit_uri' => url('user/'. $account->uid .'/edit', array('absolute' => TRUE, 'language' => $language)),
);
- if (!empty($password)) {
- $tokens['!password'] = $password;
+ if (!empty($account->password)) {
+ $tokens['!password'] = $account->password;
}
return $tokens;
}
/**
+ * Get the language object preferred by the user. This user preference can
+ * be set on the user account editing page, and is only available if there
+ * are more than one languages enabled on the site. If the user did not
+ * choose a preferred language, or is the anonymous user, the $default
+ * value, or if it is not set, the site default language will be returned.
+ *
+ * @param $account
+ * User account to look up language for.
+ * @param $default
+ * Optional default language object to return if the account
+ * has no valid language.
+ */
+function user_preferred_language($account, $default = NULL) {
+ $language_list = language_list();
+ if ($account->language && isset($language_list[$account->language])) {
+ return $language_list[$account->language];
+ }
+ else {
+ return $default ? $default : language_default();
+ }
+}
+
+/**
* Conditionally create and send a notification email when a certain
* operation happens on the given user account.
*
@@ -3134,36 +3180,26 @@ function user_mail_tokens($account, $password = NULL) {
* @param $account
* The user object of the account being notified. Must contain at
* least the fields 'uid', 'name', and 'mail'.
- *
- * @param $password
- * Optional string containing the user's current password (if known).
- *
+ * @param $language
+ * Optional language to use for the notification, overriding account language.
* @return
- * The return value from drupal_mail(), if ends up being called.
+ * The return value from drupal_mail_send(), if ends up being called.
*/
-function _user_mail_notify($op, $account, $password = NULL) {
- $mail_id = 'user-'. strtr($op, '_', '-');
- if ($op == 'register_pending_approval') {
- // Special case, since we need to distinguish what we send to the
- // user and what we send to the administrator, handled below.
- $mail_id .= '-user';
- }
+function _user_mail_notify($op, $account, $language = NULL) {
// By default, we always notify except for deleted and blocked.
$default_notify = ($op != 'status_deleted' && $op != 'status_blocked');
$notify = variable_get('user_mail_'. $op .'_notify', $default_notify);
- $result = NULL;
if ($notify) {
- $from = variable_get('site_mail', ini_get('sendmail_from'));
- $variables = user_mail_tokens($account, $password);
- $subject = _user_mail_text($op .'_subject', $variables);
- $body = drupal_wrap_mail(_user_mail_text($op .'_body', $variables));
- $result = drupal_mail($mail_id, $account->mail, $subject, $body, $from);
+ $params['account'] = $account;
+ $language = $language ? $language : user_preferred_language($account);
+ $mail = drupal_mail('user', $op, $account->mail, $language, $params);
if ($op == 'register_pending_approval') {
// If a user registered requiring admin approval, notify the admin, too.
- drupal_mail('user-register-approval-admin', $from, $subject, t("!username has applied for an account.\n\n!edit_uri", $variables), $from);
+ // We use the site default language for this.
+ drupal_mail('user', 'register_pending_approval_admin', variable_get('site_mail', ini_get('sendmail_from')), language_default(), $params);
}
}
- return $result;
+ return empty($mail) ? NULL : $mail['result'];
}
/**