[177a560] | 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 | } |
---|