Index: modules/contact/contact.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.admin.inc,v retrieving revision 1.3 diff -u -p -r1.3 contact.admin.inc --- modules/contact/contact.admin.inc 9 Nov 2007 07:55:13 -0000 1.3 +++ modules/contact/contact.admin.inc 7 Apr 2008 04:15:14 -0000 @@ -166,7 +166,7 @@ function contact_admin_settings() { $form['contact_default_status'] = array( '#type' => 'checkbox', '#title' => t('Enable personal contact form by default'), - '#default_value' => variable_get('contact_default_status', 1), + '#default_value' => variable_get('contact_default_status', CONTACT_BY_AUTH), '#description' => t('Default status of the personal contact form for new users.'), ); return system_settings_form($form); Index: modules/contact/contact.module =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.module,v retrieving revision 1.104 diff -u -p -r1.104 contact.module --- modules/contact/contact.module 20 Feb 2008 13:46:39 -0000 1.104 +++ modules/contact/contact.module 7 Apr 2008 04:15:14 -0000 @@ -7,6 +7,20 @@ */ /** + * @name Contact flags + * @{ + * Flags for use in access to contact forms. + */ + +define('CONTACT_BY_AUTH', 0x0001); +define('CONTACT_BY_ANON', 0x0002); +define('CONTACT_BY_BOTH', CONTACT_BY_AUTH | CONTACT_BY_ANON); + +/** + * @} + */ + +/** * Implementation of hook_help(). */ function contact_help($path, $arg) { @@ -39,6 +53,7 @@ function contact_perm() { return array( 'access site-wide contact form' => t('Send feedback to administrators via e-mail using the site-wide contact form.'), 'administer site-wide contact form' => t('Configure site-wide contact form administration settings.'), + 'access personal contact forms' => t('Send users a message via e-mail using their contact form.'), ); } @@ -115,12 +130,13 @@ function contact_menu() { function _contact_user_tab_access($account) { global $user; if (!isset($account->contact)) { - $account->contact = FALSE; + $account->contact = 0; } return - $account && $user->uid && + $account && user_access('access personal contact forms') && ( - ($user->uid != $account->uid && $account->contact) || + ($user->uid && $user->uid != $account->uid && ($account->contact & CONTACT_BY_AUTH)) || // Access by authenticated users only. + ($user->uid != $account->uid && ($account->contact & CONTACT_BY_ANON)) || // Access by authenticated and anonymous users. user_access('administer users') ); } @@ -134,6 +150,13 @@ function contact_load($cid) { } /** + * Implementation of hook_enable(). + */ +function contact_enable() { + drupal_set_message(t('If you are allowing anonymous users access to personal contact forms, be sure to provide adequate protection against malicious use by spam bots.'), 'error'); +} + +/** * Implementation of hook_user(). * * Allows the user the option of enabling/disabling his personal contact form. @@ -145,10 +168,11 @@ function contact_user($type, &$edit, &$u '#weight' => 5, '#collapsible' => TRUE, ); - $form['contact']['contact'] = array('#type' => 'checkbox', + $form['contact']['contact'] = array('#type' => 'radios', '#title' => t('Personal contact form'), '#default_value' => !empty($edit['contact']) ? $edit['contact'] : FALSE, - '#description' => t('Allow other users to contact you by e-mail via your personal contact form. Note that while your e-mail address is not made public to other members of the community, privileged users such as site administrators are able to contact you even if you choose not to enable this feature.', array('@url' => url("user/$user->uid/contact"))), + '#description' => t('Allow other users to contact you by e-mail via your personal contact form. Note that while your e-mail address is not made public to other members of the community, privileged users such as site administrators are able to contact you even if you choose the first option.', array('@url' => url("user/$user->uid/contact"))), + '#options' => _contact_user_form_options(), ); return $form; } @@ -156,11 +180,24 @@ function contact_user($type, &$edit, &$u return array('contact' => isset($edit['contact']) ? $edit['contact'] : FALSE); } elseif ($type == 'insert') { - $edit['contact'] = variable_get('contact_default_status', 1); + $edit['contact'] = variable_get('contact_default_status', CONTACT_BY_AUTH); } } /** + * Builds array for personal contact form options. + */ +function _contact_user_form_options() { + $anon = user_load(0); + $options[0] = t('Do not allow access to my personal contact form except for site administrators.'); + $options[CONTACT_BY_AUTH] = t('Registered users with appropriate permissions can contact me via my personal contact form.'); + if (user_access('access personal contact forms', $anon)) { + $options[CONTACT_BY_BOTH] = t('Anonymous users and registered users with appropriate permissions can contact me via my personal contact form.'); + } + return $options; +} + +/** * Implementation of hook_mail(). */ function contact_mail($key, &$message, $params) { @@ -180,11 +217,16 @@ function contact_mail($key, &$message, $ 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); + if (!empty($params['user'])) { + $user = $params['user']; + $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); + } + else { + $message['body'][] = t("!name has sent you a message via your contact form (!form-url) at !site.", array('!name' => $params['name'], '!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']; Index: modules/contact/contact.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.pages.inc,v retrieving revision 1.8 diff -u -p -r1.8 contact.pages.inc --- modules/contact/contact.pages.inc 25 Mar 2008 14:07:34 -0000 1.8 +++ modules/contact/contact.pages.inc 7 Apr 2008 04:15:14 -0000 @@ -23,6 +23,9 @@ function contact_site_page() { return $output; } +/** + * Generates the site-wide contact form. + */ function contact_mail_page() { global $user; @@ -88,9 +91,6 @@ function contact_mail_page() { '#title' => t('Send yourself a copy.'), ); } - else { - $form['copy'] = array('#type' => 'value', '#value' => FALSE); - } $form['submit'] = array('#type' => 'submit', '#value' => t('Send e-mail'), ); @@ -157,7 +157,7 @@ function contact_mail_page_submit($form, function contact_user_page($account) { global $user; - if (!valid_email_address($user->mail)) { + if ($user->uid && !valid_email_address($user->mail)) { $output = t('You need to provide a valid e-mail address to contact other users. Please update your user information and try again.', array('@url' => url("user/$user->uid/edit"))); } else if (!flood_is_allowed('contact', variable_get('contact_hourly_threshold', 3)) && !user_access('administer site-wide contact form')) { @@ -173,12 +173,27 @@ function contact_user_page($account) { function contact_mail_user(&$form_state, $recipient) { global $user; - $form['#token'] = $user->name . $user->mail; $form['recipient'] = array('#type' => 'value', '#value' => $recipient); - $form['from'] = array('#type' => 'item', - '#title' => t('From'), - '#value' => check_plain($user->name) .' <'. check_plain($user->mail) .'>', - ); + if ($user->uid) { + $form['#token'] = $user->name . $user->mail; + $form['from'] = array('#type' => 'item', + '#title' => t('From'), + '#value' => check_plain($user->name) .' <'. check_plain($user->mail) .'>', + ); + } + else { + $form['#token'] = $recipient->name . $recipient->mail; + $form['name'] = array('#type' => 'textfield', + '#title' => t('Your name'), + '#maxlength' => 255, + '#required' => TRUE, + ); + $form['mail'] = array('#type' => 'textfield', + '#title' => t('Your e-mail address'), + '#maxlength' => 255, + '#required' => TRUE, + ); + } $form['to'] = array('#type' => 'item', '#title' => t('To'), '#value' => check_plain($recipient->name), @@ -193,9 +208,13 @@ function contact_mail_user(&$form_state, '#rows' => 15, '#required' => TRUE, ); - $form['copy'] = array('#type' => 'checkbox', - '#title' => t('Send yourself a copy.'), - ); + // Do not allow anonymous users to send themselves a copy + // because it can be abused by spammers. + if ($user->uid) { + $form['copy'] = array('#type' => 'checkbox', + '#title' => t('Send yourself a copy.'), + ); + } $form['submit'] = array('#type' => 'submit', '#value' => t('Send e-mail'), ); @@ -203,6 +222,17 @@ function contact_mail_user(&$form_state, } /** + * Validate the personal contact page form submission. + */ +function contact_mail_user_validate($form, &$form_state) { + global $user; + + if (!$user->uid && !valid_email_address($form_state['values']['mail'])) { + form_set_error('mail', t('You must enter a valid e-mail address.')); + } +} + +/** * Process the personal contact page form submission. */ function contact_mail_user_submit($form, &$form_state) { @@ -212,23 +242,38 @@ function contact_mail_user_submit($form, // Send from the current user to the requested user. $to = $account->mail; - $from = $user->mail; + if ($user->uid) { + $from = $user->mail; + } + else { + $from = $form_state['values']['mail']; + } // Save both users and all form values for email composition. $values = $form_state['values']; $values['account'] = $account; - $values['user'] = $user; + if ($user->uid) { + $values['user'] = $user; + } + else { + $values['name'] = $form_state['values']['name']; + } // 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, using current page language. - if ($form_state['values']['copy']) { + if (isset($form_state['values']['copy'])) { drupal_mail('contact', 'user_copy', $from, $language, $values, $from); } flood_register_event('contact'); - watchdog('mail', '%name-from sent %name-to an e-mail.', array('%name-from' => $user->name, '%name-to' => $account->name)); + if ($user->uid) { + watchdog('mail', '%name-from sent %name-to an e-mail.', array('%name-from' => $user->name, '%name-to' => $account->name)); + } + else { + watchdog('mail', t('%name-from sent %name-to an e-mail.', array('%name-from' => $form_state['values']['name'] . ', ' . $form_state['values']['mail'] . ',', '%name-to' => $account->name))); + } drupal_set_message(t('The message has been sent.')); // Back to the requested users profile page.