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

Matthias Hutterer's avatar
Matthias Hutterer committed
3
// $Id$
Matthias Hutterer's avatar
Matthias Hutterer committed
4

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

/**
20
 * Implements hook_field_schema().
Matthias Hutterer's avatar
Matthias Hutterer committed
21
 */
22
function email_field_schema($field) {
Matthias Hutterer's avatar
Matthias Hutterer committed
23
  return array(
24
25
26
27
28
    'columns' => array(
      'email' => array(
        'type' => 'varchar',
         'length' => 255,
         'not null' => FALSE,
29
30
31
      ),
    ),
  );
Matthias Hutterer's avatar
Matthias Hutterer committed
32
33
34
}

/**
35
36
37
38
 * Implements hook_field_validate().
 *
 * Possible error codes:
 * - 'email_invalid': The email address is not valid
Matthias Hutterer's avatar
Matthias Hutterer committed
39
 */
40
41
42
43
44
45
46
47
48
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
49
50
  }
}
51
52
53
/**
 * Implementation of hook_field().
 */
54
function email_field($op, &$node, $field, &$items, $teaser, $page) {
55
  switch ($op) {
56
57
    case 'validate':
      if (is_array($items)) {
58
59
60
        foreach ($items as $delta => $item) {
          if ($item['email'] != '' && !valid_email_address(trim($item['email']))) {
            form_set_error($field['field_name'],t('"%mail" is not a valid email address',array('%mail' => $item['email'])));
61
          }
62
63
64
        }
     }
     break;
65
66
67

    case 'sanitize':
      foreach ($items as $delta => $item) {
68
        $items[$delta]['safe'] = check_plain($item['email']);
69
70
71
72
73
74
      }
      break;
  }
}

/**
75
 * Implements of hook_content_is_empty().
76
 */
77
function email_field_is_empty($item, $field) {
78
79
80
81
82
  if (empty($item['email'])) {
    return TRUE;
  }
  return FALSE;
}
Matthias Hutterer's avatar
Matthias Hutterer committed
83

84
/**
85
 * Implements hook_field_formatter_info().
86
87
88
 *
 */
function email_field_formatter_info() {
89
  $formats = array(
90
    'default' => array(
91
      'label' => t('Default email link'),
92
93
94
      'field types' => array('email'),
    ),
    'contact' => array(
95
      'label' => t('Email contact form'),
96
97
98
      'field types' => array('email'),
    ),
  );
99
100
101
102
103
104
  if (module_exists('spamspan')) {
    $formats += array(
      'spamspan' => array(
        'label' => t('Email SpamSpan'),
        'field types' => array('email'),
      ),
105
106
107
    );
  }
  return $formats;
108
}
Matthias Hutterer's avatar
Matthias Hutterer committed
109

110
/**
111
 * Implements hook_field_formatter_view().
112
 */
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
function email_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
  $element = array();
  switch ($display['type']) {
    case 'default':
      foreach ($items as $delta => $item) {
        $output = l($item['email'], 'mailto:'. $item['email']);
        $element[$delta] = array('#markup' => $output);
      }
      break;
      
    case 'contact':
      foreach ($items as $delta => $item) {
        //TODO at the moment only nodes as object type
        $element[$delta] = l(t('Email contact form'), 'email/'. $object->nid .'/'. $instance['field_name']);
      }
      break;
      
    case 'spamspan':
      foreach ($items as $delta => $item) {
        if (module_exists('spamspan')) {
          $element[$delta] = spamspan($item['email']);
        }
        else {
          $output = l($item['email'], 'mailto:'. $item['email']);
          $element[$delta] = array('#markup' => $output);
        }
      }
      break;
Matthias Hutterer's avatar
Matthias Hutterer committed
141
  }
142
  return $element;   
143
144
}

Matthias Hutterer's avatar
Matthias Hutterer committed
145
146

/**
147
 * Implements hook_field_widget_info().
Matthias Hutterer's avatar
Matthias Hutterer committed
148
 */
149
function email_field_widget_info() {
Matthias Hutterer's avatar
Matthias Hutterer committed
150
  return array(
151
152
    'email_textfield' => array(
      'label' => t('Text field'),
Matthias Hutterer's avatar
Matthias Hutterer committed
153
      'field types' => array('email'),
154
      'settings' => array('size' => 60),
Matthias Hutterer's avatar
Matthias Hutterer committed
155
156
157
158
    ),
  );
}

159
/**
160
 * Implements hook_field_widget_settings_form().
161
 */
162
163
164
165
166
167
168
169
170
171
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'),
172
  );
173
  return $form;
174
}
Matthias Hutterer's avatar
Matthias Hutterer committed
175
176

/**
177
 * Implements hook_field_widget_form().
Matthias Hutterer's avatar
Matthias Hutterer committed
178
 */
