Index: webform.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v
retrieving revision 1.155
diff -u -r1.155 webform.module
--- webform.module	21 Jan 2010 02:40:45 -0000	1.155
+++ webform.module	21 Jan 2010 05:47:40 -0000
@@ -372,7 +372,17 @@
   global $user;
   $account = isset($account) ? $account : $user;
 
-  $general_access = user_access('access all webform results', $account) || (isset($submission) && user_access('access own webform submissions', $account) && ($account->uid == $submission->uid)) || (user_access('access own webform results', $account) && $account->uid == $node->uid);
+  $access_all = user_access('access all webform results', $account);
+  $access_own_submission = isset($submission) && user_access('access own webform submissions', $account) && (($account->uid && $account->uid == $submission->uid) || isset($_SESSION['webform_submission'][$submission->sid]));
+  $access_node_submissions = user_access('access own webform results', $account) && $account->uid == $node->uid;
+
+  $general_access = $access_all || $access_own_submission || $access_node_submissions;
+
+  // Disable the page cache for anonymous users in this access callback,
+  // otherwise the "Access denied" page gets cached.
+  if (!$account->uid && user_access('access own webform submissions', $account)) {
+    webform_disable_page_cache();
+  }
 
   switch ($op) {
     case 'view':
@@ -382,7 +392,7 @@
     case 'delete':
       return $general_access && (user_access('delete all webform submissions', $account) || (user_access('delete own webform submissions', $account) && $account->uid == $submission->uid));
     case 'list':
-      return user_access('access all webform results', $account) || (user_access('access own webform submissions', $account) && $account->uid) || (user_access('access own webform results', $account) && $account->uid == $node->uid);
+      return user_access('access all webform results', $account) || (user_access('access own webform submissions', $account) && ($account->uid || isset($_SESSION['webform_submission']))) || (user_access('access own webform results', $account) && $account->uid == $node->uid);
   }
 }
 
@@ -937,8 +947,9 @@
   }
 
   // Get a count of previous submissions by this user.
-  if ($user->uid && (user_access('access own webform submissions') || user_access('access all webform results') || (user_access('access own webform results') && $user->uid == $node->uid))) {
-    $submission_count = db_result(db_query('SELECT count(*) FROM {webform_submissions} WHERE nid = %d AND uid = %d AND is_draft = 0', $node->nid, $user->uid));
+  if ($page && webform_submission_access($node, NULL, 'list')) {
+    module_load_include('inc', 'webform', 'includes/webform.submissions');
+    $submission_count = webform_get_submission_count($node->nid, $user->uid);
   }
 
   // Check if this user has a draft for this webform.
@@ -1513,6 +1524,12 @@
       $time = time();
       setcookie($cookie_name .'['. $time .']', $time, $time + $node->webform['submit_interval'] + 86400);
     }
+
+    // Save session information about this submission for anonymous users,
+    // allowing them to access or edit their submissions.
+    if (!$user->uid && user_access('access own webform submissions')) {
+      $_SESSION['webform_submission'][$form_state['values']['details']['sid']] = $node->nid;
+    }
   }
   else {
     // Sid was found thus update the existing sid in the database.
@@ -1600,7 +1617,8 @@
           return FALSE;
         }
 
