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

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

/**
 * Implementation of hook_help().
 */
function contact_help($section) {
  switch ($section) {
14
15
16
17
18
19
20
21
22
23
24
    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
25
    case 'admin/modules#description':
26
27
28
      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
29
30
31
32
33
34
35
36
37
38
  }
}

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

39
40
41
42
43
44
45
46
47
  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
48
    $items[] = array('path' => 'admin/contact/edit', 'title' => t('add category'),
49
50
51
52
53
54
55
      '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
56
57
58
59
60
61
62
63
64
    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;
}

65
66
67
68
/**
 * Implementation of hook_settings().
 */
function contact_settings() {
69
  $form['contact_form_information'] = array(
70
    '#type' => 'textarea', '#title' => t('Additional information'),
71
72
    '#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')))
73
  );
74
75
76
77
78
79
80
  $form['contact_hourly_threshold'] = array(
    '#type' => 'select',
    '#title' => t('Hourly threshold'),
    '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50)),
    '#default_value' => variable_get('contact_hourly_threshold', 3),
    '#description' => t('The maximum number of contact form submissions a user can perform per hour.'),
  );
81
  return $form;
82
83
}

Dries's avatar
   
Dries committed
84
85
86
87
88
89
90
/**
 * 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') {
91
92
    $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"))));
93
    return $form;
Dries's avatar
   
Dries committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  }
  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)) {
111
      $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
112
    }
113
114
    else if (!flood_is_allowed('contact', variable_get('contact_hourly_threshold', 3))) {
      $output = t("You can't contact more than %number users per hour. Please try again later.", array('%number' => variable_get('contact_hourly_threshold', 3)));
Dries's avatar
   
Dries committed
115
116
    }
    else {
117
118
      drupal_set_title($account->name);

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

Dries's avatar
   
Dries committed
129
    return $output;
Dries's avatar
   
Dries committed
130
131
132
133
134
135
  }
  else {
    drupal_not_found();
  }
}

136
function contact_user_mail_submit($form_id, $edit) {
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
178
179
180
  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");
}

181
function contact_admin_edit($cid = NULL) {
182
183
184
  if (isset($_POST['edit'])) {
    $edit = $_POST['edit'];

Dries's avatar
Dries committed
185
186
    if (empty($edit['category'])) {
      form_set_error('category', t('You must enter a category.'));
187
188
189
190
191
192
    }
    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
193
      db_query("DELETE FROM {contact} WHERE cid = %d", $cid);
194
195
      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']))));
196
197
198
      drupal_goto('admin/contact');
    }
  }
Dries's avatar
Dries committed
199
  else {
Dries's avatar
Dries committed
200
    $category           = db_fetch_object(db_query("SELECT * FROM {contact} WHERE cid = %d", $cid));
201
    $edit['cid']        = $category->cid;
Dries's avatar
Dries committed
202
203
204
    $edit['category']   = $category->category;
    $edit['recipients'] = $category->recipients;
    $edit['reply']      = $category->reply;
205
206
    $edit['weight']     = $category->weight;
    $edit['selected']   = $category->selected;
Dries's avatar
Dries committed
207
  }
208

209
210
211
  $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."));
212
213
  $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.'));
214
  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
215

216
  return drupal_get_form('contact_admin_edit', $form);
217
218
}

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


function contact_admin() {
237
  $result = db_query('SELECT cid, category, recipients, selected FROM {contact} ORDER BY weight, category');
238
  $rows = array();
Dries's avatar
Dries committed
239
  while ($category = db_fetch_object($result)) {
240
    $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));
241
  }
242
  $header = array(t('Category'), t('Recipients'), t('Selected'), array('data' => t('Operations'), 'colspan' => 2));
Dries's avatar
   
Dries committed
243
  return theme('table', $header, $rows);
244
245
246
247
248
}

function contact_mail_page() {
  global $user;

249
250
  if (!flood_is_allowed('contact', variable_get('contact_hourly_threshold', 3))) {
    $output = t("You can't send more than %number messages per hour. Please try again later.", array('%number' => variable_get('contact_hourly_threshold', 3)));
251
252
  }
  else {
253
    if ($user->uid) {
254
255
256
      $edit['name'] = $user->name;
      $edit['mail'] = $user->mail;
    }
257

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

Dries's avatar
Dries committed
267
    if (count($categories) > 1) {
268
269
      $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.')));
270
271
272
      $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
273
      if (count($categories) > 2) {
274
        $form['cid'] = array('#type' => 'select', '#title' => t('Category'), '#default_value' => $default_category, '#options' => $categories, '#required' => TRUE);
Dries's avatar
Dries committed
275
      }
276
277
      $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']);
278
      $form['submit'] = array('#type' => 'submit', '#value' => t('Send e-mail'));
279
      $output = drupal_get_form('contact_mail_page', $form);
280
281
282
283
284
285
    }
    else {
      $output = t('The contact form has not been configured.');
    }
  }

Dries's avatar
   
Dries committed
286
  return $output;
287
}
288

289
290
function contact_mail_page_validate($form_id, &$form) {
  global $form_values;
291
  if (!$form['cid']) {
292
    // Look if there is only one category
293
    $result = db_query('SELECT cid FROM {contact}');
294
295
    if (db_num_rows($result) == 1) {
      $category = db_fetch_object($result);
296
      $form_values['cid'] = $category->cid;
297
298
299
300
301
302
303
    }
    else {
      form_set_error('category', t('You must select a valid category.'));
    }
  }
}

304
function contact_mail_page_submit($form_id, $edit) {
305
306
307
308
309

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

  // Compose the body:
Dries's avatar
Dries committed
310
  $message[] = t("%name sent a message using the contact form at %form.", array('%name' => $edit['name'], '%form' => url($_GET['q'], NULL, NULL, TRUE)));
311
312
313
314
315
316
317
  $message[] = $edit['message'];

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

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

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

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