179
180
181
182
183
184
185
186
187
188
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
189
190
}

191

192

Matthias Hutterer's avatar
Matthias Hutterer committed
193
194
195
/**
 * Implementation of hook_widget().
 */
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
function email_widget(&$form, &$form_state, $field, $items, $delta = 0) {
  $element = array(
    '#type' => $field['widget']['type'],
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
  );
  return $element;
}

/**
 * Process an individual element.
 */
function email_textfield_process($element, $edit, $form_state, $form) {
  $field = $form['#field_info'][$element['#field_name']];
  $field_key = $element['#columns'][0];
  $delta = $element['#delta'];
  $element[$field_key] = array(
    '#type' => 'textfield',
213
214
    '#title' => $element['#title'],
    '#description' => content_filter_xss($field['widget']['description']),
215
    '#required' => $element['#required'],
216
    '#maxlength' => 255,
217
    '#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60,
218
    '#attributes' => array('class' => 'text', 'dir' => 'ltr'),
219
220
221
222
223
    '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL,
  );
  return $element;
}

224
225
226
/**
 * Implementation of hook_menu().
 */
227
228
function email_menu() {
  $items['email/%/%'] = array(
229
    'title' => 'Email Contact Form',
230
231
    'page callback' => 'email_mail_page',
    'page arguments' => array(1, 2),
232
233
    'access callback' => 'user_access',
    'access arguments' => array('access content'),
234
235
    'type' => MENU_CALLBACK,
  );
236
237
  $items['admin/config/content/email'] = array(
    'title' => 'Email Contact Form Settings',
238
239
240
241
242
    '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'),
  );
243
244
245
  return $items;
}

246

247
248
249
/**
 * The contact form page.
 */
250
function email_mail_page($nid, $field_name) {
251
  if (!is_numeric($nid)) {
252
253
254
    drupal_not_found();
    return;
  }
255
256
257
258
259
260
  if (module_exists('content_permissions')) {
    if (!user_access('view '. $field_name)) {
      drupal_not_found();
      return;
    }
  }
Matthias Hutterer's avatar
Matthias Hutterer committed
261
  $node = node_load(intval($nid));
262
263
264
265
  if (!$node) {
    drupal_not_found();
    return;
  }
266
  $field = array_pop($node->$field_name);
267
  $email = $field[0]['email'];
268
269
270
  
  //TODO
  /*$types = content_types($node->type);
271
272
  // Validate field name
  $types = content_types($node->type);
273
274
275
276
277
  if (empty($email) ||
      !isset($types['fields'][$field_name]) ||
      $types['fields'][$field_name]['type'] != 'email' ||
      ($types['fields'][$field_name]['display_settings']['teaser']['format'] != 'contact' &&
      $types['fields'][$field_name]['display_settings']['full']['format'] != 'contact')) {
278
279
    drupal_not_found();
    return;
280
  }*/
281

282
283
284
285
286

  if (!flood_is_allowed('email', variable_get('email_hourly_threshold', 3))) {
    $output = t("You cannot send more than %number messages per hour. Please try again later.", array('%number' => variable_get('email_hourly_threshold', 3)));
  }
  else {
287
    $output = drupal_get_form('email_mail_page_form', $node, $field_name, $email);
288
289
290
291
292
  }

  return $output;
}

293
294
295
/**
 * Contact form
 */
296
function email_mail_page_form($form_state, $args) {
Matthias Hutterer's avatar
Matthias Hutterer committed
297
  global $user;
298
299
300
301
302
303
  
  $node = $args['build_info']['args'][0];
  $field_name = $args['build_info']['args'][1];
  $email = $args['build_info']['args'][2];
  
  $form['nid'] = array(
304
    '#type' => 'value',
305
    '#value' => $node->nid,
306
  );
307
  $form['field_name'] = array(
308
    '#type' => 'value',
309
310
311
312
313
    '#value' => $field_name,
  );
  $form['email'] = array(
    '#type' => 'value',
    '#value' => $email,
314
315
316
  );
  $form['name'] = array(
    '#type' => 'textfield',
Matthias Hutterer's avatar
Matthias Hutterer committed
317
318
    '#title' => t('Your name'),
    '#maxlength' => 255,
319
    '#default_value' => $user->uid ? $user->name : '',
Matthias Hutterer's avatar
Matthias Hutterer committed
320
321
    '#required' => TRUE,
  );
322
323
  $form['mail'] = array(
    '#type' => 'textfield',
Matthias Hutterer's avatar
Matthias Hutterer committed
324
325
    '#title' => t('Your e-mail address'),
    '#maxlength' => 255,
326
    '#default_value' => $user->uid ? $user->mail : '',
Matthias Hutterer's avatar
Matthias Hutterer committed
327
328
    '#required' => TRUE,
  );
329
330
  $form['subject'] = array(
    '#type' => 'textfield',
Matthias Hutterer's avatar
Matthias Hutterer committed
331
332
333
334
    '#title' => t('Subject'),
    '#maxlength' => 255,
    '#required' => TRUE,
  );
335
336
  $form['message'] = array(
    '#type' => 'textarea',
Matthias Hutterer's avatar
Matthias Hutterer committed
337
338
339
    '#title' => t('Message'),
    '#required' => TRUE,
  );
340
341
  $form['submit'] = array(
    '#type' => 'submit',
Matthias Hutterer's avatar
Matthias Hutterer committed
342
    '#value' => t('Send e-mail'),
343
344
    '#validate' => array('email_mail_page_form_validate'),
    '#submit' => array('email_mail_page_form_submit'),
Matthias Hutterer's avatar
Matthias Hutterer committed
345
346
347
348
  );
  return $form;
}

