contact.module 16.2 KB
Newer Older
Dries's avatar
 
Dries committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<?php
// $Id$

/**
 * @file
 * Enables the use of personal contact forms.
 */

// Users are not allowed to send more than x mails/hour:
define('CONTACT_HOURLY_THRESHOLD', 3);

/**
 * Implementation of hook_help().
 */
function contact_help($section) {
  switch ($section) {
17 18 19 20 21 22 23 24 25 26 27
    case 'admin/help#contact':
      $output = '<p>'. t('The contact module allows other users to contact you by e-mail via your personal contact form.   Users can send a subject and message in the contact form. The contact module is important in helping make connections among members of your community.') .'</p>';
      $output .= '<p>'. t('Users can administer the contact settings in their account settings.  Note that a users e-mail address is not made public and that privileged users such as site administrators are able to contact you even if you choose not to enable this feature. If users activate the personal contact form, then a contact tab will appear in their user profile.') .'</p>';
      $output .= t('<p>You can</p>
<ul>
<li>view user <a href="%profile">profiles</a>.</li>
<li>enable the personal contact form in <a href="%admin-user">administer &gt;&gt; user &gt;&gt; edit tab &gt;&gt; account settings tab &gt;&gt; personal contact settings</a>.</li>
</ul>
', array('%profile' => url('profile'), '%admin-user' => url('admin/user')));
      $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="%contact">Contact page</a>.', array('%contact' => 'http://www.drupal.org/handbook/modules/contact/')) .'</p>';
      return $output;
Dries's avatar
 
Dries committed
28
    case 'admin/modules#description':
29 30 31
      return t('Enables the use of both personal and site-wide contact forms.');
    case 'admin/contact':
      return t('This page lets you setup <a href="%form">your site-wide contact form</a>.  To do so, add one or more subjects.  You can associate different recipients with each subject 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 <a href="%settings">settings page</a> 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/settings/contact'), '%form' => url('contact', NULL, NULL, TRUE)));
Dries's avatar
 
Dries committed
32 33 34 35 36 37 38 39 40 41
  }
}

/**
 * Implementation of hook_menu().
 */
