Index: webform.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v
retrieving revision 1.131
diff -u -r1.131 webform.module
--- webform.module 16 Jun 2009 12:39:04 -0000 1.131
+++ webform.module 17 Jun 2009 22:33:14 -0000
@@ -122,9 +122,38 @@
'access callback' => 'node_access',
'access arguments' => array('update', 1),
'file' => 'includes/webform.pages.inc',
+ 'weight' => 2,
+ 'type' => MENU_LOCAL_TASK,
+ );
+
+ // Node e-mail forms.
+ $items['node/%webform_menu/webform/emails'] = array(
+ 'title' => 'E-mails',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('webform_emails_form', 1),
+ 'access callback' => 'node_access',
+ 'access arguments' => array('update', 1),
+ 'file' => 'includes/webform.emails.inc',
'weight' => 1,
'type' => MENU_LOCAL_TASK,
);
+ $items['node/%webform_menu/webform/emails/%webform_menu_email'] = array(
+ 'title' => 'Edit e-mail settings',
+ 'load arguments' => array(1),
+ 'page arguments' => array('webform_email_edit_form', 1, 4),
+ 'access callback' => 'node_access',
+ 'access arguments' => array('update', 1),
+ 'file' => 'includes/webform.emails.inc',
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['node/%webform_menu/webform/emails/%webform_menu_email/delete'] = array(
+ 'title' => 'Delete e-mail settings',
+ 'load arguments' => array(1),
+ 'page arguments' => array('webform_email_delete_form', 1, 4),
+ 'access callback' => 'node_access',
+ 'access arguments' => array('update', 1),
+ 'type' => MENU_LOCAL_TASK,
+ );
// Node component forms.
$items['node/%webform_menu/webform/components/%webform_menu_component'] = array(
@@ -304,6 +333,38 @@
return $component;
}
+
+/**
+ * Menu loader callback. Load a webform e-mail if the given eid is a valid.
+ */
+function webform_menu_email_load($eid, $nid) {
+ module_load_include('inc', 'webform', 'includes/webform.emails');
+ $node = node_load($nid);
+ if ($eid == 'new') {
+ $email = array(
+ 'email' => '',
+ 'subject' => 'default',
+ 'from_name' => 'default',
+ 'from_address' => 'default',
+ 'template' => 'default',
+ );
+ if (isset($_GET['option']) && isset($_GET['email'])) {
+ $type = $_GET['option'];
+ if ($type == 'custom') {
+ $email['email'] = $_GET['email'];
+ }
+ elseif ($type == 'component' && isset($node->webform['components'][$_GET['email']])) {
+ $email['email'] = $_GET['email'];
+ }
+ }
+ }
+ else {
+ $email = isset($node->webform['emails'][$eid]) ? $node->webform['emails'][$eid] : FALSE;
+ }
+
+ return $email;
+}
+
function webform_submission_access($node, $submission, $op = 'view', $account = NULL) {
global $user;
$account = isset($account) ? $account : $user;
@@ -351,14 +412,6 @@
'template' => 'templates/webform-form',
'pattern' => 'webform_form_[0-9]+',
),
- 'webform_mail_components_form' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'includes/webform.pages.inc',
- ),
- 'webform_mail_settings_form' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'includes/webform.pages.inc',
- ),
'webform_advanced_submit_limit_form' => array(
'arguments' => array('form' => NULL),
'file' => 'includes/webform.pages.inc',
@@ -389,6 +442,19 @@
'webform_token_help' => array(
'arguments' => array(),
),
+ // webform.emails.inc.
+ 'webform_emails_form' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'includes/webform.emails.inc',
+ ),
+ 'webform_email_add_form' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'includes/webform.emails.inc',
+ ),
+ 'webform_email_edit_form' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'includes/webform.emails.inc',
+ ),
// webform_components.inc.
'webform_components_form' => array(
'arguments' => array('form' => NULL),
@@ -550,6 +616,12 @@
while ($role = db_fetch_object($result)) {
$additions->webform['roles'][] = $role->rid;
}
+
+ $additions->webform['emails'] = array();
+ $result = db_query('SELECT * FROM {webform_emails} WHERE nid = %d', $node->nid);
+ while ($email = db_fetch_array($result)) {
+ $additions->webform['emails'][$email['eid']] = $email;
+ }
}
else {
$additions->webform = array(
@@ -559,13 +631,10 @@
'submit_text' => '',
'submit_limit' => -1,
'submit_interval' => -1,
- 'email' => '',
- 'email_from_name' => 'default',
- 'email_from_address' => 'default',
- 'email_subject' => 'default',
'additional_validate' => '',
'additional_submit' => '',
'roles' => array(1, 2),
+ 'emails' => array(),
);
}
@@ -931,6 +1000,17 @@
'#description' => t('Cookies can be used to help prevent the same user from repeatedly submitting a webform. This feature is not needed for limiting submissions per user, though it can increase accuracy in some situations. Besides cookies, Webform also uses IP addresses and site usernames to prevent repeated submissions.'),
);
+ $form['advanced']['webform_email_address_format'] = array(
+ '#type' => 'radios',
+ '#title' => t('E-mail address format'),
+ '#options' => array(
+ 'long' => t('Long format: "Example Name" <name@example.com>'),
+ 'short' => t('Short format: name@example.com'),
+ ),
+ '#default_value' => variable_get('webform_email_address_format', 'long'),
+ '#description' => t('Most servers support the "long" format which will allow for more friendly From addresses in e-mails sent. However many Windows-based servers are unable to send in the long format. Change this option if experiencing problems sending e-mails with Webform.'),
+ );
+
$form['advanced']['webform_export_format'] = array(
'#type' => 'radios',
'#title' => t('Default export format'),
@@ -1347,24 +1427,6 @@
$form_state['values']['submitted_tree'] = $form_state['values']['submitted'];
$form_state['values']['submitted'] = _webform_client_form_submit_flatten($node, $form_state['values']['submitted']);
- // Convert additional email addresses into actual values.
- foreach ($node->webform['additional_emails'] as $cid => $value) {
- if (is_array($form_state['values']['submitted'][$cid])) {
- $node->webform['additional_emails'][$cid] = array();
- foreach ($form_state['values']['submitted'][$cid] as $submitted_value) {
- if ($submitted_value) {
- $node->webform['additional_emails'][$cid][] = $submitted_value;
- }
- }
- }
- else {
- $node->webform['additional_emails'][$cid] = $form_state['values']['submitted'][$cid];
- }
- if (empty($node->webform['additional_emails'][$cid])) {
- unset($node->webform['additional_emails'][$cid]);
- }
- }
-
// Perform additional submit processing.
if (trim($node->webform['additional_submit'])) {
// Support for Drupal 5 validation code.
@@ -1396,104 +1458,89 @@
$sid = $form_state['values']['details']['sid'];
// Check if this form is sending an email.
- if ((!empty($node->webform['email']) || !empty($node->webform['additional_emails'])) && $form_state['values']['details']['is_new']) {
+ if ($form_state['values']['details']['is_new']) {
+ // Create a themed message for mailing.
+ foreach ($node->webform['emails'] as $eid => $email) {
+ $cid = is_numeric($email['email']) && isset($node->webform['components'][$email['email']]) ? $email['email'] : 'custom';
- // Set values for the name, address, and subject for the email.
- $email_from_name = $node->webform['email_from_name'];
- $email_from_address = $node->webform['email_from_address'];
- $email_subject = $node->webform['email_subject'];
- foreach (array('from_name', 'from_address', 'subject') as $field) {
- if ($node->webform['email_'. $field] == 'default') {
- ${'email_'. $field} = _webform_filter_values(webform_variable_get('webform_default_'. $field), $node, $form_state['values']['submitted']);
- }
- elseif (is_numeric($node->webform['email_'. $field])) {
- if (is_array($form_state['values']['submitted'][${'email_'. $field}])) {
- $values = array();
- foreach ($form_state['values']['submitted'][${'email_'. $field}] as $key => $value) {
- $values[] = _webform_filter_values($value, $node, $form_state['values']['submitted']);
- }
- ${'email_'. $field} = implode(', ', $values);
- }
- else {
- ${'email_'. $field} = _webform_filter_values($form_state['values']['submitted'][${'email_'. $field}], $node, $form_state['values']['submitted']);
- }
+ // Pass through the theme layer if using the default template.
+ if ($email['template'] == 'default') {
+ $email['message'] = theme(array('webform_mail_'. $node->nid, 'webform_mail', 'webform_mail_message'), $form_state['values'], $node, $sid, $cid);
}
else {
- ${'email_'. $field} = _webform_filter_values(${'email_'. $field}, $node, $form_state['values']['submitted']);
+ $email['message'] = $email['template'];
}
- }
- // Create a themed message for mailing.
- // Check for a node-specific message:
- $emails = $node->webform['additional_emails'];
- if ($node->webform['email']) {
- $emails['default'] = $node->webform['email'];
- }
- $messages = array();
- $headers = array();
- $froms = array();
- $subjects = array();
- foreach ($emails as $cid => $email) {
- $messages[$cid] = theme(array('webform_mail_'. $node->nid, 'webform_mail', 'webform_mail_message'), $form_state['values'], $node, $sid, $cid);
- $headers[$cid] = theme(array('webform_mail_headers_'. $node->nid, 'webform_mail_headers'), $form_state['values'], $node, $sid, $cid);
+ // Replace tokens in the message.
+ $email['message'] = _webform_filter_values($email['message'], $node, $form_state['values'], FALSE);
+
+ // Build the e-mail headers.
+ $email['headers'] = theme(array('webform_mail_headers_'. $node->nid, 'webform_mail_headers'), $form_state['values'], $node, $sid, $cid);
// Assemble the FROM string.
- if (isset($headers[$cid]['From'])) {
- $froms[$cid] = $headers[$cid]['From'];
- unset($headers[$cid]['From']);
- }
- elseif (drupal_strlen($email_from_name) > 0) {
- $froms[$cid] = '"'. mime_header_encode($email_from_name) .'" <'. $email_from_address .'>';
+ if (isset($email['headers']['From'])) {
+ // If a header From is already set, don't override it.
+ $email['from'] = $email['headers']['From'];
+ unset($email['headers']['From']);
}
else {
- $froms[$cid] = $email_from_address;
+ $email['from'] = webform_format_email_address($email['from_address'], $email['from_name'], $node, $form_state['values']);
}
// Update the subject if set in the themed headers.
- if (isset($headers[$cid]['Subject'])) {
- $subjects[$cid] = $headers[$cid]['Subject'];
- unset($headers[$cid]['Subject']);
+ if (isset($email['headers']['Subject'])) {
+ $email['headers']['subject'] = $email['headers']['Subject'];
+ unset($email['headers']['Subject']);
}
else {
- $subjects[$cid] = $email_subject;
+ $email['subject'] = webform_format_email_subject($email['subject'], $node, $form_state['values']);
}
// Update the to e-mail if set in the themed headers.
if (isset($headers[$cid]['To'])) {
- $emails[$cid] = $headers[$cid]['To'];
+ $email['email'] = $headers[$cid]['To'];
unset($headers[$cid]['To']);
}
- }
- // Verify that this submission is not attempting to send any spam hacks.
- if (_webform_submission_spam_check($emails['default'], $subjects['default'], $froms['default'], $headers['default'])) {
- watchdog('webform', 'Possible spam attempt from @remote_addr'."
\n". nl2br(htmlentities($messages['default'])), array('@remote_add' => ip_address()));
- drupal_set_message(t('Illegal information. Data not submitted.'), 'error');
- return FALSE;
- }
-
- // Mail the webform results.
- foreach ($emails as $cid => $address) {
- // In the case of checkboxes or multiple select, multiple e-mails may need
- // to be sent out.
- if (is_array($address)) {
- foreach ($address as $single_address) {
- drupal_mail('webform', 'submission', $single_address, user_preferred_language($user), array('message' => $messages[$cid], 'subject' => $subjects[$cid], 'headers' => $headers[$cid]), $froms[$cid]);
-
- // Debugging output for email.
- if (variable_get('webform_debug', 0) >= 2) {
- drupal_set_message('E-mail Headers:
'. htmlentities(print_r($headers[$cid], TRUE)) .'To: '. $single_address .'
'. $messages[$cid] .''); + // Generate the list of addresses that this e-mail will be sent to. + $addresses = array_filter(explode(',', $email['email'])); + $addresses_final = array(); + foreach ($addresses as $address) { + $address = trim($address); + + // After filtering e-mail addresses with component values, a single value + // might contain multiple addresses (such as from checkboxes or selects). + $address = webform_format_email_address($address, NULL, $node, $form_state['values'], TRUE, FALSE, 'short'); + + if (is_array($address)) { + foreach ($address as $new_address) { + if (valid_email_address($new_address)) { + $addresses_final[] = $new_address; + } } } + elseif (valid_email_address($address)) { + $addresses_final[] = $address; + } } - else { - drupal_mail('webform', 'submission', $address, user_preferred_language($user), array('message' => $messages[$cid], 'subject' => $subjects[$cid], 'headers' => $headers[$cid]), $froms[$cid]); + // Mail the webform results. + foreach ($addresses_final as $address) { + // Verify that this submission is not attempting to send any spam hacks. + if (_webform_submission_spam_check($address, $email['subject'], $email['from'], $email['headers'])) { + watchdog('webform', 'Possible spam attempt from @remote_addr'."
'. htmlentities(print_r($headers[$cid], TRUE)) .'To: '. $address .'
'. $messages[$cid] .''); + drupal_set_message('E-mail Headers:
'. check_plain(print_r($headers[$cid], TRUE)) .'To: '. check_plain($address) .'
'. check_plain($email['message']) .''); } } + } } @@ -1730,46 +1777,71 @@ */ function _webform_filter_values($string, $node = NULL, $submission = NULL, $strict = TRUE) { global $user; + static $find, $replace; // Setup default token replacements. - $find = array('%site', '%date'); - $replace = array(variable_get('site_name', 'drupal'), format_date(time(), 'large')); + if (!isset($find)) { + $find = array('%site', '%date'); + $replace = array(variable_get('site_name', 'drupal'), format_date(time(), 'large')); + } // Node replacements. - if (isset($node)) { - $find[] = '%title'; - $replace[] = $node->title; + if (isset($node) && !in_array('%title', $find)) { + $find['%title'] = '%title'; + $replace['%title'] = $node->title; } // Submission replacements. - if (isset($submission)) { - foreach ($submission as $cid => $value) { - $find[] = '%cid['. $cid .']'; + if (isset($submission) && !in_array('%email_values', $find)) { + foreach ($submission['submitted'] as $cid => $value) { + // Find by CID. + $find[] = '%cid[' . $cid . ']'; + $replace[] = $value; + + // Find by form key. + $find[] = '%value[' . $node->webform['components'][$cid]['form_key'] . ']'; + $find[] = '%label[' . $node->webform['components'][$cid]['form_key'] . ']'; $replace[] = $value; + $replace[] = $node->webform['components'][$cid]['name']; } - } - // User replacements. - $find[] = '%username'; - $find[] = '%useremail'; - $replace[] = isset($user->name) ? $user->name : ''; - $replace[] = isset($user->mail) ? $user->mail : ''; - if ($user->uid && module_exists('profile')) { - profile_load_profile($user); + // The entire form tree: + $find[] = '%email_values'; + $replace[] = theme('webform_mail_fields', 0, $submission['submitted_tree'], $node); + + // Submission edit URL. + $find[] = '%submission_url'; + $replace[] = url('node/'. $node->nid .'/submission/'. $submission['details']['sid'], array('absolute' => TRUE)); } // Provide a list of candidates for token replacement. - $tokens = array( - '%server' => $_SERVER, + // Note these tokens are not cached as they may change frequently. + $special_tokens = array( '%session' => $_SESSION, '%cookie' => $_COOKIE, '%get' => $_GET, '%post' => $_POST, '%request' => $_REQUEST, - '%profile' => $user, ); - foreach ($tokens as $token => $variable) { + // User replacements. + if (!in_array('%username', $find)) { + $find[] = '%username'; + $find[] = '%useremail'; + $find[] = '%ip_address'; + $replace[] = isset($user->name) ? $user->name : ''; + $replace[] = isset($user->mail) ? $user->mail : ''; + $replace[] = ip_address(); + if ($user->uid && module_exists('profile')) { + profile_load_profile($user); + } + $special_tokens['%profile'] = $user; + + // Doesn't really belong here with user things, but works. + $special_tokens['%server'] = $_SERVER; + } + + foreach ($special_tokens as $token => $variable) { if (strpos($string, $token) !== FALSE) { foreach ($variable as $key => $value) { $find[] = $token .'['. $key .']'; @@ -1788,18 +1860,18 @@ $string = str_replace($find, $replace, $string); // Clean up any unused tokens. - foreach (array_keys($tokens) as $token) { + foreach (array_keys($special_tokens) as $token) { $string = preg_replace('/\\'. $token .'\[\w+\]/', '', $string); } - return $strict ? filter_xss($string) : $string; + return $strict ? check_plain($string) : $string; } /** * Filters all special tokens provided by webform, and allows basic layout in descriptions. */ function _webform_filter_descriptions($string, $node = NULL, $submission = NULL, $strict = TRUE) { - return check_markup(_webform_filter_values($string, $node = NULL, $submission = NULL, $strict = TRUE)); + return check_markup(_webform_filter_values($string, $node, $submission, $strict)); } /** @@ -1878,28 +1950,57 @@ return $result; } -function theme_webform_token_help() { - $tokens = array( +function theme_webform_token_help($node = NULL) { + $basic_tokens = array( '%username', '%useremail', + '%ip_address', '%site', '%date', + ); + + $special_tokens = array( '%server['. t('key') .']', '%session['. t('key') .']', '%get['. t('key') .']', '%post['. t('key') .']', '%request['. t('key') .']', ); + if (module_exists('profile')) { - $tokens[] = '%profile['. t('key') .']'; + $special_tokens[] = '%profile['. t('key') .']'; + } + + if (isset($node)) { + $submission_keys = array(); + foreach ($node->webform['components'] as $cid => $component) { + if (!in_array($component['type'], array('markup', 'fieldset', 'pagebreak'))) { + $submission_keys[] = $component['form_key']; + } + } + if (!empty($submission_keys)) { + $submission_tokens = array( + '%email_values', + '%submission_url', + '%label[key]', + '%value[key]', + t('Where the key may be any of the following components (do not include quotes):') . theme('item_list', $submission_keys), + ); + } } $output = ''; - $output .= t('You may use special tokens in this field that will be replaced with dynamic values.'); - $output .= theme('item_list', $tokens); - $output .= t('You can use %server[key] to add any of the special PHP $_SERVER variables, %session[key] to add any of the special PHP $_SESSION variables and %get[key] to create prefilled forms from the URL. %cookie, %request and %post also work with their respective PHP variables. For example %server[HTTP_USER_AGENT], %session[id], or %get[q].'); + $output .= '
' . t('You may use special tokens in this field that will be replaced with dynamic values.') . '
'; + + if (!empty($submission_tokens)) { + $output .= theme('item_list', $submission_tokens, t('Component variables')); + } + + $output .= theme('item_list', $basic_tokens, t('Basic variables')); + $output .= theme('item_list', $special_tokens, t('Special variables')); + $output .= '' . t('You can use %server[key] to add any of the special PHP $_SERVER variables, %session[key] to add any of the special PHP $_SESSION variables and %get[key] to create prefilled forms from the URL. %cookie, %request and %post also work with their respective PHP variables. For example %server[HTTP_USER_AGENT], %session[id], or %get[q].') . '
'; if (module_exists('profile')) { - $output .= ' '. t('If you are using the profiles module, you can also access all profile data using the syntax %profile[form_name]. If you for example have a profile value named profile_city, add the variable %profile[profile_city].'); + $output .= ''. t('If you are using the Profile module, you can also access all profile data using the syntax %profile[form_name]. If you for example have a profile value named profile_city, add the variable %profile[profile_city].') . '
'; } $fieldset = array( @@ -1933,6 +2034,108 @@ } /** + * Given an email address and a name, format an e-mail address. + * + * @param $address + * The e-mail address. + * @param $name + * The name to be used in the formatted address. + * @param $node + * The webform node if replacements will be done. + * @param $submission + * The webform submission values if replacements will be done. + * @param $encode + * Encode the text for use in an e-mail. + * @param $single + * Force a single value to be returned, even if a component expands to + * multiple addresses. This is useful to ensure a single e-mail will be + * returned for the "From" address. + * @param $format + * The e-mail format, defaults to the site-wide setting. May be either "short" + * or "long". + */ +function webform_format_email_address($address, $name, $node = NULL, $submission = NULL, $encode = TRUE, $single = TRUE, $format = NULL) { + if (!isset($format)) { + $format = variable_get('webform_email_address_format', 'long'); + } + + if ($name == 'default') { + $name = webform_variable_get('webform_default_from_name'); + } + elseif (is_numeric($name) && isset($node->webform['components'][$name])) { + if (isset($submission['submitted'][$name])) { + $name = $submission['submitted'][$name]; + } + else { + $name = t('Value of !component', array('!component' => $node->webform['components'][$name]['name'])); + } + } + + if ($address == 'default') { + $address = webform_variable_get('webform_default_from_address'); + } + elseif (is_numeric($address) && isset($node->webform['components'][$address])) { + if (isset($submission['submitted'][$address])) { + $address = $submission['submitted'][$address]; + } + else { + $address = t('Value of "!component"', array('!component' => $node->webform['components'][$address]['name'])); + } + } + + // Convert arrays into a single value for From values. + if ($single) { + $address = is_array($address) ? reset($address) : $address; + $name = is_array($name) ? reset($name) : $name; + } + + // Address may be an array if a component value was used on checkboxes. + if (is_array($address)) { + foreach ($address as $key => $individual_address) { + $address[$key] = _webform_filter_values($individual_address, $node, $submission, FALSE); + } + } + else { + $address = _webform_filter_values($address, $node, $submission, FALSE); + } + + if ($format == 'long' && isset($name)) { + $name = _webform_filter_values($name, $node, $submission, FALSE); + if ($encode) { + $name = mime_header_encode($name); + } + return '"' . $name . '" <' . $address . '>'; + } + else { + return $address; + } +} + +/** + * Given an email subject, format it with any needed replacements. + */ +function webform_format_email_subject($subject, $node = NULL, $submission = NULL) { + if ($subject == 'default') { + $subject = webform_variable_get('webform_default_subject'); + } + elseif (is_numeric($subject) && isset($node->webform['components'][$subject])) { + if (isset($submission['submitted'][$subject])) { + $subject = $submission['submitted'][$subject]; + } + else { + $subject = t('Value of "!component"', array('!component' => $node->webform['components'][$subject]['name'])); + } + } + + // Convert arrays to strings (may happen if checkboxes are used as the value). + if (is_array($subject)) { + $subject = reset($subject); + } + + return _webform_filter_values($subject, $node, $submission, FALSE); +} + +/** * Given a set of components, determine which one are appropriate for a * particular use, such as an email address or subject. * Index: webform.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.install,v retrieving revision 1.25 diff -u -r1.25 webform.install --- webform.install 16 Jun 2009 12:39:03 -0000 1.25 +++ webform.install 17 Jun 2009 22:33:13 -0000 @@ -16,7 +16,7 @@ 'description' => 'Table for storing additional properties for webform nodes.', 'fields' => array( 'nid' => array( - 'description' => 'The node identifier of a webform', + 'description' => 'The node identifier of a webform.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -57,26 +57,6 @@ 'not null' => TRUE, 'default' => -1, ), - 'email' => array( - 'description' => 'The primary e-mail address for receiving submission results.', - 'type' => 'varchar', - 'length' => 255, - ), - 'email_from_name' => array( - 'description' => 'The name of the sender in sent submission e-mails.', - 'type' => 'varchar', - 'length' => 255, - ), - 'email_from_address' => array( - 'description' => 'The address of the sender in sent submission e-mails.', - 'type' => 'varchar', - 'length' => 255, - ), - 'email_subject' => array( - 'description' => 'The subject of sent submission e-mails', - 'type' => 'varchar', - 'length' => 255, - ), 'additional_validate' => array( 'description' => 'PHP code for additional functionality when validating a form.', 'type' => 'text', @@ -95,7 +75,7 @@ 'description' => 'Stores information about components for webform nodes.', 'fields' => array( 'nid' => array( - 'description' => 'The node identifier of a webform', + 'description' => 'The node identifier of a webform.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -167,6 +147,56 @@ 'primary key' => array('nid', 'cid'), ); + $schema['webform_emails'] = array( + 'description' => 'Holds information regarding e-mails that should be sent upon submitting a webform', + 'fields' => array( + 'nid' => array( + 'description' => 'The node identifier of a webform.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'eid' => array( + 'description' => 'The e-mail identifier for this row\'s settings.', + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'small', + 'not null' => TRUE, + 'default' => 0, + ), + 'email' => array( + 'description' => 'The e-mail address that will be sent to upon submission. This may be an e-mail address, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.', + 'type' => 'text', + 'not null' => FALSE, + ), + 'subject' => array( + 'description' => 'The e-mail subject that will be used. This may be a string, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.', + 'type' => 'varchar', + 'length' => '255', + 'not null' => FALSE, + ), + 'from_name' => array( + 'description' => 'The e-mail "from" name that will be used. This may be a string, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.', + 'type' => 'varchar', + 'length' => '255', + 'not null' => FALSE, + ), + 'from_address' => array( + 'description' => 'The e-mail "from" e-mail address that will be used. This may be a string, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.', + 'type' => 'varchar', + 'length' => '255', + 'not null' => FALSE, + ), + 'template' => array( + 'description' => 'A template that will be used for the sent e-mail. This may be a string or the special key "default", which will use the template provided by the theming layer.', + 'type' => 'text', + 'not null' => FALSE, + ) + ), + 'primary key' => array('nid', 'eid'), + ); + $schema['webform_roles'] = array( 'description' => 'Holds access information regarding which roles are allowed to submit which webform nodes. Does not prevent access to the webform node entirely, use the {node_access} table for that purpose.', 'fields' => array( @@ -198,7 +228,7 @@ 'not null' => TRUE, ), 'nid' => array( - 'description' => 'The node identifier of a webform', + 'description' => 'The node identifier of a webform.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -233,7 +263,7 @@ 'description' => 'Stores all submitted field data for webform submissions.', 'fields' => array( 'nid' => array( - 'description' => 'The node identifier of a webform', + 'description' => 'The node identifier of a webform.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -1042,6 +1072,96 @@ } /** + * Convert node-level e-mail settings to new webform_emails table. + */ +function webform_update_6302() { + $ret = array(); + + // Safety check to prevent recreating the webform_emails table. + if (db_table_exists('webform_emails')) { + return $ret; + } + + $table = array( + 'fields' => array( + 'nid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'eid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'small', + 'not null' => TRUE, + 'default' => 0, + ), + 'email' => array( + 'type' => 'text', + 'not null' => FALSE, + ), + 'subject' => array( + 'type' => 'varchar', + 'length' => '255', + 'not null' => FALSE, + ), + 'from_name' => array( + 'type' => 'varchar', + 'length' => '255', + 'not null' => FALSE, + ), + 'from_address' => array( + 'type' => 'varchar', + 'length' => '255', + 'not null' => FALSE, + ), + 'template' => array( + 'type' => 'text', + 'not null' => FALSE, + ) + ), + 'primary key' => array('nid', 'eid'), + ); + + db_create_table($ret, 'webform_emails', $table); + + // Move over data from the webform table. + $result = db_query("SELECT w.nid, w.email, w.email_from_name, w.email_from_address, w.email_subject, wc.cid, wc.extra FROM {webform} w LEFT JOIN {webform_component} wc ON w.nid = wc.nid AND type IN ('select', 'hidden', 'email') ORDER BY nid"); + $nid = 0; + while ($row = db_fetch_object($result)) { + // Insert an e-mail settings row for the default e-mail. + if ($row->nid != $nid) { + $nid = $row->nid; + $eid = 0; + if (!empty($row->email)) { + $eid++; + db_query("INSERT INTO {webform_emails} (nid, eid, email, subject, from_name, from_address, template) VALUES (%d, %d, '%s', '%s', '%s', '%s', 'default')", $nid, $eid, $row->email, $row->email_subject, $row->email_from_name, $row->email_from_address); + } + } + + // Check for an e-mail based on a component. + if ($row->extra) { + $extra = unserialize($row->extra); + if ($extra['email']) { + $eid++; + unset($extra['email']); + db_query("INSERT INTO {webform_emails} (nid, eid, email, subject, from_name, from_address, template) VALUES (%d, %d, '%s', '%s', '%s', '%s', 'default')", $nid, $eid, $row->cid, $row->email_subject, $row->email_from_name, $row->email_from_address); + db_query("UPDATE {webform_component} SET extra = '%s' WHERE nid = %d AND cid = %d", serialize($extra), $row->nid, $row->cid); + } + } + } + + // Remove columns from webform table. + db_drop_field($ret, 'webform', 'email'); + db_drop_field($ret, 'webform', 'email_from_name'); + db_drop_field($ret, 'webform', 'email_from_address'); + db_drop_field($ret, 'webform', 'email_subject'); + + return $ret; +} + +/** * Recursively delete all files and folders in the specified filepath, then * delete the containing folder. * Index: webform.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.js,v retrieving revision 1.4 diff -u -r1.4 webform.js --- webform.js 7 May 2009 22:38:13 -0000 1.4 +++ webform.js 17 Jun 2009 22:33:13 -0000 @@ -9,6 +9,8 @@ Drupal.webform.defaultValues(context); // On click or change, make a parent radio button selected. Drupal.webform.setActive(context); + // Update the template select list upon changing a template. + Drupal.webform.updateTemplate(context); } Drupal.webform = new Object(); @@ -39,6 +41,32 @@ }; Drupal.webform.setActive = function(context) { - var setActive = function() { $('.form-radio', $(this).parent().parent()).attr('checked', true); }; + var setActive = function() { + $('.form-radio', $(this).parent().parent()).attr('checked', true); + }; $('.webform-set-active', context).click(setActive).change(setActive); }; + +Drupal.webform.updateTemplate = function(context) { + var defaultTemplate = $('#edit-templates-default').val(); + var $templateSelect = $('#webform-template-fieldset select', context); + var $templateTextarea = $('#webform-template-fieldset textarea', context); + + var updateTemplateSelect = function() { + if ($(this).val() == defaultTemplate) { + $templateSelect.val('default'); + } + else { + $templateSelect.val('custom'); + } + } + + var updateTemplateText = function() { + if ($(this).val() == 'default') { + $templateTextarea.val(defaultTemplate); + } + } + + $templateTextarea.keyup(updateTemplateSelect); + $templateSelect.change(updateTemplateText); +} Index: components/hidden.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/hidden.inc,v retrieving revision 1.13 diff -u -r1.13 hidden.inc --- components/hidden.inc 7 May 2009 22:38:14 -0000 1.13 +++ components/hidden.inc 17 Jun 2009 22:33:14 -0000 @@ -17,7 +17,6 @@ 'weight' => 0, 'value' => '', 'extra' => array( - 'email' => 0, ), ); } @@ -46,13 +45,6 @@ '#type' => 'hidden', '#value' => 1, ); - $edit_fields['extra']['email'] = array( - '#type' => 'checkbox', - '#title' => t('E-mail a submission copy'), - '#return_value' => 1, - '#default_value' => $currfield['extra']['email'], - '#description' => t('Check this option if this component contains an e-mail address that should get a copy of the submission. Emails are sent individually so other emails will not be shown to the recipient.'), - ); $edit_fields['extra']['description'] = array(); // Hide the description box. return $edit_fields; } Index: components/select.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/select.inc,v retrieving revision 1.23 diff -u -r1.23 select.inc --- components/select.inc 7 May 2009 22:38:14 -0000 1.23 +++ components/select.inc 17 Jun 2009 22:33:14 -0000 @@ -20,7 +20,6 @@ 'value' => '', 'extra' => array( 'items' => '', - 'email' => 0, 'multiple' => NULL, 'aslist' => NULL, 'description' => '', @@ -73,14 +72,7 @@ '#default_value' => $currfield['extra']['aslist'], '#description' => t('Check this option if you want the select component to be of listbox type instead of radiobuttons or checkboxes.'), ); - $edit_fields['extra']['email'] = array( - '#type' => 'checkbox', - '#title' => t('E-mail a submission copy'), - '#return_value' => 1, - '#default_value' => $currfield['extra']['email'], - '#description' => t('Check this option if this component contains an e-mail address that should get a copy of the submission. Emails are sent individually so other emails will not be shown to the recipient.') .' '. - t('To use the option with a select component, you must use key-value pairs seperated by pipes. i.e. user@example.com|Sample user.'), - ); + return $edit_fields; } Index: components/email.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/email.inc,v retrieving revision 1.20 diff -u -r1.20 email.inc --- components/email.inc 7 May 2009 22:38:14 -0000 1.20 +++ components/email.inc 17 Jun 2009 22:33:14 -0000 @@ -21,7 +21,6 @@ 'extra' => array( 'width' => '', 'disabled' => 0, - 'email' => 0, 'description' => '', 'attributes' => array(), ), @@ -66,13 +65,6 @@ '#size' => 5, '#maxlength' => 10, ); - $edit_fields['extra']['email'] = array( - '#type' => 'checkbox', - '#title' => t('E-mail a submission copy'), - '#return_value' => 1, - '#default_value' => $currfield['extra']['email'], - '#description' => t('Check this option if this component contains an e-mail address that should get a copy of the submission. Emails are sent individually so other emails will not be shown to the recipient.'), - ); $edit_fields['extra']['disabled'] = array( '#type' => 'checkbox', '#title' => t('Disabled'), Index: templates/webform-mail.tpl.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/templates/webform-mail.tpl.php,v retrieving revision 1.1 diff -u -r1.1 webform-mail.tpl.php --- templates/webform-mail.tpl.php 22 May 2009 03:11:18 -0000 1.1 +++ templates/webform-mail.tpl.php 17 Jun 2009 22:33:15 -0000 @@ -23,23 +23,19 @@ * logic on CIDs you can customize various e-mails. */ ?> - format_date(time(), 'small'))) ?> + uid): ?> - $user->name, '@ip_address' => $ip_address)) ?> + - $ip_address)) ?> + : - +%email_values -nid .'/submission/'. $sid, array('absolute' => TRUE)) ?> + +%submission_url Index: includes/webform.pages.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.pages.inc,v retrieving revision 1.2 diff -u -r1.2 webform.pages.inc --- includes/webform.pages.inc 16 Jun 2009 14:42:13 -0000 1.2 +++ includes/webform.pages.inc 17 Jun 2009 22:33:15 -0000 @@ -92,97 +92,6 @@ ); /* End per-role submission control */ - /* Start E-mail Settings Form */ - $form['mail_settings'] = array( - '#type' => 'fieldset', - '#title' => t('Mail settings'), - '#collapsible' => TRUE, - '#collapsed' => FALSE, - '#weight' => -2, - '#theme' => 'webform_mail_settings_form', - ); - - $form['mail_settings']['email'] = array( - '#type' => 'textfield', - '#title' => t('E-mail to address'), - '#maxlength' => 255, - '#default_value' => $node->webform['email'], - '#description' => t('Form submissions will be e-mailed to this address. Leave blank for none. Multiple e-mail addresses may be separated by commas.'), - ); - - $form['mail_settings']['email_components'] = array( - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#theme' => 'webform_mail_components_form', - '#title' => t('Conditional e-mail recipients'), - '#description' => t('The settings below allow you to send e-mails to multiple recipients based off the value of a component.'), - '#node' => $node, - ); - - $options = _webform_component_options($node->webform['components'], 'email'); - $default_value = array(); - if (is_array($node->webform['components'])) { - foreach ($node->webform['components'] as $cid => $component) { - if (isset($component['extra']['email']) && $component['extra']['email']) { - $default_value[] = $cid; - } - } - } - $form['mail_settings']['email_components']['email_components'] = array( - '#type' => 'checkboxes', - '#options' => $options, - '#default_value' => $default_value, - '#parents' => array('email_components'), - ); - - foreach (array('from_name', 'from_address', 'subject') as $field) { - switch ($field) { - case 'from_name': - $default_value = _webform_filter_values(webform_variable_get('webform_default_from_name'), $node); - $title = t('E-mail from name'); - $description = t('After adding components to this form any email, select, or hidden form element may be selected as the sender\'s name for e-mails.'); - break; - case 'from_address': - $default_value = _webform_filter_values(webform_variable_get('webform_default_from_address'), $node); - $title = t('E-mail from address'); - $description = t('After adding components to this form any textfield, select, or hidden form element may be selected as the sender\'s e-mail address.'); - break; - case 'subject': - $default_value = _webform_filter_values(webform_variable_get('webform_default_subject'), $node); - $title = t('E-mail subject'); - $description = t('After adding components to this form any textfield, select, or hidden form element may be selected as the subject for e-mails.'); - break; - } - - $form['mail_settings']['email_'. $field .'_option'] = array( - '#title' => $title, - '#type' => 'radios', - '#default_value' => is_numeric($node->webform['email_'. $field]) ? 'component' : ((empty($default_value) || ($node->webform['email_'. $field] != 'default' && isset($node->webform['email_'. $field]))) ? 'custom' : 'default'), - '#description' => $description, - ); - if (!empty($default_value)) { - $form['mail_settings']['email_'. $field .'_option']['#options']['default'] = $default_value; - } - $form['mail_settings']['email_'. $field .'_option']['#options']['custom'] = 'custom'; - $form['mail_settings']['email_'. $field .'_option']['#options']['component'] = 'component'; - - $form['mail_settings']['email_'. $field .'_custom'] = array( - '#type' => 'textfield', - '#size' => 40, - '#default_value' => (!is_numeric($node->webform['email_'. $field]) && $node->webform['email_'. $field] != 'default') ? $node->webform['email_'. $field] : NULL, - ); - $options = _webform_component_options($node->webform['components'], $field == 'from_address' ? 'email' : 'string'); - $form['mail_settings']['email_'. $field .'_component'] = array( - '#type' => 'select', - '#default_value' => is_numeric($node->webform['email_'. $field]) ? $node->webform['email_'. $field] : NULL, - '#options' => empty($options) ? array('' => 'No available components') : $options, - '#disabled' => empty($options) ? TRUE : FALSE, - '#weight' => 6, - ); - } - /* End mail settings form */ - /* Start advanced settings form */ $form['advanced'] = array( '#type' => 'fieldset', @@ -278,25 +187,6 @@ // Save roles. $node->webform['roles'] = $form_state['values']['roles']; - // Save e-mail. - $node->webform['email'] = $form_state['values']['email']; - - // Add the conditional e-mail recipients to components. - foreach ($form_state['values']['email_components'] as $cid => $checked) { - $node->webform['components'][$cid]['extra']['email'] = $checked; - } - - // Merge the e-mail name, address, and subject options into single values. - foreach (array('from_name', 'from_address', 'subject') as $field) { - $option = $form_state['values']['email_'. $field .'_option']; - if ($option == 'default') { - $node->webform['email_'. $field] = 'default'; - } - else { - $node->webform['email_'. $field] = $form_state['values']['email_'. $field .'_'. $option]; - } - } - // Set the Show complete form in teaser setting. $node->webform['teaser'] = $form_state['values']['teaser']; @@ -321,61 +211,6 @@ } /** - * Theme the component options for sending e-mails. - */ -function theme_webform_mail_components_form($form) { - drupal_add_css(drupal_get_path('module', 'webform') .'/webform.css'); - $node = $form['#node']; - $header = array( - array('data' => t('To'), 'class' => 'webform-checkbox'), - t('Name'), - t('Type'), - ); - $rows = array(); - foreach (element_children($form['email_components']) as $cid) { - $title = $form['email_components'][$cid]['#title']; - unset($form['email_components'][$cid]['#title']); - $rows[] = array( - array('data' => drupal_render($form['email_components'][$cid]), 'class' => 'webform-checkbox'), - $title, - $node->webform['components'][$cid]['type'], - ); - } - if (empty($rows)) { - $rows[] = array(array('colspan' => 5, 'data' => t('No components yet in this webform.'))); - } - - $form['#children'] = theme('table', $header, $rows); - return drupal_render($form); -} - -/** - * Theme the Webform mail settings section of the node form. - */ -function theme_webform_mail_settings_form($form) { - drupal_add_js(drupal_get_path('module', 'webform') .'/webform.js'); - - // Loop through fields, rendering them into radio button options. - foreach (array('from_name', 'from_address', 'subject') as $field) { - foreach (array('custom' => t('Custom'), 'component' => t('Component')) as $option => $title) { - $form['email_'. $field .'_'. $option]['#attributes']['class'] = 'webform-set-active'; - $form['email_'. $field .'_option'][$option]['#title'] = $title .': '. drupal_render($form['email_'. $field .'_'. $option]); - } - // For spacing consitency, every option is wrapped in container-inline. - foreach (element_children($form['email_'. $field .'_option']) as $option) { - $form['email_'. $field .'_option'][$option]['#prefix'] = '