-        drupal_mail('webform', 'submission', $address, user_preferred_language($user), array('message' => $email['message'], 'subject' => $email['subject'], 'headers' => $email['headers']), $email['from']);
+        $language = $user->uid ? user_preferred_language($user) : language_default();
+        drupal_mail('webform', 'submission', $address, $language, array('message' => $email['message'], 'subject' => $email['subject'], 'headers' => $email['headers']), $email['from']);
   
         // Debugging output for email.
         if (variable_get('webform_debug', 0) >= 2) {
@@ -2420,6 +2438,20 @@
 }
 
 /**
+ * Disable the Drupal page cache.
+ */
+function webform_disable_page_cache() {
+  // PressFlow and Drupal 7 method.
+  if (function_exists('drupal_page_is_cacheable')) {
+    drupal_page_is_cacheable(FALSE);
+  }
+  // Drupal 6 hack to disable page cache.
+  else {
+    $GLOBALS['conf']['cache'] = FALSE;
+  }
+}
+
+/**
  * Set the necessary breadcrumb for the page we are on.
  */
 function webform_set_breadcrumb($node, $submission = NULL) {
Index: includes/webform.submissions.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.submissions.inc,v
retrieving revision 1.6
diff -u -r1.6 webform.submissions.inc
--- includes/webform.submissions.inc	14 Jan 2010 06:12:47 -0000	1.6
+++ includes/webform.submissions.inc	21 Jan 2010 05:47:40 -0000
@@ -81,7 +81,14 @@
 function webform_submission_delete($node, $submission) {
   // Iterate through all components and let each do cleanup if necessary.
   foreach ($node->webform['components'] as $cid => $component) {
-    webform_component_invoke($component['type'], 'delete', $component, $submission->data[$cid]);
+    if (isset($submission->data[$cid])) {
+      webform_component_invoke($component['type'], 'delete', $component, $submission->data[$cid]);
+    }
+  }
+
+  // Delete any anonymous session information.
+  if (isset($_SESSION['webform_submission'][$submission->sid])) {
+    unset($_SESSION['webform_submission'][$submission->sid]);
   }
 
   db_query('DELETE FROM {webform_submitted_data} WHERE nid = %d AND sid = %d', $node->nid, $submission->sid);
@@ -127,6 +134,7 @@
  * Menu callback; Present a Webform submission page for display or editing.
  */
 function webform_submission_page($node, $submission, $format) {
+  global $user;
   webform_set_breadcrumb($node, $submission);
 
   if ($format == 'form') {
@@ -136,6 +144,7 @@
     $output = webform_submission_render($node, $submission, $format);
   }
 
+  // Add navigation for administrators.
   if (user_access('access all webform results') || (user_access('access own webform results') && $user->uid == $node->uid)) {
     $navigation = theme('webform_submission_navigation', $node, $submission, $format != 'form' ? 'display' : 'form');
     $information = theme('webform_submission_information', $node, $submission);
@@ -145,6 +154,11 @@
     $information = NULL;
   }
 
+  // Disable the page cache for anonymous users viewing or editing submissions.
+  if (!$user->uid) {
+    webform_disable_page_cache();
+  }
+
   return theme('webform_submission_page', $output, $navigation, $information);
 }
 
@@ -181,14 +195,22 @@
  */
 function webform_get_submissions($nid, $header = NULL, $uid = NULL, $pager_count = 0) {
   $sids = NULL;
-  if ($pager_count) {
+  $arguments = array($nid);
+  if ($pager_count || $uid === 0) {
     $pager_query = 'SELECT * FROM {webform_submissions} WHERE nid = %d';
-    if ($uid) {
+    if ($uid !== NULL) {
       $pager_query .= ' AND uid = %d';
+      $arguments[] = $uid;
     }
-    $res = pager_query($pager_query, $pager_count, 0, NULL, $nid, $uid);
+    if ($uid === 0) {
+      $submissions = array_keys($_SESSION['webform_submission']);
+      $placeholders = count($submissions) ? array_fill(0, count($submissions), "%d") : array();
+      $pager_query .= count($submissions) ? ' AND sid IN (' . implode(',', $placeholders) . ')' : ' AND sid = 0';
+      $arguments = array_merge($arguments, $submissions);
+    }
+    $result = pager_query($pager_query, $pager_count, 0, NULL, $arguments);
     $sids = array();
-    while ($row = db_fetch_object($res)) {
+    while ($row = db_fetch_object($result)) {
       $sids[] = $row->sid;
     }
     $sids = implode($sids, ',');
@@ -200,8 +222,8 @@
            'LEFT JOIN {users} u ON u.uid = s.uid '.
            'WHERE sd.nid = %d';
 
-  if ($pager_count && !empty($sids)) {
-    $query .= ' AND s.sid IN (%s)';
+  if ($pager_count && isset($sids)) {
+    $query .= empty($sids) ? ' AND s.sid = 0' : ' AND s.sid IN (%s)';
   }
 
   if ($uid) {
@@ -252,12 +274,26 @@
  * @return
  *   An integer value of the number of submissions.
  */
-function webform_get_submission_count($nid, $uid = NULL) {
-  $query = 'SELECT count(*) FROM {webform_submissions} WHERE nid = %d';
-  if ($uid) {
-    $query .= ' AND uid = %d';
+function webform_get_submission_count($nid, $uid = NULL, $reset = FALSE) {
+  static $counts;
+
+  if (!isset($counts[$nid][$uid]) || $reset) {
+    $query = 'SELECT count(*) FROM {webform_submissions} WHERE nid = %d';
+    $arguments = array($nid);
+    if ($uid !== NULL) {
+      $query .= ' AND uid = %d';
+      $arguments[] = $uid;
+    }
+    if ($uid === 0) {
+      $submissions = $_SESSION['webform_submission'];
+      $placeholders = count($submissions) ? array_fill(0, count($submissions), "%d") : array();
+      $query .= count($submissions) ? ' AND sid IN (' . implode(',', $placeholders) . ')' : ' AND sid = 0';
+      $arguments = array_merge($arguments, array_keys($_SESSION['webform_submission']));
+    }
+
+    $counts[$nid][$uid] = db_result(db_query($query, $arguments));
   }
-  return db_result(db_query($query, $nid, $uid));
+  return $counts[$nid][$uid];
 }
 
 /**
Index: includes/webform.report.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.report.inc,v
retrieving revision 1.9
diff -u -r1.9 webform.report.inc
--- includes/webform.report.inc	21 Jan 2010 03:13:14 -0000	1.9
+++ includes/webform.report.inc	21 Jan 2010 05:47:40 -0000
@@ -25,7 +25,13 @@
 
   $header = theme('webform_results_submissions_header', $node);
   if ($user_filter) {
-    drupal_set_title(t('Submissions for %user', array('%user' => $user->name)));
+    if ($user->uid) {
+      drupal_set_title(t('Submissions for %user', array('%user' => $user->name)));
+    }
+    else {
+      drupal_set_title(t('Your submissions'));
+      webform_disable_page_cache();
+    }
     webform_set_breadcrumb($node);
     $submissions = webform_get_submissions($node->nid, $header, $user->uid, $pager_count);
     $count = webform_get_submission_count($node->nid, $user->uid);
@@ -136,12 +142,17 @@
       $row[] = $submission->remote_addr;
     }
     $row[] = l(t('View'), "node/$node->nid/submission/$sid");
+    $operation_count = 1;
     if ((user_access('edit own webform submissions') && $user->uid == $submission->uid) || user_access('edit all webform submissions')) {
-      $row[] = l(t('Edit'), "node/$node->nid/submission/$sid/edit");
+      $row[] = l(t('Edit'), "node/$node->nid/submission/$sid/edit", array('query' => drupal_get_destination()));
+      $operation_count++;
+    }
+    if ((user_access('delete own webform submissions') && $user->uid == $submission->uid) || user_access('delete all webform submissions')) {
       $row[] = l(t('Delete'), "node/$node->nid/submission/$sid/delete", array('query' => drupal_get_destination()));
+      $operation_count++;
     }
-    else {
-      $row[count($row) - 1] = array('data' => $row[count($row) - 1], 'colspan' => 3);
+    if ($operation_count < 3) {
+      $row[count($row) - 1] = array('data' => $row[count($row) - 1], 'colspan' => 4 - $operation_count);
     }
     $rows[] = $row;
   }