function contact_menu($may_cache) {
  global $user;
  $items = array();

42 43 44 45 46 47 48 49 50
  if ($may_cache) {
    $items[] = array('path' => 'contact', 'title' => t('contact us'),
      'callback' => 'contact_mail_page', 'access' => user_access('access content'),
      'type' => MENU_SUGGESTED_ITEM);
    $items[] = array('path' => 'admin/contact', 'title' => t('contact form'),
      'callback' => 'contact_admin', 'access' => user_access('administer site configuration'));
    $items[] = array('path' => 'admin/contact/list', 'title' => t('list'),
      'callback' => 'contact_admin', 'access' => user_access('administer site configuration'),
      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
Dries's avatar
Dries committed
51
    $items[] = array('path' => 'admin/contact/edit', 'title' => t('add category'),
52 53 54 55 56 57 58
      'callback' => 'contact_admin_edit', 'access' => user_access('administer site configuration'),
      'type' => MENU_LOCAL_TASK);
    $items[] = array('path' => 'admin/contact/delete', 'title' => t('delete contact'),
      'callback' => 'contact_admin_delete', 'access' => user_access('administer site configuration'),
      'type' => MENU_CALLBACK);
  }
  else {
Dries's avatar
 
Dries committed
59 60 61 62 63 64 65 66 67
    if (arg(0) == 'user' && is_numeric(arg(1))) {
      $items[] = array('path' => "user/". arg(1) ."/contact", 'title' => t('contact'),
        'callback' => 'contact_mail_user', 'type' => MENU_LOCAL_TASK, 'weight' => 2);
    }
  }

  return $items;
}

68 69 70 71
/**
 * Implementation of hook_settings().
 */
function contact_settings() {
72
  $form['contact_form_information'] = array(
73 74 75
    '#type' => 'textarea', '#title' => t('Additional information'), '#cols' => 60, '#rows' => 5,
    '#default_value' => variable_get('contact_form_information', t('You can leave us a message using the contact form below.')),
    '#description' => t('Information to show on the <a href="%form">contact page</a>.  Can be anything from submission guidelines to your postal address or telephone number.', array('%form' => url('contact')))
76 77
  );
  return $form;
78 79
}

Dries's avatar
 
Dries committed
80 81 82 83 84 85 86
/**
 * Implementation of hook_user().
 *
 * Provides signature customization for the user's comments.
 */
function contact_user($type, $edit, &$user, $category = NULL) {
  if ($type == 'form' && $category == 'account') {
87 88
    $form['contact'] = array('#type' => 'fieldset', '#title' => t('Contact settings'), '#weight' => 5, '#collapsible' => TRUE, '#collapsed' => FALSE);
    $form['contact']['contact'] = array('#type' => 'checkbox', '#title' => t('Personal contact form'), '#return_value' => 1, '#default_value' => $edit['contact'], '#description' => t('Allow other users to contact you by e-mail via <a href="%url">your personal contact form</a>. Note that your e-mail address is not made public and that 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"))));
89 90
    return $form;
    //return array(array('title' => t('Contact settings'), 'data' => drupal_get_form('contact_user', $form), 'weight' => 2));
Dries's avatar
 
Dries committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
  }
  if ($type == 'validate') {
    return array('contact' => $edit['contact']);
  }
}

function contact_mail_user() {
  global $user;

  if ($account = user_load(array('uid' => arg(1), 'status' => 1))) {
    if (!$account->contact && !user_access('administer users')) {
      $output = t('%name is not accepting e-mails.', array('%name' => $account->name));
    }
    else if (!$user->uid) {
      $output = t('Please <a href="%login">login</a> or <a href="%register">register</a> to send %name a message.', array('%login' => url('user/login'), '%register' => url('user/register'), '%name' => $account->name));
    }
    else if (!valid_email_address($user->mail)) {
108
      $output = t('You need to provide a valid e-mail address to contact other users. Please edit your <a href="%url">user information</a>.', array('%url' => url("user/$user->uid/edit")));
Dries's avatar
 
Dries committed
109 110
    }
    else if (!flood_is_allowed('contact', CONTACT_HOURLY_THRESHOLD)) {
111
      $output = t("You can't contact more than %number users per hour. Please try again later.", array('%number' => CONTACT_HOURLY_THRESHOLD));
Dries's avatar
 
Dries committed
112 113
    }
    else {
114 115
      drupal_set_title($account->name);

116 117 118 119 120 121 122
      $form['#token'] = $user->name . $user->mail;
      $form['from'] = array('#type' => 'item', '#title' => t('From'), '#value' => $user->name .' &lt;'. $user->mail .'&gt;');
      $form['to'] = array('#type' => 'item', '#title' => t('To'), '#value' => $account->name);
      $form['subject'] = array('#type' => 'textfield', '#title' => t('Subject'), '#size' => 60, '#maxlength' => 50, '#required' => TRUE);
      $form['message'] = array('#type' => 'textarea', '#title' => t('Message'), '#cols' => 60, '#rows' => 15, '#required' => TRUE);
      $form['copy'] = array('#type' => 'checkbox', '#title' => ('Send me a copy.'));
      $form['submit'] = array('#type' => 'submit', '#value' => t('Send e-mail'));
123
      $output = drupal_get_form('contact_user_mail', $form);
Dries's avatar
 
Dries committed
124 125
    }

Dries's avatar
 
Dries committed
126
    return $output;
Dries's avatar
 
Dries committed
127 128 129 130 131 132
  }
  else {
    drupal_not_found();
  }
}

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
function contact_user_mail_execute($form_id, $edit) {
  global $user;

  $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", NULL, NULL, TRUE), '%form-url' => url($_GET['q'], NULL, NULL, 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", NULL, NULL, TRUE)));
  $message[] = t('Message:');
  $message[] = $edit['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') .'] '. $edit['subject'];

  // Prepare the body:
  $body = implode("\n\n", $message);

  // Send the e-mail:
  user_mail($to, $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");

  // Send a copy if requested:
  if ($edit['copy']) {
    user_mail($from, $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
  }

  // Log the operation:
  flood_register_event('contact');
  watchdog('mail', t('%name-from sent %name-to an e-mail.', array('%name-from' => theme('placeholder', $user->name), '%name-to' => theme('placeholder', $account->name))));

  // Set a status message:
  drupal_set_message(t('The message has been sent.'));

  // Jump to the user's profile page:
  drupal_goto("user/$account->uid");
}

Dries's avatar
Dries committed
178
function contact_admin_edit($category = NULL) {
179 180 181
  if (isset($_POST['edit'])) {
    $edit = $_POST['edit'];

Dries's avatar
Dries committed
182 183
    if (empty($edit['category'])) {
      form_set_error('category', t('You must enter a category.'));
184 185 186 187 188 189
    }
    if (empty($edit['recipients'])) {
      form_set_error('recipients', t('You must enter one or more recipients.'));
    }

    if (!form_get_errors()) {
Dries's avatar
Dries committed
190 191
      db_query("DELETE FROM {contact} WHERE category = '%s'", $category);
      db_query("INSERT INTO {contact} (category, recipients, reply) VALUES ('%s', '%s', '%s')", $edit['category'], $edit['recipients'], $edit['reply']);
192 193 194
      drupal_goto('admin/contact');
    }
  }
Dries's avatar
Dries committed
195 196 197 198 199 200
  else {
    $category           = db_fetch_object(db_query("SELECT * FROM {contact} WHERE category = '%s'", $category));
    $edit['category']   = $category->category;
    $edit['recipients'] = $category->recipients;
    $edit['reply']      = $category->reply;
  }
201

202 203 204 205
  $form['category'] = array('#type' => 'textfield', '#title' => t('Category'), '#size' => 60, '#maxlength' => 255, '#default_value' => $edit['category'], '#description' => t("Example: 'website feedback' or 'product information'."), '#required' => TRUE);
  $form['recipients'] = array('#type' => 'textarea', '#title' => t('Recipients'), '#cols' => 60, '#rows' => 5, '#default_value' => $edit['recipients'], '#description' => t("Example: 'webmaster@yoursite.com' or 'sales@yoursite.com'.  To specify multiple repecients, separate each e-mail address with a comma."), '#required' => TRUE);
  $form['reply'] = array('#type' => 'textarea', '#title' => t('Auto-reply'), '#cols' => 60, '#rows' => 5, '#default_value' => $edit['reply'], '#description' => t("Optional auto-reply.  Leave empty if you don't want to send the user an auto-reply message."));
  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
206

207
  return drupal_get_form('contact_admin_edit', $form);
208 209
}

Dries's avatar
Dries committed
210
function contact_admin_delete($category) {
211
  if ($_POST['op'] != t('Delete')) {
212 213 214 215 216 217
    return confirm_form('contact_admin_delete', array(),
                    t('Are you sure you want to delete %category?', array('%category' => theme('placeholder', $category))),
                    'admin/contact',
                    t('This action cannot be undone.'),
                    t('Delete'),
                    t('Cancel'));
218 219
  }
  else {
Dries's avatar
Dries committed
220
    db_query("DELETE FROM {contact} WHERE category = '%s'", $category);
221 222 223 224 225 226
    drupal_goto('admin/contact');
  }
}


function contact_admin() {
Dries's avatar
Dries committed
227
  $result = db_query('SELECT category, recipients FROM {contact} ORDER BY category');
228
  $rows = array();
Dries's avatar
Dries committed
229 230
  while ($category = db_fetch_object($result)) {
    $rows[] = array($category->category, $category->recipients, l(t('edit'), 'admin/contact/edit/'. urlencode($category->category)), l(t('delete'), 'admin/contact/delete/'. urlencode($category->category)));
231
  }
Dries's avatar
Dries committed
232
  $header = array(t('Category'), t('Recipients'), array('data' => t('Operations'), 'colspan' => 2));
Dries's avatar
 
Dries committed
233
  return theme('table', $header, $rows);
234 235 236 237 238 239 240 241 242
}

function contact_mail_page() {
  global $user;

  if (!flood_is_allowed('contact', CONTACT_HOURLY_THRESHOLD)) {
    $output = t("You can't send more than %number messages per hour. Please try again later.", array('%number' => CONTACT_HOURLY_THRESHOLD));
  }
  else {
243
    if ($user->uid) {
244 245 246
      $edit['name'] = $user->name;
      $edit['mail'] = $user->mail;
    }
247

Dries's avatar
Dries committed
248 249 250 251
    $result = db_query('SELECT category FROM {contact} ORDER BY category');
    $categories[] = '--';
    while ($category = db_fetch_object($result)) {
      $categories[$category->category] = $category->category;
252 253
    }

Dries's avatar
Dries committed
254
    if (count($categories) > 1) {
255 256 257 258 259
      $form['#token'] = $user->name . $user->mail;
      $form['contact_information'] = array('#type' => 'markup', '#value' => variable_get('contact_form_information', t('You can leave us a message using the contact form below.')));
      $form['name'] = array('#type' => 'textfield', '#title' => t('Your name'), '#size' => 60, '#maxlength' => 255, '#default_value' => $edit['name'], '#required' => TRUE);
      $form['mail'] = array('#type' => 'textfield', '#title' => t('Your e-mail address'), '#size' => 60, '#maxlength' => 255, '#default_value' => $edit['mail'], '#required' => TRUE);
      $form['subject'] = array('#type' => 'textfield', '#title' => t('Subject'), '#size' => 60, '#maxlength' => 255, '#default_value' => $edit['subject'], '#required' => TRUE);
Dries's avatar
Dries committed
260
      if (count($categories) > 2) {
261
        $form['category'] = array('#type' => 'select', '#title' => t('Category'), '#size' => 60, '#maxlength' => 255, '#default_value' => $edit['category'], '#options' => $categories, '#required' => TRUE);
Dries's avatar
Dries committed
262
      }
263 264 265
      $form['message'] = array('#type' => 'textarea', '#title' => t('Message'), '#cols' => 60, '#rows' => 5, '#default_value' => $edit['message'], '#required' => TRUE);
      $form['copy'] = array('#type' => 'checkbox', '#title' => t('Send me a copy.'), '#default_value' => $edit['copy'], '#return_value' => 1);
      $form['submit'] = array('#type' => 'submit', '#value' => t('Send e-mail'));
266
      $output = drupal_get_form('contact_mail_page', $form);
267 268 269 270 271 272
    }
    else {
      $output = t('The contact form has not been configured.');
    }
  }

Dries's avatar
 
Dries committed
273
  return $output;
274
}
275

276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
function contact_mail_page_validate($form_id, &$form) {
  global $form_values;
  if (!$form['category']) {
    // Look if there is only one category
    $result = db_query('SELECT category FROM {contact}');
    if (db_num_rows($result) == 1) {
      $category = db_fetch_object($result);
      $form_values['category'] = $category->category;
    }
    else {
      form_set_error('category', t('You must select a valid category.'));
    }
  }
}

function contact_mail_page_execute($form_id, $edit) {

  // Prepare the sender:
  $from = $edit['mail'];

  // Compose the body:
  $message[] = t("%name sent a message using the contact form at %form:", array('%name' => $edit['name'], '%form' => url($_GET['q'], NULL, NULL, TRUE)));
  $message[] = $edit['message'];

  // Tidy up the body:
  foreach ($message as $key => $value) {
    $message[$key] = wordwrap($value);
  }

  // Format the category:
  $subject = '['. $edit['category'] .'] '. $edit['subject'];

  // Prepare the body:
  $body = implode("\n\n", $message);

  // Load the category information:
  $contact = db_fetch_object(db_query("SELECT * FROM {contact} WHERE category = '%s'", $edit['category']));

  // Send the e-mail to the recipients:
  user_mail($contact->recipients, $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");

  // If the user requests it, send a copy.
  if ($edit['copy']) {
    user_mail($from, $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
  }

  // Send an auto-reply if necessary:
  if ($contact->reply) {
    user_mail($from, $subject, wordwrap($contact->reply), "From: $contact->recipients\nReply-to: $contact->recipients\nX-Mailer: Drupal\nReturn-path: $contact->recipients\nErrors-to: $contact->recipients");
  }

  // Log the operation:
  flood_register_event('contact');
  watchdog('mail', t('%name-from sent an e-mail regarding %category.', array('%name-from' => theme('placeholder', $edit['name'] ." <$from>"), '%category' => theme('placeholder', $contact->category))));

  // Set a status message:subject
  drupal_set_message(t('Your message has been sent.'));

  // Jump to contact page:
  drupal_goto('contact');
}