email.module 12.9 KB
Newer Older
Matthias Hutterer's avatar
Matthias Hutterer committed
1 2 3
<?php


4
/**
5
 * Implements hook_field_info().
6
 */
7
function email_field_info() {
8
  return array(
9 10
    'email' => array(
      'label' => 'Email',
11 12 13
      'description' => t('This field stores and renders email addresses.'),
      'default_widget' => 'email_textfield',
      'default_formatter' => 'email_default',
14
      'property_type' => 'text',
15 16 17
    ),
  );
}
Matthias Hutterer's avatar
Matthias Hutterer committed
18 19

/**
20 21 22 23
 * Implements hook_field_validate().
 *
 * Possible error codes:
 * - 'email_invalid': The email address is not valid
Matthias Hutterer's avatar
Matthias Hutterer committed
24
 */
25 26 27 28 29 30 31 32 33
function email_field_validate($obj_type, $object, $field, $instance, $langcode, $items, &$errors) {
  foreach ($items as $delta => $item) {
    if ($item['email'] != '' && !valid_email_address(trim($item['email']))) {
      $message = t('"%mail" is not a valid email address', array('%mail' => $item['email']));
      $errors[$field['field_name']][$langcode][$delta][] = array(
        'error' => "email_invalid",
        'message' => $message,
      );
    }
Matthias Hutterer's avatar
Matthias Hutterer committed
34 35
  }
}
36

37 38 39 40 41 42
/**
 * Implements hook_field_widget_error().
 */
function email_field_widget_error($element, $error, $form, &$form_state) {
  form_error($element, $error['message']);
}
43 44

/**
Matthias Hutterer's avatar
Matthias Hutterer committed
45
 * Implements hook_content_is_empty().
46
 */
47
function email_field_is_empty($item, $field) {
48 49 50 51 52
  if (empty($item['email'])) {
    return TRUE;
  }
  return FALSE;
}
Matthias Hutterer's avatar
Matthias Hutterer committed
53

54
/**
55
 * Implements hook_field_formatter_info().
56 57 58
 *
 */
function email_field_formatter_info() {
59
  $formats = array(
60
    'email_default' => array(
61
      'label' => t('Default email link'),
62
      'description' => t('Display the email address as a mailto link.'),
63 64
      'field types' => array('email'),
    ),
65
    'email_contact' => array(
66
      'label' => t('Email contact form'),
67
      'description' => t('Display a contact form.'),
68 69
      'field types' => array('email'),
    ),
70
    'email_plain' => array(
Matthias Hutterer's avatar
Matthias Hutterer committed
71
      'label' => t('Email plain text'),
72
      'description' => t('Display the email address as plain text.'),
Matthias Hutterer's avatar
Matthias Hutterer committed
73 74
      'field types' => array('email'),
    ),
75
  );
76 77
  if (module_exists('spamspan')) {
    $formats += array(
78
      'email_spamspan' => array(
79 80 81
        'label' => t('Email SpamSpan'),
        'field types' => array('email'),
      ),
82 83 84
    );
  }
  return $formats;
85
}
Matthias Hutterer's avatar
Matthias Hutterer committed
86

87
/**
88
 * Implements hook_field_formatter_view().
89
 */
90 91 92
function email_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
  $element = array();
  switch ($display['type']) {
93
    case 'email_default':
94
      foreach ($items as $delta => $item) {
Matthias Hutterer's avatar
Matthias Hutterer committed
95
        $output = l($item['email'], 'mailto:' . $item['email']);
96 97 98
        $element[$delta] = array('#markup' => $output);
      }
      break;
Matthias Hutterer's avatar
Matthias Hutterer committed
99

100
    case 'email_contact':
101
      $ids = entity_extract_ids($object_type, $object);
102
      foreach ($items as $delta => $item) {
Matthias Hutterer's avatar
Matthias Hutterer committed
103 104
        $element[$delta] = array('#markup' => l(t('Contact person by email'), 'email/' . $object_type . '/' . $ids[0] . '/' . $instance['field_name']));
        // Since email is always sent to first item's email, break after any email address found.
105
        break;
106 107
      }
      break;
Matthias Hutterer's avatar
Matthias Hutterer committed
108

109
    case 'email_plain':
Matthias Hutterer's avatar
Matthias Hutterer committed
110 111 112 113
      foreach ($items as $delta => $item) {
        $element[$delta] = array('#markup' => check_plain($item['email']));
      }
      break;
Matthias Hutterer's avatar
Matthias Hutterer committed
114

115
    case 'email_spamspan':
116 117 118 119 120
      foreach ($items as $delta => $item) {
        if (module_exists('spamspan')) {
          $element[$delta] = spamspan($item['email']);
        }
        else {
Matthias Hutterer's avatar
Matthias Hutterer committed
121
          $output = l($item['email'], 'mailto:' . $item['email']);
122 123 124 125
          $element[$delta] = array('#markup' => $output);
        }
      }
      break;
Matthias Hutterer's avatar
Matthias Hutterer committed
126
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
127
  return $element;
128 129
}

