Index: webform.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v
retrieving revision 1.130
diff -u -r1.130 webform.module
--- webform.module	15 Jun 2009 23:07:22 -0000	1.130
+++ webform.module	16 Jun 2009 04:56:53 -0000
@@ -40,7 +40,7 @@
     case 'node/add#webform':
       $output = t('A webform can be a questionnaires, contact or request forms. It can be used to let visitors make contact, register for a event or to enable a complex survey.');
       break;
-    case 'node/%/edit/components':
+    case 'node/%/webform/components':
       $output .= '<p>'. t('This page displays all the components currently configured for this webform node. You may add any number of components to the form, even multiple of the same type. To add a new component, fill in a name and select a type from the fields at the bottom of the table. Submit the form to create the new component or update any changed form values.') .'</p>';
       $output .= '<p>'. t('Click on any existing component\'s name to edit its settings.') .'</p>';
       break;
@@ -95,42 +95,53 @@
     'access arguments' => array('view', 1),
     'type' => MENU_CALLBACK,
   );
-  $items['node/%webform_menu/edit/configuration'] = array(
-    'title' => 'Configuration',
-    'page callback' => 'node_page_edit',
-    'page arguments' => array(1),
+  $items['node/%webform_menu/webform'] = array(
+    'title' => 'Webform',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('webform_components_form', 1),
     'access callback' => 'node_access',
     'access arguments' => array('update', 1),
+    'file' => 'includes/webform.components.inc',
     'weight' => 1,
-    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'type' => MENU_LOCAL_TASK,
   );
-  $items['node/%webform_menu/edit/components'] = array(
+  $items['node/%webform_menu/webform/components'] = array(
     'title' => 'Form components',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('webform_components_form', 1),
     'access callback' => 'node_access',
     'access arguments' => array('update', 1),
     'file' => 'includes/webform.components.inc',
-    'weight' => 2,
+    'weight' => 0,
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
+  $items['node/%webform_menu/webform/configure'] = array(
+    'title' => 'Form settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('webform_configure_form', 1),
+    'access callback' => 'node_access',
+    'access arguments' => array('update', 1),
+    'file' => 'includes/webform.pages.inc',
+    'weight' => 1,
     'type' => MENU_LOCAL_TASK,
   );
 
   // Node component forms.
-  $items['node/%webform_menu/edit/components/%webform_menu_component'] = array(
+  $items['node/%webform_menu/webform/components/%webform_menu_component'] = array(
     'load arguments' => array(1, 5),
     'page arguments' => array('webform_component_edit_form', 1, 4, FALSE),
     'access callback' => 'node_access',
     'access arguments' => array('update', 1),
     'type' => MENU_LOCAL_TASK,
   );
-  $items['node/%webform_menu/edit/components/%webform_menu_component/clone'] = array(
+  $items['node/%webform_menu/webform/components/%webform_menu_component/clone'] = array(
     'load arguments' => array(1, 5),
     'page arguments' => array('webform_component_edit_form', 1, 4, TRUE),
     'access callback' => 'node_access',
     'access arguments' => array('update', 1),
     'type' => MENU_LOCAL_TASK,
   );
-  $items['node/%webform_menu/edit/components/%webform_menu_component/delete'] = array(
+  $items['node/%webform_menu/webform/components/%webform_menu_component/delete'] = array(
     'load arguments' => array(1, 5),
     'page arguments' => array('webform_component_delete_form', 1, 4),
     'access callback' => 'node_access',
@@ -342,12 +353,15 @@
     ),
     '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',
     ),
     'webform_admin_settings' => array(
       'arguments' => array('form' => NULL),
@@ -475,13 +489,8 @@
 function webform_insert($node) {
   module_load_include('inc', 'webform', 'includes/webform.components');
 
-  // If this is submitted from the node form, do a little extra cleanup.
-  if (isset($node->op) && $node->op == $node->submit) {
-    webform_submit($node);
-  }
-
   // Insert the Webform.
-  db_query("INSERT INTO {webform} (nid, confirmation, teaser, submit_text, submit_limit, submit_interval, email, email_from_name, email_from_address, email_subject, additional_validate, additional_submit) VALUES (%d, '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $node->nid, $node->webform['confirmation'], $node->webform['teaser'], $node->webform['submit_text'], $node->webform['submit_limit'], $node->webform['submit_interval'], $node->webform['email'], $node->webform['email_from_name'], $node->webform['email_from_address'], $node->webform['email_subject'], $node->webform['additional_validate'], $node->webform['additional_submit']);
+  db_query("INSERT INTO {webform} (nid, confirmation, confirmation_format, teaser, submit_text, submit_limit, submit_interval, email, email_from_name, email_from_address, email_subject, additional_validate, additional_submit) VALUES (%d, '%s', %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $node->nid, $node->webform['confirmation'], $node->webform['confirmation_format'], $node->webform['teaser'], $node->webform['submit_text'], $node->webform['submit_limit'], $node->webform['submit_interval'], $node->webform['email'], $node->webform['email_from_name'], $node->webform['email_from_address'], $node->webform['email_subject'], $node->webform['additional_validate'], $node->webform['additional_submit']);
 
   // Insert the components into the database. Used with clone.module.
   if (isset($node->webform['components']) && !empty($node->webform['components'])) {
@@ -545,6 +554,7 @@
   else {
     $additions->webform = array(
       'confirmation' => '',
+      'confirmation_format' => FILTER_FORMAT_DEFAULT,
       'teaser' => 0,
       'submit_text' => '',
       'submit_limit' => -1,
@@ -612,14 +622,10 @@
 
 /**
  * Implementation of hook_form().
+ *
  * Creates the standard form for editing or creating a webform.
  */
-function webform_form(&$node, &$param) {
-  $form['webform'] = array(
-    '#type' => 'markup',
-    '#tree' => TRUE,
-  );
-
+function webform_form(&$node, &$form_state) {
   // Set node defaults if empty.
   if (!isset($node->nid) && !isset($node->webform)) {
     $node->nid = 0;
@@ -628,392 +634,17 @@
     $node->nid = NULL;
   }
 
-  // When the form is rebuilt for a preview, submit_limit may be set incorrectly.
-  if (isset($node->build_mode) && $node->build_mode == NODE_BUILD_PREVIEW && $node->webform['enforce_limit'] == 'no') {
-    $node->webform['submit_limit'] = -1;
-  }
+  $form = node_content_form($node, $form_state);
 
-  /* Save Components in a value (helps with clone.module) */
-  $form['webform']['components'] = array(
+  $form['webform'] = array(
     '#type' => 'value',
-    '#value' => $node->webform['components'],
-  );
-
-  /* Start Edit Form */
-  $form['webform']['settings'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Webform Settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    '#weight' => -4,
-    '#parents' => array('webform'),
-  );
-
-  $form['webform']['settings']['title'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Title'),
-    '#default_value' => $node->title,
-    '#maxlength' => 128,
-    '#required' => TRUE,
-    '#tree' => FALSE,
-  );
-
-  $form['webform']['settings']['body'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Description'),
-    '#description' => t('Text to be shown as teaser and before the form.'),
-    '#default_value' => $node->body,
-    '#cols' => 40,
-    '#rows' => 10,
-    '#tree' => FALSE,
-  );
-
-  $form['webform']['settings']['confirmation'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Confirmation message or redirect URL'),
-    '#description' => t('Message to be shown upon successful submission or a path to a redirect page. Preface message with <em>message:</em> for a simple message that does not require a page refresh. Redirect pages must start with <em>http://</em> for external sites or <em>internal:</em> for an internal path. i.e. <em>http://www.example.com</em> or <em>internal:node/10</em>'),
-    '#default_value' => $node->webform['confirmation'],
-    '#cols' => 40,
-    '#rows' => 10,
-  );
-
-  $form['webform']['settings']['format'] = filter_form($node->format);
-  /* End Edit Form */
-
-  /* Start per-role submission control */
-  $form['webform']['role_control'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Webform access control'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    '#weight' => -3,
-    '#parents' => array('webform'),
-    '#description' => t('These permissions affect which roles can submit this webform. It does not prevent access to the webform page. If needing to prevent access to the webform page entirely, use a content access module such as <a href="http://drupal.org/project/taxonomy_access">Taxonomy Access</a> or <a href="http://drupal.org/project/node_privacy_byrole">Node Privacy by Role</a>.'),
-    '#access' => variable_get('webform_submission_access_control', 1),
-  );
-  $user_roles = user_roles();
-  $form['webform']['role_control']['roles'] = array(
-    '#default_value' => $node->webform['roles'],
-    '#options' => $user_roles,
-    '#type' => 'checkboxes',
-    '#title' => t('Roles that can submit this webform'),
-    '#description' => t('Uncheck all roles to prevent new submissions. The %authenticated role applies to any user signed into the site, regardless of other assigned roles.', array('%authenticated' => $user_roles[2])),
-  );
-  /* End per-role submission control */
-
-  /* Start E-mail Settings Form */
-  $form['webform']['mail_settings'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Webform mail settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    '#weight' => -2,
-    '#parents' => array('webform'),
-    '#theme' => 'webform_mail_settings_form',
-  );
-
-  $form['webform']['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['webform']['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['webform']['mail_settings']['email_components']['email_components'] = array(
-    '#type' => 'checkboxes',
-    '#options' => $options,
-    '#default_value' => $default_value,
-    '#parents' => array('webform', 'email_components'),
-  );
-
-  foreach (array('from_name', 'from_address', 'subject') as $field) {
-    switch ($field) {
-      case 'from_name':
-        $default_value = webform_variable_get('webform_default_from_name');
-        $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_variable_get('webform_default_from_address');
-        $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_variable_get('webform_default_subject');
-        $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['webform']['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['webform']['mail_settings']['email_'. $field .'_option']['#options']['default'] = $default_value;
-    }
-    $form['webform']['mail_settings']['email_'. $field .'_option']['#options']['custom'] = 'custom';
-    $form['webform']['mail_settings']['email_'. $field .'_option']['#options']['component'] = 'component';
-
-    $form['webform']['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['webform']['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['webform']['advanced'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Webform advanced settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#weight' => -1,
-    '#parents' => array('webform'),
-  );
-  $form['webform']['advanced']['teaser'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show complete form in teaser'),
-    '#default_value' => $node->webform['teaser'],
-    '#description' => t('Display the entire form in the teaser display of this node.'),
-  );
-  $form['webform']['advanced']['submit_limit'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Limit the number of submissions a user may send within a specified time period'),
-    '#theme' => 'webform_advanced_submit_limit_form',
-  );
-  $form['webform']['advanced']['submit_limit']['enforce_limit'] = array(
-    '#type' => 'radios',
-    '#options' => array('no' => t('Unlimited'), 'yes' => 'Limit to !count submission(s) !timespan'),
-    '#default_value' => $node->webform['submit_limit'] == -1 ? 'no' : 'yes',
-    '#parents' => array('webform', 'enforce_limit'),
-  );
-  $form['webform']['advanced']['submit_limit']['submit_limit'] = array(
-    '#type' => 'textfield',
-    '#maxlength' => 2,
-    '#size' => 2,
-    '#default_value' => $node->webform['submit_limit'] != -1 ? $node->webform['submit_limit'] : '',
-    '#parents' => array('webform', 'submit_limit'),
+    '#value' => $node->webform,
   );
-  $form['webform']['advanced']['submit_limit']['submit_interval'] = array(
-    '#type' => 'select',
-    '#options' => array(
-      '-1' => t('ever'),
-      '1600' => t('every hour'),
-      '86400' => t('every day'),
-      '604800' => t('every week'),
-    ),
-    '#default_value' => $node->webform['submit_interval'],
-    '#parents' => array('webform', 'submit_interval'),
-  );
-  $form['webform']['advanced']['submit_text'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Submit button text'),
-    '#default_value' => $node->webform['submit_text'],
-    '#description' => t('By default the submit button on this form will have the label <em>Submit</em>. Enter a new title here to override the default.'),
-  );
-  if (user_access('use PHP for additional processing')) {
-    $form['webform']['advanced']['additional_validate'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Additional Validation'),
-      '#description' => t('Enter PHP code to perform additional validation for this form. Include the &lt;?php ?&gt; tags. $form and $form_state are available variables. If validation fails, use the form_set_error function to prevent the form from being submitted. Use the same syntax as a _validate function used in the <a href="http://api.drupal.org/api/file/developer/topics/forms_api.html">Forms API</a>.'),
-      '#default_value' => $node->webform['additional_validate'],
-      '#cols' => 40,
-      '#rows' => 10,
-    );
-
-    $form['webform']['advanced']['additional_submit'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Additional Processing'),
-      '#description' => t('Enter PHP code to perform additional processing for this form (after the validation). Include the &lt;?php ?&gt; tags. $form and $form_state are available variables, use the same syntax as a _submit function used in the <a href="http://api.drupal.org/api/file/developer/topics/forms_api.html">Forms API</a>.'),
-      '#default_value' => $node->webform['additional_submit'],
-      '#cols' => 40,
-      '#rows' => 10,
-    );
-  }
-  else {
-    $form['webform']['advanced']['additional_validate'] = array(
-      '#type' => 'value',
-      '#value' => $node->webform['additional_validate'],
-    );
-
-    $form['webform']['advanced']['additional_submit'] = array(
-      '#type' => 'value',
-      '#value' => $node->webform['additional_submit'],
-    );
-  }
-  /* End Advanced Settings Form */
 
   return $form;
 }
 
 /**
- * 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'] = '<div class="container-inline">';
-      $form['email_'. $field .'_option'][$option]['#suffix'] = '</div>';
-    }
-    // Wrap the default option in a placeholder tag..
-    if (isset($form['email_'. $field .'_option']['#options']['default'])) {
-      $form['email_'. $field .'_option']['default']['#title'] = t('Default') .': '. theme('placeholder', $form['email_'. $field .'_option']['default']['#title']);
-    }
-  }
-
-  return drupal_render($form);
-}
-
-/**
- * Theme the submit limit fieldset on the webform node form.
- */
-function theme_webform_advanced_submit_limit_form($form) {
-  $form['submit_limit']['#attributes']['class'] = 'webform-set-active';
-  $form['submit_interval']['#attributes']['class'] = 'webform-set-active';
-  $replacements = array(
-    '!count' => drupal_render($form['submit_limit']),
-    '!timespan' => drupal_render($form['submit_interval']),
-  );
-  $form['enforce_limit']['no']['#prefix'] = '<div class="container-inline">';
-  $form['enforce_limit']['no']['#suffix'] = '</div>';
-  $form['enforce_limit']['yes']['#prefix'] = '<div class="container-inline">';
-  $form['enforce_limit']['yes']['#suffix'] = '</div>';
-  $form['enforce_limit']['yes']['#title'] = t('Limit to !count submission(s) !timespan', $replacements);
-  return drupal_render($form);
-}
-
-/**
- * Implementation of hook_validate().
- */
-function webform_validate(&$node) {
-  // Ensure the entered e-mail addresses are valid.
-  if (!empty($node->webform['email'])) {
-    $emails = explode(',', $node->webform['email']);
-    foreach ($emails as $email) {
-      if (!valid_email_address(trim($email))) {
-        form_set_error('webform][email', t('The entered email address %address is not a valid address.', array('%address' => $email)));
-        break;
-      }
-    }
-  }
-  if ($node->webform['email_from_address_option'] == 'custom') {
-    if (!valid_email_address($node->webform['email_from_address_custom'])) {
-      form_set_error('webform][email_from_address_custom', t('The entered email address %address is not a valid address.', array('%address' => $node->webform['email_from_address_custom'])));
-    }
-  }
-}
-
-/**
- * Implementation of hook_submit().
- */
-function webform_submit(&$node) {
-  // Add the conditional e-mail recipients to components.
-  if ($node->nid) {
-    $original_node = node_load($node->nid);
-
-    foreach ($original_node->webform['components'] as $cid => $component) {
-      if (!isset($node->webform['components'][$cid])) {
-        $node->webform['components'][$cid] = $component;
-      }
-      if (isset($node->webform['email_components'][$cid])) {
-        $node->webform['components'][$cid]['extra']['email'] = $node->webform['email_components'][$cid];
-      }
-    }
-  }
-  unset($node->webform['email_components']);
-
-  // Merge the e-mail name, address, and subject options into single values.
-  foreach (array('from_name', 'from_address', 'subject') as $field) {
-    $option = $node->webform['email_'. $field .'_option'];
-    if ($option == 'default') {
-      $node->webform['email_'. $field] = 'default';
-    }
-    else {
-      $node->webform['email_'. $field] = $node->webform['email_'. $field .'_'. $option];
-    }
-    unset($node->webform['email_'. $field .'_option']);
-    unset($node->webform['email_'. $field .'_component']);
-    unset($node->webform['email_'. $field .'_custom']);
-  }
-
-  // Set the submit limit to -1 if set to unlimited.
-  if ($node->webform['enforce_limit'] == 'no') {
-    $node->webform['submit_limit'] = -1;
-    $node->webform['submit_interval'] = -1;
-  }
-  unset($node->webform['enforce_limit']);
-}
-
-/**
  * Implementation of hook_form_alter().
  */
 function webform_form_alter(&$form, $form_state, $form_id) {
@@ -1047,7 +678,7 @@
     drupal_set_message(t('This webform is currently unpublished. After finishing your changes to the webform, use the <em>Publish</em> button below.'));
   }
 
-  $form_state['redirect'] = 'node/'. $nid .'/edit/components';
+  $form_state['redirect'] = 'node/'. $nid .'/webform/components';
 }
 
 /**
@@ -1987,7 +1618,7 @@
     drupal_goto('node/'. $vars['node']->nid);
   }
 
-  $vars['confirmation_message'] = check_markup($vars['node']->webform['confirmation'], $vars['node']->format, FALSE);
+  $vars['confirmation_message'] = check_markup($vars['node']->webform['confirmation'], $vars['node']->webform['confirmation_format'], FALSE);
 }
 
 /**
@@ -2084,7 +1715,7 @@
  *   normal e-mails, it will have the value of 'default'.
  * @return
  *   An array of headers to be used when sending a webform email. If headers
- *   for "From", "To", or "Subject" are set, they will take precendence over
+ *   for "From", "To", or "Subject" are set, they will take precedence over
  *   the values set in the webform configuration.
  */
 function theme_webform_mail_headers($form_values, $node, $sid, $cid) {
Index: webform.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.install,v
retrieving revision 1.24
diff -u -r1.24 webform.install
--- webform.install	20 May 2009 20:26:33 -0000	1.24
+++ webform.install	16 Jun 2009 04:56:52 -0000
@@ -26,6 +26,12 @@
         'type' => 'text',
         'not null' => TRUE,
       ),
+      'confirmation_format' => array(
+        'description' => 'The input format used by the confirmation message.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'teaser' => array(
         'description' => 'Boolean value for whether the entire form should be displayed on the teaser.',
         'type' => 'int',
@@ -1016,6 +1022,26 @@
 }
 
 /**
+ * Add a separate column for confirmation message input format.
+ */
+function webform_update_6301() {
+  $ret = array();
+
+  // Safety check to prevent re-adding existing column.
+  if (db_column_exists('webform', 'confirmation_format')) {
+    return $ret;
+  }
+
+  db_add_field($ret, 'webform', 'confirmation_format', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
+  $result = db_query("SELECT n.nid, nr.format FROM {node} n INNER JOIN {node_revisions} nr ON n.vid = nr.vid WHERE n.type = 'webform'");
+  while ($node = db_fetch_object($result)) {
+    db_query('UPDATE {webform} SET confirmation_format = %d WHERE nid = %d', $node->format, $node->nid);
+  }
+
+  return $ret;
+}
+
+/**
  * Recursively delete all files and folders in the specified filepath, then
  * delete the containing folder.
  *
Index: includes/webform.components.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.components.inc,v
retrieving revision 1.1
diff -u -r1.1 webform.components.inc
--- includes/webform.components.inc	15 Jun 2009 20:31:02 -0000	1.1
+++ includes/webform.components.inc	16 Jun 2009 04:56:53 -0000
@@ -193,9 +193,9 @@
         drupal_render($form['components'][$cid]['mandatory']),
         drupal_render($form['components'][$cid]['email']),
         drupal_render($form['components'][$cid]['cid']) . drupal_render($form['components'][$cid]['pid']) . drupal_render($form['components'][$cid]['weight']),
-        l(t('Edit'), 'node/'. $node->nid .'/edit/components/'. $cid),
-        l(t('Clone'), 'node/'. $node->nid .'/edit/components/'. $cid .'/clone'),
-        l(t('Delete'), 'node/'. $node->nid .'/edit/components/'. $cid .'/delete'),
+        l(t('Edit'), 'node/'. $node->nid .'/webform/components/'. $cid),
+        l(t('Clone'), 'node/'. $node->nid .'/webform/components/'. $cid .'/clone'),
+        l(t('Delete'), 'node/'. $node->nid .'/webform/components/'. $cid .'/delete'),
       );
       $row_class = 'draggable'. ($component['type'] != 'fieldset' ? ' tabledrag-leaf' : '');
       $rows[] = array('data' => $row_data, 'class' => $row_class);
@@ -260,7 +260,7 @@
   }
   elseif (isset($_POST['op']) && $_POST['op'] == t('Add')) {
     $component = $form_state['values']['add'];
-    $form_state['redirect'] = array('node/'. $node->nid .'/edit/components/new/'. $component['type'], 'name='. urlencode($component['name']) .'&mandatory='. $component['mandatory'] .'&email='. $component['email'] .'&pid='. $component['pid'] .'&weight='. $component['weight']);
+    $form_state['redirect'] = array('node/'. $node->nid .'/webform/components/new/'. $component['type'], 'name='. urlencode($component['name']) .'&mandatory='. $component['mandatory'] .'&email='. $component['email'] .'&pid='. $component['pid'] .'&weight='. $component['weight']);
   }
   else {
     drupal_set_message(t('The component positions and mandatory values have been updated.'));
@@ -459,7 +459,7 @@
     $cid = webform_component_insert($form_state['values']);
   }
 
-  $form_state['redirect'] = array('node/'. $form_state['values']['nid'] .'/edit/components', isset($cid) ? 'cid='. $cid : '');
+  $form_state['redirect'] = array('node/'. $form_state['values']['nid'] .'/webform/components', isset($cid) ? 'cid='. $cid : '');
 }
 
 function webform_component_delete_form($form_state, $node, $component) {
@@ -484,13 +484,13 @@
     $description = t('This will immediately delete the %name component from the %webform webform. This cannot be undone.', array('%name' => $node->webform['components'][$cid]['name'], '%webform' => $node->title));
   }
 
-  return confirm_form($form, $question, 'node/'. $node->nid .'/edit/components', $description, t('Delete'));
+  return confirm_form($form, $question, 'node/'. $node->nid .'/webform/components', $description, t('Delete'));
 }
 
 function webform_component_delete_form_submit($form, &$form_state) {
   drupal_set_message(t('Component %name deleted.', array('%name' => $form_state['values']['component']['name'])));
   webform_component_delete($form_state['values']['node'], $form_state['values']['component']);
-  $form_state['redirect'] = 'node/'. $form_state['values']['node']->nid .'/edit/components';
+  $form_state['redirect'] = 'node/'. $form_state['values']['node']->nid .'/webform/components';
 }
 
 /**
Index: includes/webform.pages.inc
===================================================================
RCS file: includes/webform.pages.inc
diff -N includes/webform.pages.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/webform.pages.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,396 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ *
+ * Menu callbacks and functions for configuring and editing webforms.
+ */
+
+/**
+ * Main configuration form for editing a webform node.
+ */
+function webform_configure_form(&$form_state, $node) {
+  $form = array();
+
+  $form['nid'] = array(
+    '#type' => 'value',
+    '#value' => $node->nid,
+  );
+
+  /* Start Edit Form */
+  $form['submission'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Submission settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => -4,
+  );
+
+  $form['submission']['confirmation_wrapper']['confirmation'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Confirmation message or redirect URL'),
+    '#description' => t('Message to be shown upon successful submission or a path to a redirect page. Preface message with <em>message:</em> for a simple message that does not require a page refresh. Redirect pages must start with <em>http://</em> for external sites or <em>internal:</em> for an internal path. i.e. <em>http://www.example.com</em> or <em>internal:node/10</em>'),
+    '#default_value' => $node->webform['confirmation'],
+    '#cols' => 40,
+    '#rows' => 10,
+  );
+
+  $form['submission']['confirmation_wrapper']['format'] = filter_form($node->webform['confirmation_format'], NULL, array('confirmation_format'));
+
+  // Submission limit settings.
+  $form['submission']['submit_limit'] = array(
+    '#type' => 'item',
+    '#title' => t('Submission limit'),
+    '#theme' => 'webform_advanced_submit_limit_form',
+    '#description' => t('Limit the number of submissions <em>per user</em>. A user is identified by their user login if logged-in, or by their IP Address and Cookie if anonymous. Use of cookies may be modified in the global <a href="!url">Webform settings</a>.', array('!url' => url('admin/settings/webform'))),
+  );
+  $form['submission']['submit_limit']['enforce_limit'] = array(
+    '#type' => 'radios',
+    '#options' => array('no' => t('Unlimited'), 'yes' => 'Limit to !count submission(s) !timespan'),
+    '#default_value' => $node->webform['submit_limit'] == -1 ? 'no' : 'yes',
+    '#parents' => array('enforce_limit'),
+  );
+  $form['submission']['submit_limit']['submit_limit'] = array(
+    '#type' => 'textfield',
+    '#maxlength' => 2,
+    '#size' => 2,
+    '#default_value' => $node->webform['submit_limit'] != -1 ? $node->webform['submit_limit'] : '',
+    '#parents' => array('submit_limit'),
+  );
+  $form['submission']['submit_limit']['submit_interval'] = array(
+    '#type' => 'select',
+    '#options' => array(
+      '-1' => t('ever'),
+      '1600' => t('every hour'),
+      '86400' => t('every day'),
+      '604800' => t('every week'),
+    ),
+    '#default_value' => $node->webform['submit_interval'],
+    '#parents' => array('submit_interval'),
+  );
+
+  /* End Edit Form */
+
+  /* Start per-role submission control */
+  $form['role_control'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Submission access'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => -3,
+    '#description' => t('These permissions affect which roles can submit this webform. It does not prevent access to the webform page. If needing to prevent access to the webform page entirely, use a content access module such as <a href="http://drupal.org/project/taxonomy_access">Taxonomy Access</a> or <a href="http://drupal.org/project/node_privacy_byrole">Node Privacy by Role</a>.'),
+    '#access' => variable_get('webform_submission_access_control', 1),
+  );
+  $user_roles = user_roles();
+  $form['role_control']['roles'] = array(
+    '#default_value' => $node->webform['roles'],
+    '#options' => $user_roles,
+    '#type' => 'checkboxes',
+    '#title' => t('Roles that can submit this webform'),
+    '#description' => t('Uncheck all roles to prevent new submissions. The %authenticated role applies to any user signed into the site, regardless of other assigned roles.', array('%authenticated' => $user_roles[2])),
+  );
+  /* 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',
+    '#title' => t('Advanced settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#weight' => -1,
+  );
+  $form['advanced']['teaser'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show complete form in teaser'),
+    '#default_value' => $node->webform['teaser'],
+    '#description' => t('Display the entire form in the teaser display of this node.'),
+  );
+  $form['advanced']['submit_text'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Submit button text'),
+    '#default_value' => $node->webform['submit_text'],
+    '#description' => t('By default the submit button on this form will have the label <em>Submit</em>. Enter a new title here to override the default.'),
+  );
+  if (user_access('use PHP for additional processing')) {
+    $form['advanced']['additional_validate'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Additional Validation'),
+      '#description' => t('Enter PHP code to perform additional validation for this form. Include the &lt;?php ?&gt; tags. $form and $form_state are available variables. If validation fails, use the form_set_error function to prevent the form from being submitted. Use the same syntax as a _validate function used in the <a href="http://api.drupal.org/api/file/developer/topics/forms_api.html">Forms API</a>.'),
+      '#default_value' => $node->webform['additional_validate'],
+      '#cols' => 40,
+      '#rows' => 10,
+    );
+
+    $form['advanced']['additional_submit'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Additional Processing'),
+      '#description' => t('Enter PHP code to perform additional processing for this form (after the validation). Include the &lt;?php ?&gt; tags. $form and $form_state are available variables, use the same syntax as a _submit function used in the <a href="http://api.drupal.org/api/file/developer/topics/forms_api.html">Forms API</a>.'),
+      '#default_value' => $node->webform['additional_submit'],
+      '#cols' => 40,
+      '#rows' => 10,
+    );
+  }
+  else {
+    $form['advanced']['additional_validate'] = array(
+      '#type' => 'value',
+      '#value' => $node->webform['additional_validate'],
+    );
+
+    $form['advanced']['additional_submit'] = array(
+      '#type' => 'value',
+      '#value' => $node->webform['additional_submit'],
+    );
+  }
+  /* End Advanced Settings Form */
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save configuration'),
+    '#weight' => 300,
+  );
+
+  return $form;
+}
+
+/**
+ * Validate handler for webform_configure_form().
+ */
+function webform_configure_form_validate($form, &$form_state) {
+  // Ensure the entered e-mail addresses are valid.
+  if (!empty($form_state['values']['email'])) {
+    $emails = explode(',', $form_state['values']['email']);
+    foreach ($emails as $email) {
+      if (!valid_email_address(trim($email))) {
+        form_set_error('email', t('The entered email address %address is not a valid address.', array('%address' => $email)));
+        break;
+      }
+    }
+  }
+  if ($form_state['values']['email_from_address_option'] == 'custom') {
+    if (!valid_email_address($form_state['values']['email_from_address_custom'])) {
+      form_set_error('email_from_address_custom', t('The entered email address %address is not a valid address.', array('%address' => $node->webform['email_from_address_custom'])));
+    }
+  }
+}
+
+/**
+ * Submit handler for webform_configure_form().
+ */
+function webform_configure_form_submit($form, &$form_state) {
+  $node = node_load($form_state['values']['nid']);
+dsm($node);
+dsm($form_state);
+  // Save the confirmation.
+  $node->webform['confirmation'] = $form_state['values']['confirmation'];
+  $node->webform['confirmation_format'] = $form_state['values']['confirmation_format'];
+
+  // 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'];
+
+  // Set the submit limit to -1 if set to unlimited.
+  if ($form_state['values']['enforce_limit'] == 'no') {
+    $node->webform['submit_limit'] = -1;
+    $node->webform['submit_interval'] = -1;
+  }
+  else {
+    $node->webform['submit_limit'] = $form_state['values']['submit_limit'];
+    $node->webform['submit_interval'] = $form_state['values']['submit_interval'];
+  }
+
+  // Set submit button text.
+  $node->webform['submit_text'] = $form_state['values']['submit_text'];
+
+  // Set additional validation and submission code.
+  $node->webform['additional_validate'] = $form_state['values']['additional_validate'];
+  $node->webform['additional_submit'] = $form_state['values']['additional_submit'];
+dsm($node);
+
+  node_save($node);
+}
+
+/**
+ * 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'] = '<div class="container-inline">';
+      $form['email_'. $field .'_option'][$option]['#suffix'] = '</div>';
+    }
+    // Wrap the default option in a placeholder tag..
+    if (isset($form['email_'. $field .'_option']['#options']['default'])) {
+      $form['email_'. $field .'_option']['default']['#title'] = t('Default') .': '. theme('placeholder', $form['email_'. $field .'_option']['default']['#title']);
+    }
+  }
+
+  return drupal_render($form);
+}
+
+/**
+ * Theme the submit limit fieldset on the webform node form.
+ */
+function theme_webform_advanced_submit_limit_form($form) {
+  $form['submit_limit']['#attributes']['class'] = 'webform-set-active';
+  $form['submit_interval']['#attributes']['class'] = 'webform-set-active';
+  $replacements = array(
+    '!count' => drupal_render($form['submit_limit']),
+    '!timespan' => drupal_render($form['submit_interval']),
+  );
+  $form['enforce_limit']['no']['#prefix'] = '<div class="container-inline">';
+  $form['enforce_limit']['no']['#suffix'] = '</div>';
+  $form['enforce_limit']['yes']['#prefix'] = '<div class="container-inline">';
+  $form['enforce_limit']['yes']['#suffix'] = '</div>';
+  $form['enforce_limit']['yes']['#title'] = t('Limit to !count submission(s) !timespan', $replacements);
+  return drupal_render($form);
+}
