Index: includes/webform.submissions.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.submissions.inc,v
retrieving revision 1.21
diff -u -r1.21 webform.submissions.inc
--- includes/webform.submissions.inc	10 Mar 2010 04:02:07 -0000	1.21
+++ includes/webform.submissions.inc	15 Mar 2010 23:57:43 -0000
@@ -22,11 +22,7 @@
     }
 
     if (is_array($values)) {
-      $delta = 0;
-      foreach ($values as $key => $value) {
-        $data[$cid]['value'][$delta] = $value;
-        $delta++;
-      }
+      $data[$cid]['value'] = $values;
     }
     else {
       $data[$cid]['value'][0] = $values;
Index: includes/webform.components.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.components.inc,v
retrieving revision 1.29
diff -u -r1.29 webform.components.inc
--- includes/webform.components.inc	11 Mar 2010 01:40:11 -0000	1.29
+++ includes/webform.components.inc	15 Mar 2010 23:57:42 -0000
@@ -615,6 +615,9 @@
     $next_id_query = db_select('webform_component')->condition('nid', $component['nid']);
     $next_id_query->addExpression('MAX(cid) + 1', 'cid');
     $component['cid'] = $next_id_query->execute()->fetchField();
+    if ($component['cid'] == NULL) {
+      $component['cid'] = 1;
+    }
   }
 
   $query = db_insert('webform_component')
Index: includes/webform.emails.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.emails.inc,v
retrieving revision 1.12
diff -u -r1.12 webform.emails.inc
--- includes/webform.emails.inc	10 Mar 2010 04:02:08 -0000	1.12
+++ includes/webform.emails.inc	15 Mar 2010 23:57:42 -0000
@@ -469,6 +469,9 @@
     $next_id_query = db_select('webform_emails')->condition('nid', $email['nid']);
     $next_id_query->addExpression('MAX(eid) + 1', 'eid');
     $email['eid'] = $next_id_query->execute()->fetchField();
+    if ($email['eid'] == NULL) {
+      $email['eid'] = 1;
+    }
   }
 
   $email['excluded_components'] = implode(',', $email['excluded_components']);
Index: webform.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v
retrieving revision 1.200
diff -u -r1.200 webform.module
--- webform.module	11 Mar 2010 01:40:11 -0000	1.200
+++ webform.module	15 Mar 2010 23:57:40 -0000
@@ -909,9 +909,22 @@
 function webform_node_prepare($node) {
   $webform_types = webform_variable_get('webform_node_types');
   if (in_array($node->type, $webform_types) && !isset($node->webform)) {
-    $nodes = array($node->nid => $node);
-    $types = array($node->type);
-    webform_node_load($nodes, $types);
+    $node->webform = array(
+      'confirmation' => '',
+      'confirmation_format' => filter_default_format(),
+      'redirect_url' => '',
+      'teaser' => 0,
+      'allow_draft' => 0,
+      'submit_notice' => 0,
+      'submit_text' => '',
+      'submit_limit' => -1,
+      'submit_interval' => -1,
+      'additional_validate' => '',
+      'additional_submit' => '',
+      'roles' => array(1, 2),
+      'emails' => array(),
+      'components' => array(),
+    );
   }
 }
 
@@ -930,21 +943,7 @@
   // Load defaults for all nodes that are webforms.
   foreach ($nodes as $nid => $node) {
     if (in_array($node->type, $webform_types)) {
-      $nodes[$nid]->webform = array(
-        'confirmation' => '',
-        'confirmation_format' => filter_default_format(),
-        'redirect_url' => '',
-        'teaser' => 0,
-        'allow_draft' => 0,
-        'submit_notice' => 0,
-        'submit_text' => '',
-        'submit_limit' => -1,
-        'submit_interval' => -1,
-        'additional_validate' => '',
-        'additional_submit' => '',
-        'roles' => array(1, 2),
-        'emails' => array(),
-      );
+      webform_node_prepare($nodes[$nid]);
     }
   }
 
@@ -978,8 +977,6 @@
     $nodes[$nid]->webform['components'] = db_select('webform_component')
       ->fields('webform_component')
       ->condition('nid', $nid)
-      ->orderBy('weight')
-      ->orderBy('name')
       ->execute()
       ->fetchAllAssoc('cid', PDO::FETCH_ASSOC);
 
