Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.641
diff -u -r1.641 common.inc
--- includes/common.inc 15 May 2007 20:19:47 -0000 1.641
+++ includes/common.inc 20 May 2007 01:00:35 -0000
@@ -747,6 +747,87 @@
}
/**
+ * Text replacement with deferred localization
+ *
+ * It can be used for the same base text to be localized to multiple languages
+ * or when the language is not yet known when composing the text.
+ *
+ * Example
+ * - This will print the same message in all available languages
+ *
+ * @code
+ * // This first line will be localized with the username parameter
+ * $text[] = array('Hello !username,', array('!username' => $user->name));
+ * // This will be also localized, but the !content_type string has to be replaced later
+ * $text[] = array('A new !content_type has been posted to !site_name:');
+ * // Simple string, won't be localized
+ * $text[] = $node->title
+ *
+ * // Variables for replacement
+ * $args['!site_name'] => variable_get('site_name', 'Drupal'); // Simple text, won't be localized
+ * $args['!content_type'] => array($node->type); // Array, will be localized
+ *
+ * // We have composed the base text, now it will be localized and printed for each language
+ * foreach (language_list() as $language) {
+ * $output .= '
'. $language->name.'
';
+ * $output .= tt($text, $args, $language->language);
+ * }
+ * @endcode
+ *
+ * @param $text
+ * Plain text or array of text lines
+ * @param $args
+ * Optional associative array of replacements to make after translation.
+ * * Array keys are placeholders, like in t() function
+ * * Array values may be simple strings or an array with string and arguments when it must be localized
+ * @param $langcode
+ * Language code for localization
+ * @param $wrap
+ * Optional, TRUE for wrapping each text line
+ * @param $endline
+ * Optional string for end of each line
+ * @return
+ * Text localized and formatted with variable replacement
+ */
+function tt($text, $args = array(), $langcode = NULL, $wrap = FALSE, $endline = "\n") {
+ // If plain text, convert to array
+ $text = is_array($text) ? $text : array($text);
+
+ // Prepare arguments for replacement
+ // This replacement also supports localization
+ foreach ($args as $key => $value) {
+ // If value is an array, it means it must go through localization
+ $value = is_array($value) ? t(array_shift($value), array_shift($value), $langcode) : $value;
+ switch ($key[0]) {
+ // Escaped only
+ case '@':
+ $args[$key] = check_plain($value);
+ break;
+ // Escaped and placeholder
+ case '%':
+ default:
+ $args[$key] = theme('placeholder', $value);
+ break;
+ // Pass-through
+ case '!':
+ $args[$key] = $value;
+ }
+ }
+ // Arguments have been parsed and localized
+ // Now we go with the text.
+ // Each line can be localized with its own parameters
+ foreach ($text as $key => $value) {
+ // It is an array, run through localization with optional parameters
+ $text[$key] = is_array($value) ? t(array_shift($value), array_shift($value), $langcode) : $value;
+ if ($wrap) {
+ $text[$key] = wordwrap($text[$key]);
+ }
+ }
+ // Put the text together and final variable replacement
+ return strtr(implode($endline, $text), $args);
+}
+
+/**
* @defgroup validation Input validation
* @{
* Functions to validate user input.
Index: modules/contact/contact.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.module,v
retrieving revision 1.84
diff -u -r1.84 contact.module
--- modules/contact/contact.module 14 May 2007 13:43:35 -0000 1.84
+++ modules/contact/contact.module 20 May 2007 01:00:36 -0000
@@ -364,33 +364,36 @@
$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[] = "!name-from,";
+ $message[] = array("!name-from (!name-from-url) has sent you a message via your contact form (!form-url) at !site.");
+ $message[] = array("If you don't want to receive such e-mails, you can change your settings at !url.");
+ $message[] = array('Message:');
$message[] = $form_values['message'];
- // Tidy up the body:
- foreach ($message as $key => $value) {
- $message[$key] = wordwrap($value);
- }
-
// Prepare all fields:
$to = $account->mail;
$from = $user->mail;
// Format the subject:
- $subject = '['. variable_get('site_name', 'Drupal') .'] '. $form_values['subject'];
-
- // Prepare the body:
- $body = implode("\n\n", $message);
-
+ $subject = '[!site-name] @subject';
+
+ // Prepare variables for replacement
+ $variables = array(
+ '!name-from' => $user->name,
+ '!name-to' => $account->name,
+ '!name-from-url' => url("user/$user->uid", array('absolute' => TRUE)),
+ '!form-url' => url($_GET['q'], array('absolute' => TRUE)),
+ '!site-name' => variable_get('site_name', 'Drupal'),
+ '!url' => url("user/$account->uid", array('absolute' => TRUE)),
+ '@subject' => $form_values['subject']
+ );
+
// Send the e-mail:
- drupal_mail('contact-user-mail', $to, $subject, $body, $from);
+ user_mail('contact-mail', $account, $variables, $subject, $message, $from);
// Send a copy if requested:
if ($form_values['copy']) {
- drupal_mail('contact-user-copy', $from, $subject, $body, $from);
+ user_mail('contact-copy', $user, $variables, $subject, $message, $from);
}
// Log the operation:
Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.172
diff -u -r1.172 locale.module
--- modules/locale/locale.module 15 May 2007 20:19:47 -0000 1.172
+++ modules/locale/locale.module 20 May 2007 01:00:37 -0000
@@ -186,10 +186,11 @@
* 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) {
+ // Show language field when user is editing own account and administrator is creating account
+ 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 == '') {
+ if (!$user || $user->language == '') {
$default = language_default();
$user->language = $default->language;
}
@@ -203,9 +204,9 @@
);
$form['locale']['language'] = array('#type' => 'radios',
'#title' => t('Language'),
- '#default_value' => $user->language,
+ '#default_value' => $user ? $user->language : $default->language,
'#options' => $names,
- '#description' => t('Selecting a different locale will change the interface language of the site.'),
+ '#description' => t('Selecting a locale will set the default site interface and mail language for this account.'),
);
return $form;
}
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.782
diff -u -r1.782 user.module
--- modules/user/user.module 17 May 2007 21:33:59 -0000 1.782
+++ modules/user/user.module 20 May 2007 01:00:40 -0000
@@ -1192,16 +1192,13 @@
}
function user_pass_submit($form_values, $form, &$form_state) {
- global $base_url;
$account = $form_values['account'];
- $from = variable_get('site_mail', ini_get('sendmail_from'));
// Mail one time login URL and instructions.
- $variables = array('!username' => $account->name, '!site' => variable_get('site_name', 'Drupal'), '!login_url' => user_pass_reset_url($account), '!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)));
- $subject = _user_mail_text('pass_subject', $variables);
- $body = _user_mail_text('pass_body', $variables);
- $mail_success = drupal_mail('user-pass', $account->mail, $subject, $body, $from);
+ $variables = array('!login_url' => user_pass_reset_url($account));
+
+ $mail_success = user_mail('pass', $account, $variables);
if ($mail_success) {
watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail));
@@ -1216,6 +1213,63 @@
}
/**
+ * Send an e-mail message to a user, using Drupal variables and default settings.
+ * This function automatically provides subject and body for known user e-mails
+ *
+ * @param $key
+ * A key to identify the mail sent. The mailkey for altering will be 'user-' + $key
+ * @param $account
+ * User account to which the e-mail will be sent.
+ * @param $subject
+ * Optional 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
+ * Optional message to be sent. Drupal will format the correct line endings for you.
+ * @param $from
+ * Optional mail to set From, Reply-To, Return-Path and Error-To to this value.
+ * @param $headers
+ * Optional associative array containing the headers to add. This is typically
+ * used to add extra headers (From, Cc, and Bcc).
+ * When sending mail, the mail must contain a From header.
+ * @return
+ * Returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise.
+ */
+function user_mail($key, $account, $variables = array(), $subject = '', $body = '', $from = NULL, $headers = array()) {
+ global $base_url;
+
+ // Add standard variables
+ $variables += array('!username' => $account->name, '!site' => variable_get('site_name', 'Drupal'), '!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)));
+
+ // Get the language code for this user account
+ $langcode = user_language($account);
+
+ // Build the e-mail if no subject and body has been passed
+ $subject = $subject ? tt($subject, $variables, $langcode) : _user_mail_text($key.'_subject', $variables, $langcode);
+ $body = $body ? tt($body, $variables, $langcode, TRUE, "\n\n") : _user_mail_text($key.'_body', $variables, $langcode);
+ $from = $from ? $from : variable_get('site_mail', ini_get('sendmail_from'));
+
+ return drupal_mail('user-'.$key, $account->mail, $subject, $body, $from, $headers);
+}
+
+function _user_mail_localize($text) {
+
+}
+/**
+ * Returns user language code for notifications
+ *
+ * @param $account
+ * Optional user account
+ */
+function user_language($account = NULL) {
+ global $user;
+
+ $account = isset($account) ? $account : $user;
+ $default = language_default();
+ // The user language will be the site default if no language is set for the account.
+ return (isset($account->language) && $account->language) ? $account->language : $default->language;
+}
+
+/**
* Menu callback; process one time login link and redirects to the user page on success.
*/
function user_pass_reset($uid, $timestamp, $hashed_pass, $action = NULL) {
@@ -1341,7 +1395,6 @@
}
function user_register_submit($form_values, $form, &$form_state) {
- global $base_url;
$admin = user_access('administer users');
$mail = $form_values['mail'];
@@ -1353,7 +1406,7 @@
$pass = user_password();
};
$notify = isset($form_values['notify']) ? $form_values['notify'] : NULL;
- $from = variable_get('site_mail', ini_get('sendmail_from'));
+
if (isset($form_values['roles'])) {
$roles = array_filter($form_values['roles']); // Remove unset roles
}
@@ -1379,7 +1432,7 @@
watchdog('user', 'New user: %name (%email).', array('%name' => $name, '%email' => $mail), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
- $variables = array('!username' => $name, '!site' => variable_get('site_name', 'Drupal'), '!password' => $pass, '!uri' => $base_url, '!uri_brief' => substr($base_url, strlen('http://')), '!mailto' => $mail, '!date' => format_date(time()), '!login_uri' => url('user', array('absolute' => TRUE)), '!edit_uri' => url('user/'. $account->uid .'/edit', array('absolute' => TRUE)), '!login_url' => user_pass_reset_url($account));
+ $variables = array('!password' => $pass, '!mailto' => $mail, '!login_url' => user_pass_reset_url($account));
// The first user may login immediately, and receives a customized welcome e-mail.
if ($account->uid == 1) {
@@ -1399,19 +1452,14 @@
}
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.
- $subject = _user_mail_text('welcome_subject', $variables);
- $body = _user_mail_text('welcome_body', $variables);
- drupal_mail('user-register-welcome', $mail, $subject, $body, $from);
+ user_mail('welcome', $account);
user_authenticate($account->name, trim($pass));
$form_state['redirect'] = '';
return;
}
else if ($account->status || $notify) {
// Create new user account, no administrator approval required.
- $subject = $notify ? _user_mail_text('admin_subject', $variables) : _user_mail_text('welcome_subject', $variables);
- $body = $notify ? _user_mail_text('admin_body', $variables) : _user_mail_text('welcome_body', $variables);
-
- drupal_mail(($notify ? 'user-register-notify' : 'user-register-welcome'), $mail, $subject, $body, $from);
+ user_mail(($notify ? 'admin' : 'welcome'), $account);
if ($notify) {
drupal_set_message(t('Password and further instructions have been e-mailed to the new user %user.', array('%user' => $name)));
@@ -1424,11 +1472,8 @@
}
else {
// Create new user account, administrator approval required.
- $subject = _user_mail_text('approval_subject', $variables);
- $body = _user_mail_text('approval_body', $variables);
-
- drupal_mail('user-register-approval-user', $mail, $subject, $body, $from);
- drupal_mail('user-register-approval-admin', $from, $subject, t("!username has applied for an account.\n\n!edit_uri", $variables), $from);
+ user_mail('approval', $account, $variables);
+ user_mail('approval-admin', user_load(1), $variables);
drupal_set_message(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.
In the meantime, your password and further instructions have been sent to your e-mail address.'));
}
@@ -1679,7 +1724,7 @@
/*** Administrative features ***********************************************/
-function _user_mail_text($messageid, $variables = array()) {
+function _user_mail_text($messageid, $variables = array(), $langcode = NULL) {
// Check if an admin setting overrides the default string.
if ($admin_setting = variable_get('user_mail_'. $messageid, FALSE)) {
@@ -1689,21 +1734,23 @@
else {
switch ($messageid) {
case 'welcome_subject':
- return t('Account details for !username at !site', $variables);
+ return t('Account details for !username at !site', $variables, $langcode);
case 'welcome_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 'admin_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 'admin_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 'approval_subject':
- return t('Account details for !username at !site (pending admin approval)', $variables);
+ return t('Account details for !username at !site (pending admin approval)', $variables, $langcode);
case '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 granted, you may 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 may wish to change your password at !edit_uri\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 granted, you may 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 may wish to change your password at !edit_uri\n\n\n-- !site team", $variables, $langcode);
case 'pass_subject':
- return t('Replacement login information for !username at !site', $variables);
+ return t('Replacement login information for !username at !site', $variables, $langcode);
case 'pass_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 'approval-admin_subject':
+ return t("!username has applied for an account.\n\n!edit_uri", $variables, $langcode);
}
}
}