array( 'arguments' => array('element' => NULL), ), 'email_formatter_default' => array( 'arguments' => array('element' => NULL), ), 'email_formatter_spamspan' => array( 'arguments' => array('element' => NULL), ), 'email_formatter_contact' => array( 'arguments' => array('element' => NULL), ), 'email_formatter_plain' => array( 'arguments' => array('element' => NULL), ), ); } /** * Implementation of hook_field_info(). */ function email_field_info() { return array( 'email' => array( 'label' => 'Email', 'callbacks' => array( 'tables' => CONTENT_CALLBACK_DEFAULT, 'arguments' => CONTENT_CALLBACK_DEFAULT, ), ), ); } /** * Implementation of hook_field_settings(). */ function email_field_settings($op, $field) { switch ($op) { case 'database columns': $columns['email'] = array('type' => 'varchar', 'length' => 255, 'not null' => FALSE, 'sortable' => TRUE); return $columns; } } /** * Implementation of hook_field(). */ function email_field($op, &$node, $field, &$items, $teaser, $page) { switch ($op) { case 'validate': if (is_array($items)) { 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']))); } } } break; case 'sanitize': foreach ($items as $delta => $item) { $items[$delta]['safe'] = check_plain($item['email']); } break; } } /** * Implementation of hook_content_is_empty(). */ function email_content_is_empty($item, $field) { if (empty($item['email'])) { return TRUE; } return FALSE; } /** * Implementation of hook_field_formatter_info(). * */ function email_field_formatter_info() { $formats = array( 'default' => array( 'label' => t('Default email link'), 'field types' => array('email'), 'multiple values' => CONTENT_HANDLE_CORE, ), 'contact' => array( 'label' => t('Email contact form'), 'field types' => array('email'), 'multiple values' => CONTENT_HANDLE_CORE, ), 'plain' => array( 'label' => t('Email plain text'), 'field types' => array('email'), 'multiple values' => CONTENT_HANDLE_CORE, ), ); if (module_exists('spamspan')) { $formats += array( 'spamspan' => array( 'label' => t('Email SpamSpan'), 'field types' => array('email'), 'multiple values' => CONTENT_HANDLE_CORE, ), ); } return $formats; } /** * Theme function for 'default' email field formatter. */ function theme_email_formatter_default($element) { return !empty($element['#item']['safe']) ? l($element['#item']['email'], "mailto:" . $element['#item']['email']) : ''; } /** * Theme function for 'spamspan' email field formatter. */ function theme_email_formatter_spamspan($element) { if (empty($element['#item']['safe'])) { return ''; } if (module_exists('spamspan')) { return spamspan($element['#item']['email']); } else { return l($element['#item']['email'], "mailto:" . $element['#item']['email']); } } /** * Theme function for 'contact' email field formatter. */ function theme_email_formatter_contact($element) { return !empty($element['#item']['safe']) ? l(t('Email contact form'), 'email/'. $element['#node']->nid .'/'. $element['#field_name']) : ''; } /** * Theme function for 'plain' email field formatter. */ function theme_email_formatter_plain($element) { return !empty($element['#item']['safe']) ? $element['#item']['safe'] : ''; } /** * Implementation of hook_widget_info(). */ function email_widget_info() { return array( 'email_textfield' => array( 'label' => t('Text field'), 'field types' => array('email'), 'multiple values' => CONTENT_HANDLE_CORE, 'callbacks' => array( 'default value' => CONTENT_CALLBACK_DEFAULT, ), ), ); } /** * Implementation of FAPI hook_elements(). */ function email_elements() { return array( 'email_textfield' => array( '#input' => TRUE, '#columns' => array('email'), '#delta' => 0, '#process' => array('email_textfield_process'), ), ); } /** * Implementation of hook_widget_settings(). */ function email_widget_settings($op, $widget) { switch ($op) { case 'form': $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; $form['size'] = array( '#type' => 'textfield', '#title' => t('Size of textfield'), '#default_value' => $size, '#element_validate' => array('_email_widget_settings_size_validate'), '#required' => TRUE, ); return $form; case 'save': return array('size'); } } function _email_widget_settings_size_validate($element, &$form_state) { $value = $form_state['values']['size']; if (!is_numeric($value) || intval($value) != $value || $value <= 0) { form_error($element, t('"Size" must be a positive integer.')); } } /** * Implementation of hook_widget(). */ 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', '#title' => $element['#title'], '#description' => content_filter_xss($field['widget']['description']), '#required' => $element['#required'], '#maxlength' => 255, '#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60, '#attributes' => array('class' => 'text', 'dir' => 'ltr'), '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, ); return $element; } /** * FAPI theme for an individual text elements. */ function theme_email_textfield($element) { return $element['#children']; } /** * Implementation of hook_menu(). */ function email_menu() { $items['email/%node/%'] = array( 'title' => 'Email Contact Form', 'page callback' => 'email_mail_page', 'page arguments' => array(1, 2), 'access callback' => 'node_access', 'access arguments' => array('view', 1), 'type' => MENU_CALLBACK, ); $items['admin/settings/email'] = array( 'title' => 'CCK Email Contact Form Settings', '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'), ); return $items; } /** * The contact form page. * * @param $node * The node object on which the email address is stored. * @param $field_name * The name of the CCK field which holds the email address. * * @return * Rendered page output containing either the contact form or a flood warning. */ function email_mail_page($node, $field_name) { $field_info = content_fields($field_name, $node->type); if (empty($field_info) || $field_info['type'] != 'email') { return MENU_NOT_FOUND; } // Check the field access using CCK's content_access function. if (!content_access('view', $field_info, NULL, $node)) { return MENU_ACCESS_DENIED; } // Check if the node has an email address. $email = isset($node->{$field_name}[0]['email']) ? $node->{$field_name}[0]['email'] : ''; if (empty($email)) { return MENU_NOT_FOUND; } // Check the formatters. if ($field_info['display_settings']['teaser']['format'] != 'contact' && $field_info['display_settings']['full']['format'] != 'contact') { return MENU_NOT_FOUND; } 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 { $output = drupal_get_form('email_mail_page_form', $node, $field_name, $email); } return $output; } /** * Contact form */ function email_mail_page_form($form_state, $node, $field_name, $email) { global $user; $form['node'] = array( '#type' => 'value', '#value' => $node, ); $form['field_name'] = array( '#type' => 'value', '#value' => $field_name, ); $form['email'] = array( '#type' => 'value', '#value' => $email, ); $form['name'] = array( '#type' => 'textfield', '#title' => t('Your name'), '#maxlength' => 255, '#default_value' => $user->uid ? $user->name : '', '#required' => TRUE, ); $form['mail'] = array( '#type' => 'textfield', '#title' => t('Your e-mail address'), '#maxlength' => 255, '#default_value' => $user->uid ? $user->mail : '', '#required' => TRUE, ); $form['subject'] = array( '#type' => 'textfield', '#title' => t('Subject'), '#maxlength' => 255, '#required' => TRUE, ); $form['message'] = array( '#type' => 'textarea', '#title' => t('Message'), '#required' => TRUE, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Send e-mail'), '#validate' => array('email_mail_page_form_validate'), '#submit' => array('email_mail_page_form_submit'), ); return $form; } /** * Validate the site-wide contact page form submission. */ function email_mail_page_form_validate($form, &$form_state) { if (!valid_email_address($form_state['values']['mail'])) { form_set_error('mail', t('You must enter a valid e-mail address.')); } if (preg_match("/\r|\n/", $form_state['values']['subject'])) { form_set_error('subject', t('The subject cannot contain linebreaks.')); watchdog('mail', 'Email injection exploit attempted in email form subject: '. check_plain($form_state['values']['subject']), WATCHDOG_NOTICE); } } /** * Process the site-wide contact page form submission. */ function email_mail_page_form_submit($form, &$form_state) { $node = $form_state['values']['node']; $field_name = $form_state['values']['field_name']; $email = $form_state['values']['email']; // 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. $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)); // Send the e-mail to the recipients: drupal_mail('email', 'contact', $email, language_default(), $params, $from); // Log the operation: flood_register_event('email'); 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))))); // Update user: drupal_set_message(t('Your message has been sent.')); // Jump to home page rather than back to contact page to avoid contradictory messages if flood control has been activated. $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: $msg[] = t('@name sent a message using the contact form at @node.', array('@name' => $params['name'], '@node' => $params['url']), $language->language); $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); $message['subject'] = t('[@title] @subject', array('@title' => preg_replace("/\r|\n/",'', $node->title), '@subject' => $params['subject']), $language->language); break; } } /** * Implementation of hook token_list */ function email_token_list($type = 'all') { if ($type == 'field' || $type == 'all') { $tokens['email']['raw'] = t('Raw email address'); $tokens['email']['formatted'] = t('Formatted email address'); return $tokens; } } /** * Implementation of hook token_values */ function email_token_values($type, $object = NULL, $options = array()) { if ($type == 'field') { $item = $object[0]; $tokens['raw'] = $item['email']; $tokens['formatted'] = $item['view']; return $tokens; } } /** * 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); }