349
350
351
/**
 * Validate the site-wide contact page form submission.
 */
352
353
function email_mail_page_form_validate($form, &$form_state) {
  if (!valid_email_address($form_state['values']['mail'])) {
354
355
    form_set_error('mail', t('You must enter a valid e-mail address.'));
  }
356
  if (preg_match("/\r|\n/", $form_state['values']['subject'])) {
Matthias Hutterer's avatar
Matthias Hutterer committed
357
    form_set_error('subject', t('The subject cannot contain linebreaks.'));
358
    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
359
  }
360
361
362
363
364
}

/**
 * Process the site-wide contact page form submission.
 */
365
function email_mail_page_form_submit($form, &$form_state) {
366
  $node = node_load($form_state['values']['nid']);
367
368
369
  $field_name = $form_state['values']['field_name'];
  $email = $form_state['values']['email'];
  
370
371
372
  // 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.

373
374
375
376
377
378
379
380
  $from = $form_state['values']['mail'];
 
  $params['node'] = $node;
  $params['subject'] = $form_state['values']['subject'];
  $params['name'] = $form_state['values']['name'];
  $params['message'] = $form_state['values']['message'];
  $params['url'] = url('node/' . $node->nid, array('absolute' => TRUE));
   
381
  // Send the e-mail to the recipients:
382
383
  drupal_mail('email', 'contact', $email, language_default(), $params, $from);
 
384
385
  // Log the operation:
  flood_register_event('email');
386
387
  watchdog('mail', t('%name-from sent an e-mail at %form.', array('%name-from' => theme('placeholder', $form_state['values']['name'] ." <$from>"), '%form' => url($_GET['q'], array('absolute' => TRUE)))));
 
388
389
  // Update user:
  drupal_set_message(t('Your message has been sent.'));
390
 
391
  // Jump to home page rather than back to contact page to avoid contradictory messages if flood control has been activated.
392
393
394
395
396
397
398
399
400
401
402
403
  $form_state['redirect'] = 'node/'. $node->nid;
}

/**
 * Implementation of hook_mail()
 */
function email_mail($key, &$message, $params) {
  $language = $message['language'];
  switch($key) {
    case 'contact':
      $node = $params['node'];
      // Compose the body:
404
      $msg[] = t('@name sent a message using the contact form at @node.', array('@name' => $params['name'], '@node' => $params['url']), array('langcode' =>$language->language));
405
406
407
408
409
410
411
412
413
414
      $msg[] = $params['message'];

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

      // Prepare the body:
      $message['body'] = implode("\n\n", $msg);
      
415
      $message['subject'] = t('[@title] @subject', array('@title' => preg_replace("/\r|\n/",'', $node->title), '@subject' => $params['subject']), array('langcode' =>$language->language));
416
417
      break;
  }
418
}
Matthias Hutterer's avatar
Matthias Hutterer committed
419
420


421
422
//TODO Token support

Matthias Hutterer's avatar
Matthias Hutterer committed
423
/**
424
425
 * Implements of hook_token_list()
 *
Matthias Hutterer's avatar
Matthias Hutterer committed
426
427
function email_token_list($type = 'all') {
  if ($type == 'field' || $type == 'all') {
428
429
    $tokens['email']['raw']       = t('Raw email address');
    $tokens['email']['formatted'] = t('Formatted email address');
Matthias Hutterer's avatar
Matthias Hutterer committed
430
431
432
433
434
    return $tokens;
  }
}

/**
435
436
 * Implements of hook token_values().
 *
Matthias Hutterer's avatar
Matthias Hutterer committed
437
438
439
function email_token_values($type, $object = NULL, $options = array()) {
  if ($type == 'field') {
    $item = $object[0];
440
441
    $tokens['raw']       = $item['email'];
    $tokens['formatted'] = $item['view'];
Matthias Hutterer's avatar
Matthias Hutterer committed
442
443
444
    return $tokens;
  }
}
445
*/
446
447
448
449
450
451
452
453
454
455
456
457
/**
 * 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);
}