Problem

When submitting a third-party form displayed in a block on the same page as a restricted webform, this message persists: "You must login or register to view this form". See screenshot 1 and screenshot 2.

Steps to reproduce:

  1. Set up a fresh d7 instance
  2. Enable webform 7.x-4.x
  3. Create a webform and make it restricted (go to node/XXX/webform/configure and under 'Roles that can submit this webform' select, for instance, 'authenticated user')
  4. Make a third-party form show up in a block - for instance turn on the core search module and put the search block in a visible region
  5. View the webform as anonymous -> you should see a message 'You must login or register to view this form.' (screenshot 1)
  6. Submit the search form from that webform page -> the message will show up on the search results page (screenshot 2) which is confusing for users

Proposed resolution

The problem seems to lie in drupal_set_message() being called in the theme function. The webform is built twice: once when it gets displayed, and once when it gets submitted. When drupal_set_message() gets called the second time, it creates a message in the session which will get displayed when the next page is rendered, no matter what that page is.

Possible solutions:

1) Show the message only if we are dealing with a GET request:

diff --git a/webform.module b/webform.module
@@ -2156,7 +2156,7 @@ function theme_webform_view_messages($variables) {
-  if ($page && isset($message)) {
+  if ($page && isset($message) && $_SERVER['REQUEST_METHOD'] == 'GET') {
     drupal_set_message($message, $type, FALSE);
   }
}

(see patch attached). The problem with this solution is that if for whatever reason the user arrives on the webform using a POST request, then the message will not show up.

2) Show the message only if the user has not submitted the webform, maybe something like this:

-  if ($page && isset($message)) {
+  if ($page && isset($message) && empty($form_state['input'])) {
     drupal_set_message($message, $type, FALSE);
   }

3) Display the message as a regular form element instead of using drupal_set_message(), maybe something like this:

   if ($page && isset($message)) {
-    drupal_set_message($message, $type, FALSE);
+    $form['message'] = array('#markup' => $message);
   }

However this might be a significant change in the UX.

4) There are probably other solutions.

Ideas ?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fengtan created an issue. See original summary.

quicksketch’s picture

Hm, I'm failing to see how $page would be TRUE when viewing a search result. That value should be set based on node_is_page() which should only fire if you're on a node/x path. The best solution would be to A) figure out why $page is somehow TRUE and B) fix it on search result pages so that it becomes FALSE. That would fix the message appearing in the first place.

fengtan’s picture

Thanks for the hints @quicksketch.

The problem seems to be similar to #2038621: Search block "submit" action causes hook_node_view to be called and could actually lie in the way Drupal handles form submissions.

When we submit the search form, it looks like Drupal calls menu_execute_active_handler() twice:

  1. First on the current page, i.e. the webform. As a result webform_node_view() gets called, and node_is_page() is true so drupal_set_message() is called.
  2. And then on the target page, i.e. the search results. The message gets displayed.
fengtan’s picture

Issue summary: View changes
fengtan’s picture