@@ -1055,6 +1052,10 @@
 function webform_node_view(&$node, $view_mode) {
   global $user;
 
+  if (!in_array($node->type, webform_variable_get('webform_node_types'))) {
+    return;
+  }
+
   // Set teaser and page variables a la Drupal 6.
   $teaser = $view_mode == 'teaser';
   $page = arg(0) == 'node' && arg(1) == $node->nid;
Index: webform.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.install,v
retrieving revision 1.43
diff -u -r1.43 webform.install
--- webform.install	13 Mar 2010 02:05:04 -0000	1.43
+++ webform.install	15 Mar 2010 23:57:38 -0000
@@ -310,11 +310,10 @@
       ),
       'no' => array(
         'description' => 'Usually this value is 0, but if a field has multiple values (such as a time or date), it may require multiple rows in the database.',
-        'type' => 'int',
-        'size' => 'tiny',
-        'unsigned' => TRUE,
+        'type' => 'varchar',
+        'length' => 128,
         'not null' => TRUE,
-        'default' => 0,
+        'default' => '0',
       ),
       'data' => array(
         'description' => 'The submitted value of this field, may be serialized for some components.',
@@ -391,7 +390,7 @@
  * needed at all to move from 3.x in Drupal 6 to Drupal 7.
  */
 function webform_update_last_removed() {
-  return 6310;
+  return 6313;
 }
 
 /**
Index: components/grid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/grid.inc,v
retrieving revision 1.16
diff -u -r1.16 grid.inc
--- components/grid.inc	8 Mar 2010 01:04:42 -0000	1.16
+++ components/grid.inc	15 Mar 2010 23:57:41 -0000
@@ -54,21 +54,23 @@
     '#type' => 'textarea',
     '#title' => t('Options'),
     '#default_value' => $component['extra']['options'],
-    '#description' => t('Options to select across the top. One option per line. Key-value pairs may be entered seperated by pipes. i.e. safe_key|Some readable option') . theme('webform_token_help'),
+    '#description' => t('Options to select across the top. One option per line. Key-value pairs must be entered separated by pipes. i.e. safe_key|Some readable option') . theme('webform_token_help'),
     '#cols' => 60,
     '#rows' => 5,
     '#weight' => -3,
     '#required' => TRUE,
+    '#element_validate' => array('_webform_edit_validate_select'),
   );
   $form['extra']['questions'] = array(
     '#type' => 'textarea',
     '#title' => t('Questions'),
     '#default_value' => $component['extra']['questions'],
-    '#description' => t('Questions list down the left side. One question per line.') . theme('webform_token_help'),
+    '#description' => t('Questions list down the left side. One question per line. Key-value pairs must be entered separated by pipes. i.e safe_key|Some readable option') . theme('webform_token_help'),
     '#cols' => 60,
     '#rows' => 5,
     '#weight' => -2,
     '#required' => TRUE,
+    '#element_validate' => array('_webform_edit_validate_select'),
   );
   $form['display']['optrand'] = array(
     '#type' => 'checkbox',
@@ -99,18 +101,20 @@
     '#description' => $filter ? _webform_filter_descriptions($component['extra']['description']) : $component['extra']['description'],
   );
 
-  $questions = _webform_grid_options($component['extra']['questions']);
-  $options = _webform_grid_options($component['extra']['options']);
+  $questions = _webform_select_options($component['extra']['questions'], TRUE);
+  $options = _webform_select_options($component['extra']['options'], TRUE);
 
   if ($component['extra']['optrand']) {
     _webform_shuffle_options($options);
   }
 
-  $delta = 0;
-  foreach ($questions as $question) {
-    $delta++;
+  if ($component['extra']['qrand']) {
+    _webform_shuffle_options($questions);
+  }
+
+  foreach ($questions as $key => $question) {
     if ($question != '') {
-      $element['q' . $delta] = array(
+      $element[$key] = array(
         '#title'         => $question,
         '#required'      => $component['mandatory'],
         '#options'       => $options,
@@ -122,21 +126,9 @@
   }
 
   if (isset($value)) {
-    $cid = 0;
     foreach (element_children($element) as $key) {
-      $element[$key]['#default_value'] = $value[$cid++];
-    }
-  }
-
-  // Shuffle questions if needed.
-  if ($component['extra']['qrand']) {
-    $aux = array();
-    $keys = element_children($element);
-    shuffle($keys);
-    foreach ($keys as $key) {
-      $aux[$key] = array();
+      $element[$key]['#default_value'] = isset($value[$key]) ? $value[$key] : NULL;
     }
-    $element = array_merge($aux, $element);
   }
 
   return $element;
@@ -146,8 +138,8 @@
  * Implementation of _webform_display_component().
  */
 function _webform_display_grid($component, $value, $format = 'html') {
-  $questions = _webform_grid_options($component['extra']['questions']);
-  $options = _webform_grid_options($component['extra']['options']);
+  $questions = _webform_select_options($component['extra']['questions'], TRUE);
+  $options = _webform_select_options($component['extra']['options'], TRUE);
 
   $element = array(
     '#title' => $component['name'],
@@ -219,31 +211,12 @@
 }
 
 /**
- * Implementation of _webform_submit_component().
- */
-function _webform_submit_grid($component, $value) {
-  $options = drupal_map_assoc(array_flip(_webform_grid_options($component['extra']['options'])));
-  $questions = _webform_grid_options($component['extra']['questions']);
-
-  // Put the form in the original option order before saving.
-  // Return the final data with the quotes back in place.
-  $ordered_value = array();
-  $delta = 0;
-  foreach ($questions as $safe_question => $question) {
-    $delta++;
-    $ordered_value['q' . $delta] = isset($value['q' . $delta]) ? $value['q' . $delta] : '';
-  }
-
-  return $ordered_value;
-}
-
-/**
  * Implementation of _webform_analysis_component().
  */
 function _webform_analysis_grid($component, $sids = array()) {
   // Generate the list of options and questions.
-  $options = _webform_grid_options($component['extra']['options']);
-  $questions = array_values(_webform_grid_options($component['extra']['questions']));
+  $options = _webform_select_options($component['extra']['options'], TRUE);
+  $questions = _webform_select_options($component['extra']['questions'], TRUE);
 
   // Generate a lookup table of results.
   $query = db_select('webform_submitted_data', 'wsd')
@@ -291,7 +264,7 @@
  * Implementation of _webform_table_component().
  */
 function _webform_table_grid($component, $value) {
-  $questions = array_values(_webform_grid_options($component['extra']['questions']));
+  $questions = _webform_select_options($component['extra']['questions'], TRUE);
   $output = '';
   // Set the value as a single string.
   if (is_array($value)) {
@@ -314,7 +287,7 @@
   $header = array();
   $header[0] = array('');
   $header[1] = array($component['name']);
-  $items = _webform_grid_options($component['extra']['questions']);
+  $items = _webform_select_options($component['extra']['questions'], TRUE);
   $count = 0;
   foreach ($items as $key => $item) {
     // Empty column per sub-field in main header.
@@ -334,10 +307,10 @@
  * Implementation of _webform_csv_data_component().
  */
 function _webform_csv_data_grid($component, $export_options, $value) {
-  $questions = array_keys(_webform_grid_options($component['extra']['questions']));
+  $questions = _webform_select_options($component['extra']['questions'], TRUE);
   $return = array();
   foreach ($questions as $key => $question) {
-    $return[] = isset($value[$key]) ? $value[$key] : '';
+    $return[] = isset($value[$key]) ? $question : '';
   }
   return $return;
 }
@@ -374,22 +347,3 @@
   $option_count = count($header) - 1;
   return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('class' => array('webform-grid', 'webform-grid-' . $option_count))));
 }
-
-/**
- * Utility function to convert user-entered values into grid options.
- */
-function _webform_grid_options($text) {
-  $options = array();
-  $rows = array_filter(explode("\n", _webform_filter_values(trim($text), NULL, NULL, NULL, FALSE)));
-
-  foreach ($rows as $option) {
-    $option = trim($option);
-    if (preg_match('/^([^|]+)\|(.*)$/', $option, $matches)) {
-      $options[$matches[1]] = $matches[2];
-    }
-    else {
-      $options[$option] = $option;
-    }
-  }
-  return $options;
-}
Index: components/time.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/time.inc,v
retrieving revision 1.26
diff -u -r1.26 time.inc
--- components/time.inc	8 Mar 2010 01:04:42 -0000	1.26
+++ components/time.inc	15 Mar 2010 23:57:41 -0000
@@ -173,17 +173,17 @@
   }
 
   if (isset($value)) {
-    $element['minute']['#default_value'] = $value[1];
+    $element['minute']['#default_value'] = $value['minute'];
   
     // Match the hourly data to the hour format.
-    if ($value[1]) {
-      $timestamp = strtotime($value[0] . ':' . $value[1] . (isset($value[2]) ? $value[2] : ''));
+    if ($value['hour']) {
+      $timestamp = strtotime($value['hour'] . ':' . $value['minute'] . (isset($value['ampm']) ? $value['ampm'] : ''));
       if ($component['extra']['hourformat'] == '24-hour') {
         $element['hour']['#default_value'] = date('H', $timestamp);
       }
       else {
         $element['hour']['#default_value'] = date('g', $timestamp);
-        $element['ampm']['#default_value'] = $value[2];
+        $element['ampm']['#default_value'] = $value['ampm'];
       }
     }
   }
@@ -217,9 +217,9 @@
  */
 function _webform_display_time($component, $value, $format = 'html') {
   $value = array(
-    'hour' => isset($value[0]) ? $value[0] : NULL,
-    'minute' => isset($value[1]) ? $value[1] : NULL,
-    'ampm' => isset($value[2]) ? $value[2] : NULL,
+    'hour' => isset($value['hour']) ? $value['hour'] : NULL,
+    'minute' => isset($value['minute']) ? $value['minute'] : NULL,
+    'ampm' => isset($value['ampm']) ? $value['ampm'] : NULL,
   );
 
   return array(
@@ -259,8 +259,7 @@
     ->fields('wsd', array('no', 'data'))
     ->condition('nid', $component['nid'])
     ->condition('cid', $component['cid'])
-    ->orderBy('sid')
-    ->orderBy('no');
+    ->orderBy('sid');
 
   if (count($sids)) {
     $query->condition('sid', $sids, 'IN');
@@ -272,14 +271,14 @@
   $timestamps = array();
   $submissions = 1;
   foreach ($result as $row) {
-    if ($row['no'] == '0') {
+    if ($row['no'] == 'hour') {
       $submissions++;
       $hour = $row['data'];
       if ($row = db_fetch_array($result)) {
-        if ($row['no'] == '1') {
+        if ($row['no'] == 'minute') {
           $minute = $row['data'];
           if ($row = db_fetch_array($result)) {
-            if ($row['no'] == '2') {
+            if ($row['no'] == 'ampm') {
               $ampm = $row['data'];
               // Build the full timestamp.
               if (drupal_strlen($hour) > 0 && drupal_strlen($minute) > 0 ) {
@@ -308,8 +307,8 @@
  * Implementation of _webform_table_component().
  */
 function _webform_table_time($component, $value) {
-  if (drupal_strlen($value[0]) > 0 && drupal_strlen($value[1]) > 0) {
-    $timestamp = strtotime($value[0] . ':' . $value[1] . $value[2]);
+  if (drupal_strlen($value['hour']) > 0 && drupal_strlen($value['minute']) > 0) {
+    $timestamp = strtotime($value['hour'] . ':' . $value['minute'] . (isset($value['ampm']) ? $value['ampm'] : ''));
     if ($component['extra']['hourformat'] == '24-hour') {
       return check_plain(date('H:i', $timestamp));
     }
@@ -337,8 +336,8 @@
  * Implementation of _webform_csv_data_component().
  */
 function _webform_csv_data_time($component, $export_options, $value) {
-  if (drupal_strlen($value[0]) > 0 && drupal_strlen($value[1]) > 0) {
-    $timestamp = strtotime($value[0] . ':' . $value[1] . $value[2]);
+  if (drupal_strlen($value['hour']) > 0 && drupal_strlen($value['minute']) > 0) {
+    $timestamp = strtotime($value['hour'] . ':' . $value['minute'] . (isset($value['ampm']) ? $value['ampm'] : ''));
     if ($component['extra']['hourformat'] == '24-hour') {
       return date('H:i', $timestamp);
     }
Index: components/select.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/select.inc,v
retrieving revision 1.43
diff -u -r1.43 select.inc
--- components/select.inc	11 Mar 2010 01:40:11 -0000	1.43
+++ components/select.inc	15 Mar 2010 23:57:41 -0000
@@ -46,11 +46,12 @@
  */
 function _webform_edit_select($component) {
   $form = array();
+
   $form['extra']['items'] = array(
     '#type' => 'textarea',
     '#title' => t('Options'),
     '#default_value' => $component['extra']['items'],
-    '#description' => t('A list of selectable options. One option per line. Key-value pairs may be entered seperated by pipes, such as "safe_key|Some readable option". Option groups for lists and menus may be specified with &lt;Group Name&gt;. &lt;&gt; can be used to insert items at the root of the menu after specifying a group.') . theme('webform_token_help'),
+    '#description' => t('<strong>Key-value pairs MUST be specified as "safe_key|Some readable option"</strong>. Only alphanumeric characters and underscores are allowed as a key. One option per line. Option groups may be specified with &lt;Group Name&gt;. &lt;&gt; can be used to insert items at the root of the menu after specifying a group.') . theme('webform_token_help'),
     '#cols' => 60,
     '#rows' => 5,
     '#weight' => -2,
@@ -69,21 +70,18 @@
   $form['extra']['multiple'] = array(
     '#type' => 'checkbox',
     '#title' => t('Multiple'),
-    '#return_value' => 'Y',
     '#default_value' => $component['extra']['multiple'],
     '#description' => t('Check this option if the user should be allowed to choose multiple values.'),
   );
   $form['extra']['aslist'] = array(
     '#type' => 'checkbox',
     '#title' => t('Listbox'),
-    '#return_value' => 'Y',
     '#default_value' => $component['extra']['aslist'],
     '#description' => t('Check this option if you want the select component to be of listbox type instead of radiobuttons or checkboxes.'),
   );
   $form['extra']['other_option'] = array(
     '#type' => 'checkbox',
     '#title' => t('Allow "Other..." option'),
-    '#return_value' => 'Y',
     '#default_value' => $component['extra']['other_option'],
     '#description' => t('Check this option if you want to allow users to enter an option not on the list.'),
     '#access' => module_exists('select_or_other'),
@@ -109,14 +107,15 @@
 /**
  * Element validation callback. Ensure keys are not duplicated.
  */
-function _webform_edit_validate_select($element, $form_state) {
-  // TODO: Validate e-mail addresses when used as keys?\
-
-  // Check for duplicate key values to prevent unexpected data loss.
+function _webform_edit_validate_select($element, &$form_state) {
+  // Check for duplicate key values to prevent unexpected data loss. Require
+  // all options to include a safe_key.
   if (!empty($element['#value'])) {
-    $lines = explode("\n", $element['#value']);
+    $lines = explode("\n", trim($element['#value']));
     $existing_keys = array();
     $duplicate_keys = array();
+    $missing_keys = array();
+    $long_keys = array();
     $group = '';
     foreach ($lines as $line) {
       $matches = array();
@@ -125,11 +124,14 @@
         $group = $matches[1];
         $key = NULL; // No need to store group names.
       }
-      elseif (preg_match('/^([^|]+)\|(.*)$/', $line, $matches)) {
+      elseif (preg_match('/^([^|]*)\|(.*)$/', $line, $matches)) {
         $key = $matches[1];
+        if (strlen($key) > 128) {
+          $long_keys[] = $key;
+        }
       }
       else {
-        $key = $line;
+        $missing_keys[] = $line;
       }
 
       if (isset($key)) {
@@ -142,6 +144,14 @@
       }
     }
 
+    if (!empty($missing_keys)) {
+      form_error($element, t('Every option must have a key specified. Specify each option as "safe_key|Some readable option".'));
+    }
+
+    if (!empty($long_keys)) {
+      form_error($element, t('Option keys must be less than 128 characters. The following keys exceed this limit:') . theme('item_list', $long_keys));
+    }
+
     if (!empty($duplicate_keys)) {
       form_error($element, t('Options within the select list must be unique. The following keys have been used multiple times:') . theme('item_list', array('items' => $duplicate_keys)));
     }
@@ -164,13 +174,13 @@
 
   // Convert the user-entered options list into an array.
   $default_value = $filter ? _webform_filter_values($component['value'], NULL, NULL, NULL, FALSE) : $component['value'];
-  $options = _webform_select_options($component['extra']['items'], $component['extra']['aslist'] !== 'Y', $filter);
+  $options = _webform_select_options($component['extra']['items'], !$component['extra']['aslist'], $filter);
 
   if ($component['extra']['optrand']) {
     _webform_shuffle_options($options);
   }
 
-  if ($component['extra']['aslist'] === 'Y' && $component['extra']['multiple'] !== 'Y' && !($component['mandatory'] && !empty($component['value']))) {
+  if ($component['extra']['aslist'] && !$component['extra']['multiple'] && !($component['mandatory'] && !empty($component['value']))) {
     $options = array('' => t('select...')) + $options;
   }
 
@@ -179,7 +189,7 @@
 
   // Set the default value.
   if (isset($value)) {
-    if ($component['extra']['multiple'] === 'Y') {
+    if ($component['extra']['multiple']) {
       // Set the value as an array.
       $element['#default_value'] = array();
       foreach ((array) $value as $key => $option_value) {
@@ -196,7 +206,7 @@
   }
   elseif ($default_value != '') {
     // Convert default value to a list if necessary.
-    if ($component['extra']['multiple'] === 'Y') {
+    if ($component['extra']['multiple']) {
       $varray = array_filter(explode(',', $default_value));
       foreach ($varray as $key => $v) {
         $element['#default_value'][] = $v;
@@ -206,17 +216,17 @@
       $element['#default_value'] = $default_value;
     }
   }
-  elseif ($component['extra']['multiple'] === 'Y') {
+  elseif ($component['extra']['multiple']) {
     $element['#default_value'] = array();
   }
 
-  if ($component['extra']['other_option'] === 'Y' && module_exists('select_or_other')) {
+  if ($component['extra']['other_option'] && module_exists('select_or_other')) {
     // Set display as a select list:
     $element['#type'] = 'select_or_other';
     $element['#other'] = !empty($component['extra']['other_text']) ? check_plain($component['extra']['other_text']) : t('Other...');
     $element['#other_unknown_defaults'] = 'other';
     $element['#other_delimiter'] = ', ';
-    if ($component['extra']['multiple'] === 'Y') {
+    if ($component['extra']['multiple']) {
       $element['#multiple'] = TRUE;
       $element['#select_type'] = 'checkboxes';
     }
@@ -224,19 +234,19 @@
       $element['#multiple'] = FALSE;
       $element['#select_type'] = 'radios';
     }
-    if ($component['extra']['aslist'] === 'Y') {
+    if ($component['extra']['aslist']) {
       $element['#select_type'] = 'select';
     }
   }
-  elseif ($component['extra']['aslist'] === 'Y') {
+  elseif ($component['extra']['aslist']) {
     // Set display as a select list:
     $element['#type'] = 'select';
-    if ($component['extra']['multiple'] === 'Y') {
+    if ($component['extra']['multiple']) {
       $element['#multiple'] = TRUE;
     }
   }
   else {
-    if ($component['extra']['multiple'] === 'Y') {
+    if ($component['extra']['multiple']) {
       // Set display as a checkbox set.
       $element['#type'] = 'checkboxes';
       // Drupal 6 hack to properly render on multipage forms.
@@ -326,34 +336,31 @@
 function _webform_submit_select($component, $value) {
   $options = drupal_map_assoc(array_flip(_webform_select_options($component['extra']['items'], TRUE)));
 
+  $return = NULL;
   if (is_array($value)) {
+    $return = array();
     foreach ($value as $key => $option_value) {
       // Handle options that are specified options.
       if ($option_value !== '' && isset($options[$key])) {
         // Checkboxes submit an *integer* value of 0 when not checked.
-        if ($option_value === 0 && $options[$key] != '0' && $component['extra']['aslist'] !== 'Y' && $component['extra']['multiple'] === 'Y') {
+        if ($option_value === 0 && $options[$key] !== '0' && !$component['extra']['aslist'] && $component['extra']['multiple']) {
           unset($value[$key]);
         }
         else {
-          $value[$key] = $options[$key];
+          $return[] = $key;
         }
       }
       // Handle options that are added through the "other" field.
-      elseif ($component['extra']['other_option'] === 'Y' && module_exists('select_or_other')) {
-        $value[$key] = $option_value;
+      elseif ($component['extra']['other_option'] && module_exists('select_or_other')) {
+        $return[] = $option_value;
       }
-      else {
-        unset($value[$key]);
-      }
-    }
-
-    // Always save at least something, even if it's an empty single value.
-    if (empty($value)) {
-      $value[0] = '';
     }
   }
+  elseif (is_string($value)) {
+    $return = $value;
+  }
 
-  return $value;
+  return $return;
 }
 
 /**
@@ -462,7 +469,7 @@
     }
 
     // Add a row for any unknown or user-entered values.
-    if ($component['extra']['other_option'] === 'Y') {
+    if ($component['extra']['other_option']) {
       $full_count = $count_query->execute()->fetchField();
       $other_count = $full_count - $normal_count;
       $display_option = !empty($component['extra']['other_text']) ? check_plain($component['extra']['other_text']) : t('Other...');
@@ -509,7 +516,7 @@
     $headers[0][] = '';
     $headers[1][] = $component['name'];
     $items = _webform_select_options($component['extra']['items'], TRUE);
-    if ($component['extra']['other_option'] === 'Y') {
+    if ($component['extra']['other_option']) {
       $other_label = !empty($component['extra']['other_text']) ? check_plain($component['extra']['other_text']) : t('Other...');
       $items[$other_label] = $other_label;
     }
@@ -552,7 +559,7 @@
     }
 
     // Any remaining items in the $value array will be user-added options.
-    if ($component['extra']['other_option'] === 'Y') {
+    if ($component['extra']['other_option']) {
       $return[] = count($value) ? implode(',', $value) : '';
     }
   }
Index: components/date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/date.inc,v
retrieving revision 1.31
diff -u -r1.31 date.inc
--- components/date.inc	8 Mar 2010 01:04:42 -0000	1.31
+++ components/date.inc	15 Mar 2010 23:57:40 -0000
@@ -124,11 +124,7 @@
   );
 
   if (isset($value)) {
-    $element['#default_value'] = array(
-      'month' => $value[0],
-      'day' => $value[1],
-      'year' => $value[2],
-    );
+    $element['#default_value'] = $value;
   }
 
   return $element;
@@ -261,7 +257,7 @@
 function _webform_submit_date($component, $value) {
   // Webform stores dates in month/day/year rows.
   // Ensure consistency when using international date formats.
-  return array($value['month'], $value['day'], $value['year']);
+  return array('month' => $value['month'], 'day' => $value['day'], 'year' => $value['year']);
 }
 
 /**
@@ -269,9 +265,9 @@
  */
 function _webform_display_date($component, $value, $format = 'html') {
   $value = array(
-    'month' => isset($value[0]) ? $value[0] : NULL,
-    'day' => isset($value[1]) ? $value[1] : NULL,
-    'year' => isset($value[2]) ? $value[2] : NULL,
+    'month' => isset($value['month']) ? $value['month'] : NULL,
+    'day' => isset($value['day']) ? $value['day'] : NULL,
+    'year' => isset($value['year']) ? $value['year'] : NULL,
   );
 
   return array(
@@ -308,8 +304,7 @@
     ->fields('wsd', array('no', 'data'))
     ->condition('nid', $component['nid'])
     ->condition('cid', $component['cid'])
-    ->orderBy('sid')
-    ->orderBy('no');
+    ->orderBy('sid');
 
   if (count($sids)) {
     $query->condition('sid', $sids, 'IN');
@@ -359,8 +354,8 @@
  * Implementation of _webform_table_component().
  */
 function _webform_table_date($component, $value) {
-  if (drupal_strlen($value[0]) > 0 && drupal_strlen($value[1]) > 0 && drupal_strlen($value[2]) > 0) {
-    $timestamp = webform_strtotime($value[0] . '/' . $value[1] . '/' . $value[2]);
+  if (drupal_strlen($value['month']) > 0 && drupal_strlen($value['day']) > 0 && drupal_strlen($value['year']) > 0) {
+    $timestamp = webform_strtotime($value['month'] . '/' . $value['day'] . '/' . $value['year']);
     $format = webform_date_format('short');
     return format_date($timestamp, 'custom', $format, 0);
   }
@@ -384,8 +379,8 @@
  * Implementation of _webform_csv_data_component().
  */
 function _webform_csv_data_date($component, $export_options, $value) {
-  if (drupal_strlen($value[0]) > 0 && drupal_strlen($value[1]) > 0 && drupal_strlen($value[2]) > 0) {
-    $timestamp = webform_strtotime($value[0] . '/' . $value[1] . '/' . $value[2]);
+  if (drupal_strlen($value['month']) > 0 && drupal_strlen($value['day']) > 0 && drupal_strlen($value['year']) > 0) {
+    $timestamp = webform_strtotime($value['month'] . '/' . $value['day'] . '/' . $value['year']);
     $format = webform_date_format('short');
     return format_date($timestamp, 'custom', $format, 0);
   }