Matthias Hutterer's avatar
Matthias Hutterer committed
130 131

/**
132
 * Implements hook_field_widget_info().
Matthias Hutterer's avatar
Matthias Hutterer committed
133
 */
134
function email_field_widget_info() {
Matthias Hutterer's avatar
Matthias Hutterer committed
135
  return array(
136 137
    'email_textfield' => array(
      'label' => t('Text field'),
Matthias Hutterer's avatar
Matthias Hutterer committed
138
      'field types' => array('email'),
139
      'settings' => array('size' => 60),
Matthias Hutterer's avatar
Matthias Hutterer committed
140 141 142 143
    ),
  );
}

144
/**
145
 * Implements hook_field_widget_settings_form().
146
 */
147 148 149 150 151 152 153 154 155 156
function email_field_widget_settings_form($field, $instance) {
  $widget = $instance['widget'];
  $settings = $widget['settings'];

  $form['size'] = array(
    '#type' => 'textfield',
    '#title' => t('Size of textfield'),
    '#default_value' => $settings['size'],
    '#required' => TRUE,
    '#element_validate' => array('_element_validate_integer_positive'),
157
  );
158
  return $form;
159
}
Matthias Hutterer's avatar
Matthias Hutterer committed
160 161

/**
162
 * Implements hook_field_widget_form().
Matthias Hutterer's avatar
Matthias Hutterer committed
163
 */
164 165 166 167 168 169 170 171 172 173
function email_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $base) {
  $element = $base;
  $element['email'] = $base + array(
    '#type' => 'textfield',
    '#default_value' => isset($items[$delta]['email']) ? $items[$delta]['email'] : NULL,
    '#size' => $instance['widget']['settings']['size'],
    '#prefix' => '<div class="text-full-wrapper">',
    '#suffix' => '</div>',
  );
  return $element;
Matthias Hutterer's avatar
Matthias Hutterer committed
174 175
}

176
/**
Matthias Hutterer's avatar
Matthias Hutterer committed
177
 * Implements hook_menu().
178
 */
179
function email_menu() {
180
  $items['email/%/%/%'] = array(
181
    'title' => 'Email Contact Form',
182
    'page callback' => 'email_mail_page',
183
    'page arguments' => array(1, 2, 3),
184 185
    'access callback' => 'user_access',
    'access arguments' => array('access content'),
186 187
    'type' => MENU_CALLBACK,
  );
188 189
  $items['admin/config/content/email'] = array(
    'title' => 'Email Contact Form Settings',
190 191 192 193
    'description' => 'Administer flood control settings for email contact forms',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('email_admin_settings'),
    'access arguments' => array('administer site configuration'),
194
    'type' => MENU_CALLBACK,
195
  );
196 197 198
  return $items;
}

199

200 201 202
/**
 * The contact form page.
 */
