contact.module 16.9 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
    '#type' => 'textarea', '#title' => t('Additional information'),
74 75
    '#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);
    $form['contact']['contact'] = array('#type' => 'checkbox', '#title' => t('Personal contact form'), '#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
    return $form;
Dries's avatar
 
Dries committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  }
  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)) {
107
      $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
108 109
    }
    else if (!flood_is_allowed('contact', CONTACT_HOURLY_THRESHOLD)) {
110
      $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
111 112
    }
    else {
113 114
      drupal_set_title($account->name);

115 116 117
      $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);
118 119
      $form['subject'] = array('#type' => 'textfield', '#title' => t('Subject'), '#maxlength' => 50, '#required' => TRUE);
      $form['message'] = array('#type' => 'textarea', '#title' => t('Message'), '#rows' => 15, '#required' => TRUE);
120 121
      $form['copy'] = array('#type' => 'checkbox', '#title' => ('Send me a copy.'));
      $form['submit'] = array('#type' => 'submit', '#value' => t('Send e-mail'));
122
      $output = drupal_get_form('contact_user_mail', $form);
Dries's avatar
 
Dries committed
123 124
    }

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

132 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
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");
}

177
function contact_admin_edit($cid = NULL) {
178 179 180
  if (isset($_POST['edit'])) {
    $edit = $_POST['edit'];

Dries's avatar
Dries committed
181 182
    if (empty($edit['category'])) {
      form_set_error('category', t('You must enter a category.'));
183 184 185 186 187 188
    }
    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
189
      db_query("DELETE FROM {contact} WHERE cid = %d", $cid);
190 191
      db_query("INSERT INTO {contact} (category, recipients, reply, weight, selected) VALUES ('%s', '%s', '%s', %d, %d)", $edit['category'], $edit['recipients'], $edit['reply'], $edit['weight'], $edit['selected']);
      drupal_set_message(t('Category %category has been updated.', array('%category' => theme('placeholder', $edit['category']))));
192 193 194
      drupal_goto('admin/contact');
    }
  }
Dries's avatar
Dries committed
195
  else {
Dries's avatar
Dries committed
196
    $category           = db_fetch_object(db_query("SELECT * FROM {contact} WHERE cid = %d", $cid));
197
    $edit['cid']        = $category->cid;
Dries's avatar
Dries committed
198 199 200
    $edit['category']   = $category->category;
    $edit['recipients'] = $category->recipients;
    $edit['reply']      = $category->reply;
201 202
    $edit['weight']     = $category->weight;
    $edit['selected']   = $category->selected;
Dries's avatar
Dries committed
203
  }
204

205 206 207
  $form['category'] = array('#type' => 'textfield', '#title' => t('Category'), '#maxlength' => 255, '#default_value' => $edit['category'], '#description' => t("Example: 'website feedback' or 'product information'."), '#required' => TRUE);
  $form['recipients'] = array('#type' => 'textarea', '#title' => t('Recipients'), '#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'), '#default_value' => $edit['reply'], '#description' => t("Optional auto-reply.  Leave empty if you don't want to send the user an auto-reply message."));
208 209
  $form['weight'] = array('#type' => 'weight', '#title' => t('Weight'), '#default_value' => $edit['weight'], '#description' => t('When listing categories, those with with light (small) weights get listed before categories with heavier (larger) weights. Categories with equal weights are sorted alphabetically.'));
  $form['selected'] = array('#type' => 'select', '#title' => t('Selected'), '#options' => array('0' => t('No'), '1' => t('Yes')), '#default_value' => $edit['selected'], '#description' => t('Set this to <em>Yes</em> if you would like this category to be selected by default.'));
210
  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
211

212
  return drupal_get_form('contact_admin_edit', $form);
213 214
}

215
function contact_admin_delete($cid) {
216
  $info = db_fetch_object(db_query("SELECT cid, category FROM {contact} WHERE cid = %d", $cid));
217
  if ($_POST['op'] != t('Delete')) {
218
    return confirm_form('contact_admin_delete', array(),
219
                    t('Are you sure you want to delete %category?', array('%category' => theme('placeholder', $info->category))),
220 221 222 223
                    'admin/contact',
                    t('This action cannot be undone.'),
                    t('Delete'),
                    t('Cancel'));
224 225
  }
  else {
Dries's avatar
Dries committed
226
    db_query("DELETE FROM {contact} WHERE cid = %d", $cid);
227 228 229 230 231 232
    drupal_goto('admin/contact');
  }
}


function contact_admin() {
233
  $result = db_query('SELECT cid, category, recipients, selected FROM {contact} ORDER BY weight, category');
234
  $rows = array();
Dries's avatar
Dries committed
235
  while ($category = db_fetch_object($result)) {
236
    $rows[] = array($category->category, $category->recipients, ($category->selected ? t('Yes') : t('No')), l(t('edit'), 'admin/contact/edit/'. $category->cid), l(t('delete'), 'admin/contact/delete/'. $category->cid));
237
  }
238
  $header = array(t('Category'), t('Recipients'), t('Selected'), array('data' => t('Operations'), 'colspan' => 2));
Dries's avatar
 
Dries committed
239
  return theme('table', $header, $rows);
240 241 242 243 244 245 246 247 248
}

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 {
249
    if ($user->uid) {
250 251 252
      $edit['name'] = $user->name;
      $edit['mail'] = $user->mail;
    }
253

254
    $result = db_query('SELECT cid, category, selected FROM {contact} ORDER BY weight, category');
Dries's avatar
Dries committed
255 256
    $categories[] = '--';
    while ($category = db_fetch_object($result)) {
257 258 259 260
      $categories[$category->cid] = $category->category;
      if ($category->selected) {
        $default_category = $category->cid;
      }
261 262
    }

Dries's avatar
Dries committed
263
    if (count($categories) > 1) {
264 265
      $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.')));
266 267 268
      $form['name'] = array('#type' => 'textfield', '#title' => t('Your name'), '#maxlength' => 255, '#default_value' => $edit['name'], '#required' => TRUE);
      $form['mail'] = array('#type' => 'textfield', '#title' => t('Your e-mail address'), '#maxlength' => 255, '#default_value' => $edit['mail'], '#required' => TRUE);
      $form['subject'] = array('#type' => 'textfield', '#title' => t('Subject'), '#maxlength' => 255, '#default_value' => $edit['subject'], '#required' => TRUE);
Dries's avatar
Dries committed
269
      if (count($categories) > 2) {
270
        $form['cid'] = array('#type' => 'select', '#title' => t('Category'), '#default_value' => $default_category, '#options' => $categories, '#required' => TRUE);
Dries's avatar
Dries committed
271
      }
272 273
      $form['message'] = array('#type' => 'textarea', '#title' => t('Message'), '#default_value' => $edit['message'], '#required' => TRUE);
      $form['copy'] = array('#type' => 'checkbox', '#title' => t('Send me a copy.'), '#default_value' => $edit['copy']);
274
      $form['submit'] = array('#type' => 'submit', '#value' => t('Send e-mail'));
275
      $output = drupal_get_form('contact_mail_page', $form);
276 277 278 279 280 281
    }
    else {
      $output = t('The contact form has not been configured.');
    }
  }

Dries's avatar
 
Dries committed
282
  return $output;
283
}
284

285 286
function contact_mail_page_validate($form_id, &$form) {
  global $form_values;
287
  if (!$form['cid']) {
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
    // 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);
  }

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

317
  // Format the category:
318
  $subject = '['. $contact->category .'] '. $edit['subject'];
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345

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

  // 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');
}