? sites/default/files ? sites/default/settings.php Index: modules/contact/contact.module =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.module,v retrieving revision 1.112 diff -u -p -r1.112 contact.module --- modules/contact/contact.module 8 Mar 2009 05:08:22 -0000 1.112 +++ modules/contact/contact.module 28 Apr 2009 11:36:31 -0000 @@ -23,7 +23,7 @@ function contact_help($path, $arg) { $output = '
' . t('This page lets you set up your site-wide contact form. To do so, add one or more categories. You can associate different recipients with each category to route e-mails to different people. For example, you can route website feedback to the webmaster and direct product information requests to the sales department. On the settings page, you can customize the information shown above the contact form. This can be useful to provide additional contact information such as your postal address and telephone number.', array('@settings' => url('admin/build/contact/settings'), '@form' => url('contact'))) . '
'; if (!module_exists('menu')) { $menu_note = t('The menu item can be customized and configured only once the menu module has been enabled.', array('@modules-page' => url('admin/settings/modules'))); - } + } else { $menu_note = ''; } @@ -45,6 +45,10 @@ function contact_perm() { 'title' => t('Access site-wide contact form'), 'description' => t('Send feedback to administrators via e-mail using the site-wide contact form.'), ), + 'access personal contact form' => array( + 'title' => t('Access personal contact form'), + 'description' => t('Send e-mail to registered users via their personal contact form.'), + ), ); } @@ -116,15 +120,27 @@ function contact_menu() { */ function _contact_user_tab_access($account) { global $user; - if (!isset($account->contact)) { - $account->contact = FALSE; + + // User administrators always have access to the contact form. + if (user_access('administer users')) { + return TRUE; } - return - $account && $user->uid && - ( - ($user->uid != $account->uid && $account->contact) || - user_access('administer users') - ); + + // Do not show the contact form when it is turned off. + if (!isset($account->contact) || $account->contact == 0) { + return FALSE; + } + + // Do not show the form if the user is not allowed to access it. + if (!user_access('access personal contact form')) { + return FALSE; + } + else { + return TRUE; + } + + // For privacy, do not show the contact form by default. + return FALSE; } /** @@ -141,15 +157,11 @@ function contact_load($cid) { */ function contact_user_form(&$edit, &$user, $category = NULL) { if ($category == 'account') { - $form['contact'] = array('#type' => 'fieldset', - '#title' => t('Contact settings'), - '#weight' => 5, - '#collapsible' => TRUE, - ); - $form['contact']['contact'] = array('#type' => 'checkbox', - '#title' => t('Personal contact form'), + $form['account']['contact'] = array('#type' => 'checkbox', + '#title' => t('Enable 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"))), + '#weight' => 10, ); return $form; } @@ -173,6 +185,7 @@ function contact_user_validate(&$edit, & * Implementation of hook_mail(). */ function contact_mail($key, &$message, $params) { + global $user; $language = $message['language']; switch ($key) { case 'page_mail': Index: modules/contact/contact.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.pages.inc,v retrieving revision 1.18 diff -u -p -r1.18 contact.pages.inc --- modules/contact/contact.pages.inc 26 Apr 2009 20:09:12 -0000 1.18 +++ modules/contact/contact.pages.inc 28 Apr 2009 11:36:31 -0000 @@ -154,7 +154,11 @@ function contact_mail_page_submit($form, function contact_user_page($account) { global $user; - if (!valid_email_address($user->mail)) { + if ($user->uid == 0 && $account->contact) { + drupal_set_title($account->name); + $output = drupal_get_form('contact_mail_user', $account); + } + elseif (!valid_email_address($user->mail) && !$account->contact) { $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", array('query' => 'destination=' . drupal_get_destination())))); } elseif (!flood_is_allowed('contact', variable_get('contact_hourly_threshold', 3)) && !user_access('administer site-wide contact form')) { @@ -170,64 +174,123 @@ function contact_user_page($account) { function contact_mail_user(&$form_state, $recipient) { global $user; - $form['#token'] = $user->name . $user->mail; + if (!$user->uid == 0) { + $form['#token'] = $user->name . $user->mail; + $form['from'] = array( + '#type' => 'item', + '#title' => t('From'), + '#markup' => check_plain($user->name) . ' <' . check_plain($user->mail) . '>', + ); + $form['mail'] = array( + '#type' => 'value', + '#value' => check_plain($user->mail), + ); + } + else { + $form['#token'] = 'Anonymous' . variable_get('site_mail'); + $form['from'] = array( + '#type' => 'textfield', + '#title' => t('From'), + '#maxlength' => 255, + '#required' => TRUE, + ); + $form['mail'] = array( + '#type' => 'textfield', + '#title' => t('E-mail'), + '#maxlength' => 255, + '#required' => TRUE, + ); + } $form['recipient'] = array('#type' => 'value', '#value' => $recipient); - $form['from'] = array('#type' => 'item', - '#title' => t('From'), - '#markup' => theme('username', $user) . ' <' . check_plain($user->mail) . '>', - ); $form['to'] = array('#type' => 'item', '#title' => t('To'), '#markup' => theme('username', $recipient), ); - $form['subject'] = array('#type' => 'textfield', + $form['subject'] = array( + '#type' => 'textfield', '#title' => t('Subject'), '#maxlength' => 50, '#required' => TRUE, ); - $form['message'] = array('#type' => 'textarea', + $form['message'] = array( + '#type' => 'textarea', '#title' => t('Message'), '#rows' => 15, '#required' => TRUE, ); - $form['copy'] = array('#type' => 'checkbox', - '#title' => t('Send yourself a copy.'), - ); - $form['submit'] = array('#type' => 'submit', + if ($user->uid) { + $form['copy'] = array( + '#type' => 'checkbox', + '#title' => t('Send yourself a copy.'), + ); + } + else { + drupal_add_js(drupal_get_path('module', 'contact') . '/contact.js'); + $form['copy'] = array( + '#type' => 'value', + '#value' => FALSE, + ); + } + $form['submit'] = array( + '#type' => 'submit', '#value' => t('Send e-mail'), ); return $form; } + +/** + * Validate the user contact page form submission. + */ +function contact_mail_user_validate($form, &$form_state) { + global $user; + if (!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) { global $user, $language; - $account = $form_state['values']['recipient']; + $values = $form_state['values']; + $account = $values['recipient']; // Send from the current user to the requested user. $to = $account->mail; - $from = $user->mail; + if (!$user->uid == 0) { + $from = $user->mail; + $username = $user->name; + } + else { + $from = variable_get('site_mail'); + $username = 'anonymous'; + } // Save both users and all form values for email composition. - $values = $form_state['values']; $values['account'] = $account; + if (!$user->uid) { + $user->mail = $values['mail']; + $user->name = $values['from']; + } $values['user'] = $user; // 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 ($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)); + watchdog('mail', '%name-from sent %name-to an e-mail.', array('%name-from' => $username, '%name-to' => $account->name)); drupal_set_message(t('The message has been sent.')); - // Back to the requested users profile page. - $form_state['redirect'] = "user/$account->uid"; + // Back to the requested users profile page or the homepage if the + // user does not have access to user profiles. + $form_state['redirect'] = user_access('access user profiles') ? "user/$account->uid" : ''; } Index: modules/contact/contact.test =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.test,v retrieving revision 1.19 diff -u -p -r1.19 contact.test --- modules/contact/contact.test 21 Apr 2009 09:27:52 -0000 1.19 +++ modules/contact/contact.test 28 Apr 2009 11:36:31 -0000 @@ -292,8 +292,8 @@ class ContactPersonalTestCase extends Dr // Reload variables. $this->drupalLogout(); - // Create web users and attempt to use personal contact forms with default set to true. - $web_user1 = $this->drupalCreateUser(array()); + // Must specify the new 'access personal contact form' permission. + $web_user1 = $this->drupalCreateUser(array('access personal contact form')); $web_user2 = $this->drupalCreateUser(array()); $this->drupalLogin($web_user1); @@ -306,7 +306,40 @@ class ContactPersonalTestCase extends Dr $edit['message'] = $this->randomName(64); $this->drupalPost(NULL, $edit, t('Send e-mail')); $this->assertText(t('The message has been sent.'), t('Message sent.')); + + $this->drupalLogout(); + + // Create web users and attempt to use personal contact form without + // 'access personal contact form' permissions + $web_user3 = $this->drupalCreateUser(array()); + $web_user4 = $this->drupalCreateUser(array()); + + $this->drupalLogin($web_user3); + + $this->drupalGet('user/' . $web_user4->uid . '/contact'); + $this->assertResponse(403, t('Access to personal contact form denied.')); + + $this->drupalLogout(); + + // Give 'access personal contact form' permissions to anonymous users. + $admin_user = $this->drupalCreateUser(array('administer site-wide contact form', 'administer permissions')); + $this->drupalLogin($admin_user); + $this->setPermission('anonymous user', array('access personal contact form' => TRUE)); + $this->drupalLogout(); + + // Access the personal contact form as anonymous. + $this->drupalGet('user/' . $web_user4->uid . '/contact'); + $this->assertResponse(200, t('Access to personal contact form granted.')); + $edit = array(); + $edit['from'] = "my name"; + $edit['mail'] = "test@example.com"; + $edit['subject'] = $this->randomName(16); + $edit['message'] = $this->randomName(64); + $this->drupalPost(NULL, $edit, t('Send e-mail')); + $this->assertText(t('The message has been sent.'), t('Message sent.')); + $this->drupalLogout(); + // Clear flood table in preparation for flood test and allow other checks to complete. db_delete('flood')->execute(); $num_records_flood = db_query("SELECT COUNT(*) FROM {flood}")->fetchField(); @@ -314,17 +347,17 @@ class ContactPersonalTestCase extends Dr // Submit contact form with correct values and check flood interval. for ($i = 0; $i < $flood_control; $i++) { - $this->drupalGet('user/' . $web_user2->uid . '/contact'); + $this->drupalGet('user/' . $web_user1->uid . '/contact'); $this->drupalPost(NULL, $edit, t('Send e-mail')); $this->assertText(t('The message has been sent.'), t('Message sent.')); } // Submit contact form one over limit. - $this->drupalGet('user/' . $web_user2->uid . '/contact'); - $this->assertRaw(t('You cannot send more than %number messages per hour. Please try again later.', array('%number' => $flood_control)), t('Message threshold reached.')); + $this->drupalGet('user/' . $web_user1->uid . '/contact'); + $this->assertResponse(200, t('You cannot send more than %number messages per hour. Please try again later.')); $this->drupalLogout(); - + $this->drupalLogin($admin_user); // Disable the personal contact form. @@ -337,7 +370,7 @@ class ContactPersonalTestCase extends Dr $this->drupalLogout(); // Create web users and attempt to use personal contact forms with default set to false. - $web_user3 = $this->drupalCreateUser(array()); + $web_user3 = $this->drupalCreateUser(array('access personal contact form')); $web_user4 = $this->drupalCreateUser(array()); $this->drupalLogin($web_user3); @@ -345,4 +378,27 @@ class ContactPersonalTestCase extends Dr $this->drupalGet('user/' . $web_user4->uid . '/contact'); $this->assertResponse(403, t('Access to personal contact form denied.')); } + + /** + * Set permission. + * + * @param string $role User role to set permissions for. + * @param array $permissions Key-value array of permissions to set. + */ + function setPermission($role, $permissions) { + // Get role id (rid) for specified role. + $rid = db_result(db_query("SELECT rid FROM {role} WHERE name = '%s'", array($role))); + if ($rid === FALSE) { + $this->fail(t('[permission] Role "' . $role . '" not found.')); + } + + // Create edit array from permission. + $edit = array(); + foreach ($permissions as $name => $value) { + $edit[$rid . '[' . $name . ']'] = $value; + } + + $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); + $this->assertText(t('The changes have been saved.'), t('[permission] Saved changes.')); + } }