contact.module 14.7 KB
Newer Older
Dries's avatar
 
Dries committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<?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) {
    case 'admin/modules#description':
18 19 20
      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
21 22 23 24 25 26 27 28 29 30
  }
}

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

31 32 33 34 35 36 37 38 39
  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
40
    $items[] = array('path' => 'admin/contact/edit', 'title' => t('add category'),
41 42 43 44 45 46 47
      '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
48 49 50 51 52 53 54 55 56
    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;
}

57 58 59 60
/**
 * Implementation of hook_settings().
 */
function contact_settings() {
Dries's avatar
Dries committed
61
  return form_textarea(t('Additional information'), 'contact_form_information', variable_get('contact_form_information', t('You can leave us a message using the contact form below.')), 60, 5, 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'))));
62 63
}

Dries's avatar
 
Dries committed
64 65 66 67 68 69 70
/**
 * 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') {
71
    return array(array('title' => t('Contact settings'), 'data' => form_checkbox(t('Personal contact form'), 'contact', 1, $edit['contact'], 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")))), 'weight' => 2));
Dries's avatar
 
Dries committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
  }
  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)) {
89
      $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
90 91
    }
    else if (!flood_is_allowed('contact', CONTACT_HOURLY_THRESHOLD)) {
92
      $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
93 94 95 96 97 98 99
    }
    else {
      $edit = $_POST['edit'];

      if ($edit) {
        // Validate the message:
        if (!$edit['message']) {
100
          form_set_error('message', t('You must enter a message.'));
Dries's avatar
 
Dries committed
101
        }
Dries's avatar
Dries committed
102 103 104
        if (!$edit['subject']) {
          form_set_error('subject', t('You must enter a subject.'));
        }
105
        form_validate($edit, $user->name . $user->mail);
Dries's avatar
 
Dries committed
106 107 108 109 110 111 112 113 114 115 116

        if (!form_get_errors()) {
          // 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) {
117
            $message[$key] = wordwrap($value);
Dries's avatar
 
Dries committed
118 119 120 121 122
          }

          // Prepare all fields:
          $to = $account->mail;
          $from = $user->mail;
123

Dries's avatar
Dries committed
124
          // Format the subject:
125 126 127
          $subject = '['. variable_get('site_name', 'drupal') .'] '. $edit['subject'];

          // Prepare the body:
Dries's avatar
Dries committed
128
          $body = implode("\n\n", $message);
Dries's avatar
 
Dries committed
129 130 131 132

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

133 134 135 136 137
          // 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");
          }

Dries's avatar
 
Dries committed
138 139
          // Log the operation:
          flood_register_event('contact');
140
          watchdog('mail', t('%name-from sent %name-to an e-mail.', array('%name-from' => theme('placeholder', $user->name), '%name-to' => theme('placeholder', $account->name))));
Dries's avatar
 
Dries committed
141 142

          // Set a status message:
143
          drupal_set_message(t('The message has been sent.'));
Dries's avatar
 
Dries committed
144 145 146 147 148 149 150 151 152 153 154

          // Jump to the user's profile page:
          drupal_goto("user/$account->uid");
        }
      }
      else {
        $edit['mail'] = $user->mail;
      }

      $output  = form_item(t('From'), $user->name .' &lt;'. $user->mail .'&gt;');
      $output .= form_item(t('To'), $account->name);
155 156
      $output .= form_textfield(t('Subject'), 'subject', $edit['subject'], 60, 50, NULL, NULL, TRUE);
      $output .= form_textarea(t('Message'), 'message', $edit['message'], 60, 15, NULL, NULL, TRUE);
157
      $output .= form_checkbox(t('Send me a copy.'), 'copy', $edit['copy']);
158
      $output .= form_token($user->name . $user->mail);
Dries's avatar
 
Dries committed
159 160 161 162
      $output .= form_submit(t('Send e-mail'));
      $output  = form($output);
    }

Dries's avatar
 
Dries committed
163 164
    drupal_set_title($account->name);
    return $output;
Dries's avatar
 
Dries committed
165 166 167 168 169 170
  }
  else {
    drupal_not_found();
  }
}

Dries's avatar
Dries committed
171
function contact_admin_edit($category = NULL) {
172 173 174
  if (isset($_POST['edit'])) {
    $edit = $_POST['edit'];

Dries's avatar
Dries committed
175 176
    if (empty($edit['category'])) {
      form_set_error('category', t('You must enter a category.'));
177 178 179 180 181 182
    }
    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
183 184
      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']);
185 186 187
      drupal_goto('admin/contact');
    }
  }
Dries's avatar
Dries committed
188 189 190 191 192 193
  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;
  }
194

Dries's avatar
Dries committed
195 196 197
  $form  = form_textfield(t('Category'), 'category', $edit['category'], 60, 255, t("Example: 'website feedback' or 'product information'."), NULL, TRUE);
  $form .= form_textarea(t('Recipients'), 'recipients', $edit['recipients'], 60, 5, t("Example: 'webmaster@yoursite.com' or 'sales@yoursite.com'.  To specify multiple repecients, separate each e-mail address with a comma."), NULL, TRUE);
  $form .= form_textarea(t('Auto-reply'), 'reply', $edit['reply'], 60, 5, t("Optional auto-reply.  Leave empty if you don't want to send the user an auto-reply message."));
198 199
  $form .= form_submit(t('Submit'));

Dries's avatar
 
Dries committed
200
  return form($form);
201 202
}

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


function contact_admin() {
Dries's avatar
Dries committed
220
  $result = db_query('SELECT category, recipients FROM {contact} ORDER BY category');
221
  $rows = array();
Dries's avatar
Dries committed
222 223
  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)));
224
  }
Dries's avatar
Dries committed
225
  $header = array(t('Category'), t('Recipients'), array('data' => t('Operations'), 'colspan' => 2));
Dries's avatar
 
Dries committed
226
  return theme('table', $header, $rows);
227 228 229 230 231 232 233 234 235 236 237 238
}

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 {
    if (isset($_POST['edit'])) {
      $edit = $_POST['edit'];
    }
239

240 241 242 243 244 245 246 247
    if ($edit) {
      // Validate the fields:
      if (!$edit['name']) {
        form_set_error('name', t('You must enter a name.'));
      }
      if (!$edit['mail'] || !valid_email_address($edit['mail'])) {
        form_set_error('mail', t('You must enter a valid e-mail address.'));
      }
Dries's avatar
Dries committed
248 249 250
      if (!$edit['subject']) {
        form_set_error('subject', t('You must enter a subject.'));
      }
251 252 253
      if (!$edit['message']) {
        form_set_error('message', t('You must enter a message.'));
      }
Dries's avatar
Dries committed
254 255 256 257 258 259 260 261 262 263
      if (!$edit['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);
          $edit['category'] = $category->category;
        }
        else {
          form_set_error('category', t('You must select a valid category.'));
        }
264
      }
265
      form_validate($edit, $user->name . $user->mail);
Dries's avatar
Dries committed
266

267 268 269
      if (!form_get_errors()) {
        // Prepare the sender:
        $from = $edit['mail'];
270

271
        // Compose the body:
Dries's avatar
Dries committed
272
        $message[] = t("%name sent a message using the contact form at %form:", array('%name' => $edit['name'], '%form' => url($_GET['q'], NULL, NULL, TRUE)));
273 274 275 276 277 278 279
        $message[] = $edit['message'];

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

Dries's avatar
Dries committed
280 281
        // Format the category:
        $subject = '['. $edit['category'] .'] '. $edit['subject'];
282 283 284 285

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

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

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

292 293 294 295 296
        // 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");
        }

297 298
        // Send an auto-reply if necessary:
        if ($contact->reply) {
Dries's avatar
Dries committed
299
          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");
300 301 302 303
        }

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

Dries's avatar
Dries committed
306
        // Set a status message:subject
307 308
        drupal_set_message(t('Your message has been sent.'));

Dries's avatar
Dries committed
309 310
        // Jump to contact page:
        drupal_goto('contact');
311 312
      }
    }
Dries's avatar
Dries committed
313
    else if ($user->uid) {
314 315 316
      $edit['name'] = $user->name;
      $edit['mail'] = $user->mail;
    }
317

Dries's avatar
Dries committed
318 319 320 321
    $result = db_query('SELECT category FROM {contact} ORDER BY category');
    $categories[] = '--';
    while ($category = db_fetch_object($result)) {
      $categories[$category->category] = $category->category;
322 323
    }

Dries's avatar
Dries committed
324
    if (count($categories) > 1) {
325
      $output  = variable_get('contact_form_information', t('You can leave us a message using the contact form below.'));
Dries's avatar
Dries committed
326 327 328 329 330 331
      $output .= form_textfield(t('Your name'), 'name', $edit['name'], 60, 255, NULL, NULL, TRUE);
      $output .= form_textfield(t('Your e-mail address'), 'mail', $edit['mail'], 60, 255, NULL, NULL, TRUE);
      $output .= form_textfield(t('Subject'), 'subject', $edit['subject'], 60, 255, NULL, NULL, TRUE);
      if (count($categories) > 2) {
        $output .= form_select(t('Category'), 'category', $edit['category'], $categories, NULL, NULL, NULL, TRUE);
      }
332
      $output .= form_textarea(t('Message'), 'message', $edit['message'], 60, 5, NULL, NULL, TRUE);
333
      $output .= form_checkbox(t('Send me a copy.'), 'copy', $edit['copy']);
334
      $output .= form_token($user->name . $user->mail);
335 336 337 338 339 340 341 342
      $output .= form_submit(t('Send e-mail'));
      $output  = form($output);
    }
    else {
      $output = t('The contact form has not been configured.');
    }
  }

Dries's avatar
 
Dries committed
343
  return $output;
344
}
345