203 204
function email_mail_page($object_type, $object_id, $field_name) {
  global $user;
205

206 207 208 209
  if (!is_numeric($object_id)) {
    drupal_not_found();
    return;
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
210

211 212 213
  //verify this is an email field
  $field_info = field_info_field($field_name);
  if ($field_info['type'] != 'email') {
214 215 216
    drupal_not_found();
    return;
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
217

218 219
  $objects = entity_load($object_type, array($object_id));
  $object = $objects[$object_id];
Matthias Hutterer's avatar
Matthias Hutterer committed
220

221 222 223 224 225
  //verify the object really exists
  if (!$object) {
    drupal_not_found();
    return;
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
226

227 228 229
  //check field perm
  if (module_exists('field_permissions')) {
    if (!field_permissions_field_access('view', $field_info, $object_type, $object, $user)) {
230 231 232 233
      drupal_not_found();
      return;
    }
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
234

235 236
  //use the first email address as receiver
  $field = array_pop($object->$field_name);
237 238 239 240 241 242
  foreach ($field as $delta => $item) {
    if (!empty($item['email'])) {
      $email = $item['email'];
      break;
    }
  }
243 244 245

  //verify that the email address is not empty
  if (empty($email)) {
246 247 248
    drupal_not_found();
    return;
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
249

250 251
  $entity_info = entity_extract_ids($object_type, $object);
  $settings = field_info_instance($object_type, $field_name, $entity_info[2]);
Matthias Hutterer's avatar
Matthias Hutterer committed
252
  $found = FALSE;
253 254
  foreach ($settings['display'] as $display_name => $display_data) {
    if (isset($display_data['type']) && ($display_data['type'] === 'email_contact')) {
Matthias Hutterer's avatar
Matthias Hutterer committed
255
      $found = TRUE;
256 257 258 259
      break;
    }
  }
  if (!$found) {
260 261
    drupal_not_found();
    return;
262
  }
263 264

  if (!flood_is_allowed('email', variable_get('email_hourly_threshold', 3))) {
265
    return t("You cannot send more than %number messages per hour. Please try again later.", array('%number' => variable_get('email_hourly_threshold', 3)));
266
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
267

268
  return drupal_get_form('email_mail_page_form', $object_type, $object_id, $field_name, $email);
269 270
}

271 272 273
/**
 * Contact form
 */
274
function email_mail_page_form($form, $form_state, $object_type, $object_id, $field_name, $email) {
Matthias Hutterer's avatar
Matthias Hutterer committed
275
  global $user;
276 277 278 279 280 281

  $form['object_id'] = array(
    '#type' => 'value',
    '#value' => $object_id,
  );
  $form['object_type'] = array(
282
    '#type' => 'value',
283
    '#value' => $object_type,
284
  );
285
  $form['field_name'] = array(
286
    '#type' => 'value',
287 288 289 290 291
    '#value' => $field_name,
  );
  $form['email'] = array(
    '#type' => 'value',
    '#value' => $email,
292 293 294
  );
  $form['name'] = array(
    '#type' => 'textfield',
Matthias Hutterer's avatar
Matthias Hutterer committed
295 296
    '#title' => t('Your name'),
    '#maxlength' => 255,
297
    '#default_value' => $user->uid ? $user->name : '',
Matthias Hutterer's avatar
Matthias Hutterer committed
298 299
    '#required' => TRUE,
  );
300 301
  $form['mail'] = array(
    '#type' => 'textfield',
Matthias Hutterer's avatar
Matthias Hutterer committed
302 303
    '#title' => t('Your e-mail address'),
    '#maxlength' => 255,
304
    '#default_value' => $user->uid ? $user->mail : '',
Matthias Hutterer's avatar
Matthias Hutterer committed
305 306
    '#required' => TRUE,
  );
307 308
  $form['subject'] = array(
    '#type' => 'textfield',
Matthias Hutterer's avatar
Matthias Hutterer committed
309 310 311 312
    '#title' => t('Subject'),
    '#maxlength' => 255,
    '#required' => TRUE,
  );
313 314
  $form['message'] = array(
    '#type' => 'textarea',
Matthias Hutterer's avatar
Matthias Hutterer committed
315 316 317
    '#title' => t('Message'),
    '#required' => TRUE,
  );
318 319
  $form['submit'] = array(
    '#type' => 'submit',
Matthias Hutterer's avatar
Matthias Hutterer committed
320
    '#value' => t('Send e-mail'),
321 322
    '#validate' => array('email_mail_page_form_validate'),
    '#submit' => array('email_mail_page_form_submit'),
Matthias Hutterer's avatar
Matthias Hutterer committed
323 324 325 326
  );
  return $form;
}

327 328 329
/**
 * Validate the site-wide contact page form submission.
 */
330 331
function email_mail_page_form_validate($form, &$form_state) {
  if (!valid_email_address($form_state['values']['mail'])) {
332 333
    form_set_error('mail', t('You must enter a valid e-mail address.'));
  }
334
  if (preg_match("/\r|\n/", $form_state['values']['subject'])) {
Matthias Hutterer's avatar
Matthias Hutterer committed
335
    form_set_error('subject', t('The subject cannot contain linebreaks.'));
Matthias Hutterer's avatar
Matthias Hutterer committed
336
    watchdog('mail', 'Email injection exploit attempted in email form subject: ' . check_plain($form_state['values']['subject']), WATCHDOG_NOTICE);
Matthias Hutterer's avatar
Matthias Hutterer committed
337
  }
338 339 340 341 342
}

/**
 * Process the site-wide contact page form submission.
 */
343
function email_mail_page_form_submit($form, &$form_state) {
344 345
  $object_type = $form_state['values']['object_type'];
  $object_id = $form_state['values']['object_id'];
346 347
  $field_name = $form_state['values']['field_name'];
  $email = $form_state['values']['email'];
Matthias Hutterer's avatar
Matthias Hutterer committed
348 349

  // Load entity
350 351 352
  $objects = entity_load($object_type, array($object_id));
  $object = $objects[$object_id];
  $object_info = entity_get_info($object_type);
Matthias Hutterer's avatar
Matthias Hutterer committed
353

354 355 356
  // E-mail address of the sender: as the form field is a text field,
  // all instances of \r and \n have been automatically stripped from it.

357
  $from = $form_state['values']['mail'];
Matthias Hutterer's avatar
Matthias Hutterer committed
358

359
  $params['object'] = $object;
360 361 362
  $params['subject'] = $form_state['values']['subject'];
  $params['name'] = $form_state['values']['name'];
  $params['message'] = $form_state['values']['message'];
Matthias Hutterer's avatar
Matthias Hutterer committed
363

364 365 366 367 368
  $path = "";
  if (isset($object_info['path callback']) && function_exists($object_info['path callback'])) {
    $path = $object_info['path callback']($object);
  }
  $params['url'] = url($path, array('absolute' => TRUE));
Matthias Hutterer's avatar
Matthias Hutterer committed
369

370
  // Send the e-mail to the recipients:
371
  drupal_mail('email', 'contact', $email, language_default(), $params, $from);
Matthias Hutterer's avatar
Matthias Hutterer committed
372

373 374
  // Log the operation:
  flood_register_event('email');
375
  watchdog('mail', t('%name-from sent an e-mail at %form.', array('%name-from' => $form_state['values']['name'], '%form' => url($_GET['q'], array('absolute' => TRUE)))));
Matthias Hutterer's avatar
Matthias Hutterer committed
376

377
  drupal_set_message(t('Your message has been sent.'));
378
  $form_state['redirect'] = $path;
379 380 381
}

/**
Matthias Hutterer's avatar
Matthias Hutterer committed
382
 * Implements hook_mail().
383 384 385
 */
function email_mail($key, &$message, $params) {
  $language = $message['language'];
Matthias Hutterer's avatar
Matthias Hutterer committed
386
  switch ($key) {
387 388
    case 'contact':
      // Compose the body:
389 390
      $message['body'][] = t('@name sent a message using the contact form at @url.', array('@name' => $params['name'], '@url' => $params['url']), array('langcode' =>$language->language));
      $message['body'][] = $params['message'];
Matthias Hutterer's avatar
Matthias Hutterer committed
391 392 393
      $message['subject'] = "";

      // Include the title of the entity, if one exists
394 395
      $object = $params['object'];
      if (isset($object->title) && !empty($object->title)) {
Matthias Hutterer's avatar
Matthias Hutterer committed
396
        $message['subject'] = "[" . check_plain(preg_replace("/\r|\n/", '', $object->title)) . "]";
397 398
      }
      $message['subject'] .= " " . check_plain($params['subject']);
399 400
      break;
  }
401
}
Matthias Hutterer's avatar
Matthias Hutterer committed
402 403


404 405
//TODO Token support

Matthias Hutterer's avatar
Matthias Hutterer committed
406
/**
Matthias Hutterer's avatar
Matthias Hutterer committed
407
 * Implements hook_token_list().
408
 *
Matthias Hutterer's avatar
Matthias Hutterer committed
409 410
function email_token_list($type = 'all') {
  if ($type == 'field' || $type == 'all') {
411 412
    $tokens['email']['raw']       = t('Raw email address');
    $tokens['email']['formatted'] = t('Formatted email address');
Matthias Hutterer's avatar
Matthias Hutterer committed
413 414 415 416 417
    return $tokens;
  }
}

/**
Matthias Hutterer's avatar
Matthias Hutterer committed
418
 * Implements hook token_values().
419
 *
Matthias Hutterer's avatar
Matthias Hutterer committed
420 421 422
function email_token_values($type, $object = NULL, $options = array()) {
  if ($type == 'field') {
    $item = $object[0];
423 424
    $tokens['raw']       = $item['email'];
    $tokens['formatted'] = $item['view'];
Matthias Hutterer's avatar
Matthias Hutterer committed
425 426 427
    return $tokens;
  }
}
Matthias Hutterer's avatar
Matthias Hutterer committed
428 429
 */

430 431 432 433 434 435 436 437 438 439 440 441
/**
 * Settings for contact form
 */
function email_admin_settings() {
  $form['email_hourly_threshold'] = array('#type' => 'select',
    '#title' => t('Hourly threshold for a CCK Email contact form'),
    '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50)),
    '#default_value' => variable_get('email_hourly_threshold', 3),
    '#description' => t('The maximum number of contact form submissions a user can perform per hour.'),
  );
  return system_settings_form($form);
}
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458


/**
 * Implements hook_content_migrate_instance_alter().
 *
 * D6-D7 upgrade
 * fixes new formatter names
 */
function email_content_migrate_instance_alter(&$instance_value, &$field_value) {
  if ($field_value['module'] == 'email') {
    foreach ($instance_value['display'] as $context => $settings) {
      if (in_array($instance_value['display'][$context]['type'], array('default', 'plain', 'contact', 'spamspan'))) {
        $instance_value['display'][$context]['type'] = 'email_' . $instance_value['display'][$context]['type'];
      }
    }
  }
}