1 | <?php |
---|
2 | |
---|
3 | |
---|
4 | |
---|
5 | /** |
---|
6 | * Implementation of hook_theme(). |
---|
7 | */ |
---|
8 | function email_theme() { |
---|
9 | return array( |
---|
10 | 'email_textfield' => array( |
---|
11 | 'arguments' => array('element' => NULL), |
---|
12 | ), |
---|
13 | 'email_formatter_default' => array( |
---|
14 | 'arguments' => array('element' => NULL), |
---|
15 | ), |
---|
16 | 'email_formatter_spamspan' => array( |
---|
17 | 'arguments' => array('element' => NULL), |
---|
18 | ), |
---|
19 | 'email_formatter_contact' => array( |
---|
20 | 'arguments' => array('element' => NULL), |
---|
21 | ), |
---|
22 | 'email_formatter_plain' => array( |
---|
23 | 'arguments' => array('element' => NULL), |
---|
24 | ), |
---|
25 | ); |
---|
26 | } |
---|
27 | |
---|
28 | /** |
---|
29 | * Implementation of hook_field_info(). |
---|
30 | */ |
---|
31 | function email_field_info() { |
---|
32 | return array( |
---|
33 | 'email' => array( |
---|
34 | 'label' => 'Email', |
---|
35 | 'callbacks' => array( |
---|
36 | 'tables' => CONTENT_CALLBACK_DEFAULT, |
---|
37 | 'arguments' => CONTENT_CALLBACK_DEFAULT, |
---|
38 | ), |
---|
39 | ), |
---|
40 | ); |
---|
41 | } |
---|
42 | |
---|
43 | |
---|
44 | /** |
---|
45 | * Implementation of hook_field_settings(). |
---|
46 | */ |
---|
47 | function email_field_settings($op, $field) { |
---|
48 | switch ($op) { |
---|
49 | case 'database columns': |
---|
50 | $columns['email'] = array('type' => 'varchar', 'length' => 255, 'not null' => FALSE, 'sortable' => TRUE); |
---|
51 | return $columns; |
---|
52 | } |
---|
53 | } |
---|
54 | |
---|
55 | /** |
---|
56 | * Implementation of hook_field(). |
---|
57 | */ |
---|
58 | function email_field($op, &$node, $field, &$items, $teaser, $page) { |
---|
59 | switch ($op) { |
---|
60 | case 'validate': |
---|
61 | if (is_array($items)) { |
---|
62 | foreach ($items as $delta => $item) { |
---|
63 | if ($item['email'] != '' && !valid_email_address(trim($item['email']))) { |
---|
64 | form_set_error($field['field_name'],t('"%mail" is not a valid email address',array('%mail' => $item['email']))); |
---|
65 | } |
---|
66 | } |
---|
67 | } |
---|
68 | break; |
---|
69 | |
---|
70 | case 'sanitize': |
---|
71 | foreach ($items as $delta => $item) { |
---|
72 | $items[$delta]['safe'] = check_plain($item['email']); |
---|
73 | } |
---|
74 | break; |
---|
75 | } |
---|
76 | } |
---|
77 | |
---|
78 | /** |
---|
79 | * Implementation of hook_content_is_empty(). |
---|
80 | */ |
---|
81 | function email_content_is_empty($item, $field) { |
---|
82 | if (empty($item['email'])) { |
---|
83 | return TRUE; |
---|
84 | } |
---|
85 | return FALSE; |
---|
86 | } |
---|
87 | |
---|
88 | /** |
---|
89 | * Implementation of hook_field_formatter_info(). |
---|
90 | * |
---|
91 | */ |
---|
92 | function email_field_formatter_info() { |
---|
93 | $formats = array( |
---|
94 | 'default' => array( |
---|
95 | 'label' => t('Default email link'), |
---|
96 | 'field types' => array('email'), |
---|
97 | 'multiple values' => CONTENT_HANDLE_CORE, |
---|
98 | ), |
---|
99 | 'contact' => array( |
---|
100 | 'label' => t('Email contact form'), |
---|
101 | 'field types' => array('email'), |
---|
102 | 'multiple values' => CONTENT_HANDLE_CORE, |
---|
103 | ), |
---|
104 | 'plain' => array( |
---|
105 | 'label' => t('Email plain text'), |
---|
106 | 'field types' => array('email'), |
---|
107 | 'multiple values' => CONTENT_HANDLE_CORE, |
---|
108 | ), |
---|
109 | ); |
---|
110 | if (module_exists('spamspan')) { |
---|
111 | $formats += array( |
---|
112 | 'spamspan' => array( |
---|
113 | 'label' => t('Email SpamSpan'), |
---|
114 | 'field types' => array('email'), |
---|
115 | 'multiple values' => CONTENT_HANDLE_CORE, |
---|
116 | ), |
---|
117 | ); |
---|
118 | } |
---|
119 | return $formats; |
---|
120 | } |
---|
121 | |
---|
122 | /** |
---|
123 | * Theme function for 'default' email field formatter. |
---|
124 | */ |
---|
125 | function theme_email_formatter_default($element) { |
---|
126 | return !empty($element['#item']['safe']) ? l($element['#item']['email'], "mailto:" . $element['#item']['email']) : ''; |
---|
127 | } |
---|
128 | |
---|
129 | /** |
---|
130 | * Theme function for 'spamspan' email field formatter. |
---|
131 | */ |
---|
132 | function theme_email_formatter_spamspan($element) { |
---|
133 | if (empty($element['#item']['safe'])) { |
---|
134 | return ''; |
---|
135 | } |
---|
136 | if (module_exists('spamspan')) { |
---|
137 | return spamspan($element['#item']['email']); |
---|
138 | } |
---|
139 | else { |
---|
140 | return l($element['#item']['email'], "mailto:" . $element['#item']['email']); |
---|
141 | } |
---|
142 | } |
---|
143 | |
---|
144 | /** |
---|
145 | * Theme function for 'contact' email field formatter. |
---|
146 | */ |
---|
147 | function theme_email_formatter_contact($element) { |
---|
148 | return !empty($element['#item']['safe']) ? l(t('Email contact form'), 'email/'. $element['#node']->nid .'/'. $element['#field_name']) : ''; |
---|
149 | } |
---|
150 | |
---|
151 | /** |
---|
152 | * Theme function for 'plain' email field formatter. |
---|
153 | */ |
---|
154 | function theme_email_formatter_plain($element) { |
---|
155 | return !empty($element['#item']['safe']) ? $element['#item']['safe'] : ''; |
---|
156 | } |
---|
157 | |
---|
158 | |
---|
159 | /** |
---|
160 | * Implementation of hook_widget_info(). |
---|
161 | */ |
---|
162 | function email_widget_info() { |
---|
163 | return array( |
---|
164 | 'email_textfield' => array( |
---|
165 | 'label' => t('Text field'), |
---|
166 | 'field types' => array('email'), |
---|
167 | 'multiple values' => CONTENT_HANDLE_CORE, |
---|
168 | 'callbacks' => array( |
---|
169 | 'default value' => CONTENT_CALLBACK_DEFAULT, |
---|
170 | ), |
---|
171 | ), |
---|
172 | ); |
---|
173 | } |
---|
174 | |
---|
175 | /** |
---|
176 | * Implementation of FAPI hook_elements(). |
---|
177 | */ |
---|
178 | function email_elements() { |
---|
179 | return array( |
---|
180 | 'email_textfield' => array( |
---|
181 | '#input' => TRUE, |
---|
182 | '#columns' => array('email'), |
---|
183 | '#delta' => 0, |
---|
184 | '#process' => array('email_textfield_process'), |
---|
185 | ), |
---|
186 | ); |
---|
187 | } |
---|
188 | |
---|
189 | /** |
---|
190 | * Implementation of hook_widget_settings(). |
---|
191 | */ |
---|
192 | function email_widget_settings($op, $widget) { |
---|
193 | switch ($op) { |
---|
194 | case 'form': |
---|
195 | $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; |
---|
196 | $form['size'] = array( |
---|
197 | '#type' => 'textfield', |
---|
198 | '#title' => t('Size of textfield'), |
---|
199 | '#default_value' => $size, |
---|
200 | '#element_validate' => array('_email_widget_settings_size_validate'), |
---|
201 | '#required' => TRUE, |
---|
202 | ); |
---|
203 | return $form; |
---|
204 | |
---|
205 | case 'save': |
---|
206 | return array('size'); |
---|
207 | } |
---|
208 | } |
---|
209 | |
---|
210 | function _email_widget_settings_size_validate($element, &$form_state) { |
---|
211 | $value = $form_state['values']['size']; |
---|
212 | if (!is_numeric($value) || intval($value) != $value || $value <= 0) { |
---|
213 | form_error($element, t('"Size" must be a positive integer.')); |
---|
214 | } |
---|
215 | } |
---|
216 | |
---|
217 | /** |
---|
218 | * Implementation of hook_widget(). |
---|
219 | */ |
---|
220 | function email_widget(&$form, &$form_state, $field, $items, $delta = 0) { |
---|
221 | $element = array( |
---|
222 | '#type' => $field['widget']['type'], |
---|
223 | '#default_value' => isset($items[$delta]) ? $items[$delta] : '', |
---|
224 | ); |
---|
225 | return $element; |
---|
226 | } |
---|
227 | |
---|
228 | /** |
---|
229 | * Process an individual element. |
---|
230 | */ |
---|
231 | function email_textfield_process($element, $edit, $form_state, $form) { |
---|
232 | $field = $form['#field_info'][$element['#field_name']]; |
---|
233 | $field_key = $element['#columns'][0]; |
---|
234 | $delta = $element['#delta']; |
---|
235 | $element[$field_key] = array( |
---|
236 | '#type' => 'textfield', |
---|
237 | '#title' => $element['#title'], |
---|
238 | '#description' => content_filter_xss($field['widget']['description']), |
---|
239 | '#required' => $element['#required'], |
---|
240 | '#maxlength' => 255, |
---|
241 | '#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60, |
---|
242 | '#attributes' => array('class' => 'text', 'dir' => 'ltr'), |
---|
243 | '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, |
---|
244 | ); |
---|
245 | return $element; |
---|
246 | } |
---|
247 | |
---|
248 | /** |
---|
249 | * FAPI theme for an individual text elements. |
---|
250 | */ |
---|
251 | function theme_email_textfield($element) { |
---|
252 | return $element['#children']; |
---|
253 | } |
---|
254 | |
---|
255 | /** |
---|
256 | * Implementation of hook_menu(). |
---|
257 | */ |
---|
258 | function email_menu() { |
---|
259 | $items['email/%node/%'] = array( |
---|
260 | 'title' => 'Email Contact Form', |
---|
261 | 'page callback' => 'email_mail_page', |
---|
262 | 'page arguments' => array(1, 2), |
---|
263 | 'access callback' => 'node_access', |
---|
264 | 'access arguments' => array('view', 1), |
---|
265 | 'type' => MENU_CALLBACK, |
---|
266 | ); |
---|
267 | $items['admin/settings/email'] = array( |
---|
268 | 'title' => 'CCK Email Contact Form Settings', |
---|
269 | 'description' => 'Administer flood control settings for email contact forms', |
---|
270 | 'page callback' => 'drupal_get_form', |
---|
271 | 'page arguments' => array('email_admin_settings'), |
---|
272 | 'access arguments' => array('administer site configuration'), |
---|
273 | ); |
---|
274 | return $items; |
---|
275 | } |
---|
276 | |
---|
277 | |
---|
278 | /** |
---|
279 | * The contact form page. |
---|
280 | * |
---|
281 | * @param $node |
---|
282 | * The node object on which the email address is stored. |
---|
283 | * @param $field_name |
---|
284 | * The name of the CCK field which holds the email address. |
---|
285 | * |
---|
286 | * @return |
---|
287 | * Rendered page output containing either the contact form or a flood warning. |
---|
288 | */ |
---|
289 | function email_mail_page($node, $field_name) { |
---|
290 | $field_info = content_fields($field_name, $node->type); |
---|
291 | if (empty($field_info) || $field_info['type'] != 'email') { |
---|
292 | return MENU_NOT_FOUND; |
---|
293 | } |
---|
294 | |
---|
295 | // Check the field access using CCK's content_access function. |
---|
296 | if (!content_access('view', $field_info, NULL, $node)) { |
---|
297 | return MENU_ACCESS_DENIED; |
---|
298 | } |
---|
299 | |
---|
300 | // Check if the node has an email address. |
---|
301 | $email = isset($node->{$field_name}[0]['email']) ? $node->{$field_name}[0]['email'] : ''; |
---|
302 | if (empty($email)) { |
---|
303 | return MENU_NOT_FOUND; |
---|
304 | } |
---|
305 | |
---|
306 | // Check the formatters. |
---|
307 | if ($field_info['display_settings']['teaser']['format'] != 'contact' && |
---|
308 | $field_info['display_settings']['full']['format'] != 'contact') { |
---|
309 | return MENU_NOT_FOUND; |
---|
310 | } |
---|
311 | |
---|
312 | if (!flood_is_allowed('email', variable_get('email_hourly_threshold', 3))) { |
---|
313 | $output = t("You cannot send more than %number messages per hour. Please try again later.", array('%number' => variable_get('email_hourly_threshold', 3))); |
---|
314 | } |
---|
315 | else { |
---|
316 | $output = drupal_get_form('email_mail_page_form', $node, $field_name, $email); |
---|
317 | } |
---|
318 | |
---|
319 | return $output; |
---|
320 | } |
---|
321 | |
---|
322 | /** |
---|
323 | * Contact form |
---|
324 | */ |
---|
325 | function email_mail_page_form($form_state, $node, $field_name, $email) { |
---|
326 | global $user; |
---|
327 | |
---|
328 | $form['node'] = array( |
---|
329 | '#type' => 'value', |
---|
330 | '#value' => $node, |
---|
331 | ); |
---|
332 | $form['field_name'] = array( |
---|
333 | '#type' => 'value', |
---|
334 | '#value' => $field_name, |
---|
335 | ); |
---|
336 | $form['email'] = array( |
---|
337 | '#type' => 'value', |
---|
338 | '#value' => $email, |
---|
339 | ); |
---|
340 | $form['name'] = array( |
---|
341 | '#type' => 'textfield', |
---|
342 | '#title' => t('Your name'), |
---|
343 | '#maxlength' => 255, |
---|
344 | '#default_value' => $user->uid ? $user->name : '', |
---|
345 | '#required' => TRUE, |
---|
346 | ); |
---|
347 | $form['mail'] = array( |
---|
348 | '#type' => 'textfield', |
---|
349 | '#title' => t('Your e-mail address'), |
---|
350 | '#maxlength' => 255, |
---|
351 | '#default_value' => $user->uid ? $user->mail : '', |
---|
352 | '#required' => TRUE, |
---|
353 | ); |
---|
354 | $form['subject'] = array( |
---|
355 | '#type' => 'textfield', |
---|
356 | '#title' => t('Subject'), |
---|
357 | '#maxlength' => 255, |
---|
358 | '#required' => TRUE, |
---|
359 | ); |
---|
360 | $form['message'] = array( |
---|
361 | '#type' => 'textarea', |
---|
362 | '#title' => t('Message'), |
---|
363 | '#required' => TRUE, |
---|
364 | ); |
---|
365 | $form['submit'] = array( |
---|
366 | '#type' => 'submit', |
---|
367 | '#value' => t('Send e-mail'), |
---|
368 | '#validate' => array('email_mail_page_form_validate'), |
---|
369 | '#submit' => array('email_mail_page_form_submit'), |
---|
370 | ); |
---|
371 | return $form; |
---|
372 | } |
---|
373 | |
---|
374 | /** |
---|
375 | * Validate the site-wide contact page form submission. |
---|
376 | */ |
---|
377 | function email_mail_page_form_validate($form, &$form_state) { |
---|
378 | if (!valid_email_address($form_state['values']['mail'])) { |
---|
379 | form_set_error('mail', t('You must enter a valid e-mail address.')); |
---|
380 | } |
---|
381 | if (preg_match("/\r|\n/", $form_state['values']['subject'])) { |
---|
382 | form_set_error('subject', t('The subject cannot contain linebreaks.')); |
---|
383 | watchdog('mail', 'Email injection exploit attempted in email form subject: '. check_plain($form_state['values']['subject']), WATCHDOG_NOTICE); |
---|
384 | } |
---|
385 | } |
---|
386 | |
---|
387 | /** |
---|
388 | * Process the site-wide contact page form submission. |
---|
389 | */ |
---|
390 | function email_mail_page_form_submit($form, &$form_state) { |
---|
391 | $node = $form_state['values']['node']; |
---|
392 | $field_name = $form_state['values']['field_name']; |
---|
393 | $email = $form_state['values']['email']; |
---|
394 | |
---|
395 | // E-mail address of the sender: as the form field is a text field, |
---|
396 | // all instances of \r and \n have been automatically stripped from it. |
---|
397 | |
---|
398 | $from = $form_state['values']['mail']; |
---|
399 | |
---|
400 | $params['node'] = $node; |
---|
401 | $params['subject'] = $form_state['values']['subject']; |
---|
402 | $params['name'] = $form_state['values']['name']; |
---|
403 | $params['message'] = $form_state['values']['message']; |
---|
404 | $params['url'] = url('node/' . $node->nid, array('absolute' => TRUE)); |
---|
405 | |
---|
406 | // Send the e-mail to the recipients: |
---|
407 | drupal_mail('email', 'contact', $email, language_default(), $params, $from); |
---|
408 | |
---|
409 | // Log the operation: |
---|
410 | flood_register_event('email'); |
---|
411 | 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))))); |
---|
412 | |
---|
413 | // Update user: |
---|
414 | drupal_set_message(t('Your message has been sent.')); |
---|
415 | |
---|
416 | // Jump to home page rather than back to contact page to avoid contradictory messages if flood control has been activated. |
---|
417 | $form_state['redirect'] = 'node/'. $node->nid; |
---|
418 | } |
---|
419 | |
---|
420 | /** |
---|
421 | * Implementation of hook_mail() |
---|
422 | */ |
---|
423 | function email_mail($key, &$message, $params) { |
---|
424 | $language = $message['language']; |
---|
425 | switch($key) { |
---|
426 | case 'contact': |
---|
427 | $node = $params['node']; |
---|
428 | // Compose the body: |
---|
429 | $msg[] = t('@name sent a message using the contact form at @node.', array('@name' => $params['name'], '@node' => $params['url']), $language->language); |
---|
430 | $msg[] = $params['message']; |
---|
431 | |
---|
432 | // Tidy up the body: |
---|
433 | foreach ($msg as $index_key => $value) { |
---|
434 | $msg[$index_key] = wordwrap($value); |
---|
435 | } |
---|
436 | |
---|
437 | // Prepare the body: |
---|
438 | $message['body'] = implode("\n\n", $msg); |
---|
439 | |
---|
440 | $message['subject'] = t('[@title] @subject', array('@title' => preg_replace("/\r|\n/",'', $node->title), '@subject' => $params['subject']), $language->language); |
---|
441 | break; |
---|
442 | } |
---|
443 | } |
---|
444 | |
---|
445 | |
---|
446 | /** |
---|
447 | * Implementation of hook token_list |
---|
448 | */ |
---|
449 | function email_token_list($type = 'all') { |
---|
450 | if ($type == 'field' || $type == 'all') { |
---|
451 | $tokens['email']['raw'] = t('Raw email address'); |
---|
452 | $tokens['email']['formatted'] = t('Formatted email address'); |
---|
453 | return $tokens; |
---|
454 | } |
---|
455 | } |
---|
456 | |
---|
457 | /** |
---|
458 | * Implementation of hook token_values |
---|
459 | */ |
---|
460 | function email_token_values($type, $object = NULL, $options = array()) { |
---|
461 | if ($type == 'field') { |
---|
462 | $item = $object[0]; |
---|
463 | $tokens['raw'] = $item['email']; |
---|
464 | $tokens['formatted'] = $item['view']; |
---|
465 | return $tokens; |
---|
466 | } |
---|
467 | } |
---|
468 | |
---|
469 | /** |
---|
470 | * Settings for contact form |
---|
471 | */ |
---|
472 | function email_admin_settings() { |
---|
473 | $form['email_hourly_threshold'] = array('#type' => 'select', |
---|
474 | '#title' => t('Hourly threshold for a CCK Email contact form'), |
---|
475 | '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50)), |
---|
476 | '#default_value' => variable_get('email_hourly_threshold', 3), |
---|
477 | '#description' => t('The maximum number of contact form submissions a user can perform per hour.'), |
---|
478 | ); |
---|
479 | return system_settings_form($form); |
---|
480 | } |
---|