Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Hi,
I wanted to reach out and see if the webform 3.x branch would welcome a patch for token support on both confirmation message and redirect url.
kind regards,
Chris
Comments
Comment #1
quicksketchI'm not sure whether you mean Webform tokens (%username, etc.) or Token module tokens ([user], [nid], etc.). If the latter, the confirmation message is already run through the Drupal input format system, meaning that you can install any generic token filter module and get token functionality there. If wanting to use Token module tokens throughout Webform, this should be consolidated with #428982: New hooks for additional token replacements.
If you're referring to using Webform tokens in the confirmation message and redirect URL, I would be open to accepting a patch for this functionality. Adding tokens like %nid and %sid would also be useful for these purposes.
Comment #2
chriscalip CreditAttribution: chriscalip commented@quicksketch
sorry about the ambiguity, yes I was referring to webform tokens.
Thanks I would be happy to submit a patch, will start working on it tomorrow.
Comment #3
quicksketchSounds great, I'd be happy to review a patch. I'm moving this to a feature request.
Comment #4
chriscalip CreditAttribution: chriscalip commentedpatch
Comment #5
chriscalip CreditAttribution: chriscalip commentedwhoops previous patch was git based please ignore. This new patch is per http://drupal.org/patch/create diff example.
Well it looks like I walked into a minefield here :) and I might have to tone down my patch goal to just the give webform token support to the redirect url. Here's why on file webform.module function webform_client_form_submit we still have lots of contextual information (post variables,node,submission stuff) from the submit. While the function that renders the confirmation message on file webform.module function _webform_confirmation only has the node. Not to mention this feature request might have to deal with the filter descriptions popups for both redirect_url and confirmation message (heh) like the one found in the email template fieldset.
I hope this at least helps initially get the ball rolling..
Comment #6
chriscalip CreditAttribution: chriscalip commentedforgot to watch my directories.
Comment #7
quicksketchI would suggest _webform_filter_values() be applied on the entire URL, not just on the query string. Say you wanted to have a redirect to "node/%nid" for example, %nid is not part of the query string.
Comment #8
chriscalip CreditAttribution: chriscalip commentedThats a good point there so here's what I did scrapped the previous patches and remade with this patch.
Comment #9
chriscalip CreditAttribution: chriscalip commentedwhoops forgot my manners, here's a patch per http://drupal.org/patch/create instructions.
Comment #10
chriscalip CreditAttribution: chriscalip commentedComment #11
chriscalip CreditAttribution: chriscalip commentedComment #12
chriscalip CreditAttribution: chriscalip commentedComment #13
chriscalip CreditAttribution: chriscalip commentedupdated patch .. the loop didn't look right.
Comment #14
danmed CreditAttribution: danmed commentedI have updated my current Webform version (6.x-3.1) with this patch and it is working fine. I had spent hours on that, trying using custom module, hook_form_alter, ...
The solution brought about by this patch suits me fine (I am but a "beginner" with Drupal).
Do you intend to include this in a future "recommended" release for Webform?
Thanks for all.
Comment #15
danmed CreditAttribution: danmed commentedOuch, I did not follow this up, but current recommended release does not seems to include the enhancements provided by this patch. I guess that I should not try to patch the current version (6.x-3.4) with this...
I do need this feature, which way should I go please?
thanks
Comment #16
silurius CreditAttribution: silurius commentedSubscribing.
EDIT: Forgot to ask for clarification, would this patch (in a nutshell) allow us to show a basic submission summary in the confirmation message? E.g. use tokens to spit out most recent submission, or something along those lines.
Comment #17
quicksketchYes, even though the title just says redirect URL, the original issue also describes working on the confirmation message. I've marked #712060: Allow tokens in the redirect URL field duplicate. This issue may also be of interest as an alternative of a summary page: #435232: Summary/review/preview page before final submission in multistep forms
Comment #18
sabrawy CreditAttribution: sabrawy commentedi wish we can use token modules with webform ([user], [nid], etc.)
we always use webform block to get the webform with the content such as quotation form and payment
if webform can use token module we can pass a cck field as price for example or anything else
Comment #19
xevious CreditAttribution: xevious commentedIs there a plan to add this patch back into the module? I'm on 6x-3.4 and need to display the submission number on the confirmation page. The $_GET['sid'] hack does not work if the webform has a page break.
Comment #20
Alexander Matveev CreditAttribution: Alexander Matveev commentedsubscribing,
that's a very useful feature
Comment #21
wilgrace CreditAttribution: wilgrace commentedI'm still looking for some way to either display submission info on the confirmation page, or redirect users to their submission page. Is there any progress on this?
Comment #22
mstrelan CreditAttribution: mstrelan commentedFor confirmation messages the following patch should apply to 6.x-3.4 however this doesn't address tokens in the URL
Comment #23
mstrelan CreditAttribution: mstrelan commentedReroll of #22 with support for confirmation messages using either
drupal_set_message()
ortemplate_preprocess_webform_confirmation()
Comment #24
Clint Eagar CreditAttribution: Clint Eagar commentedWhen will this thread be rolled into the module?
I'm hoping for some functionality that will allow me to use Webform tokens in the redirect URL, like this:
http://www.example.com?email=%value[email]
Comment #25
quicksketchIt'll be included when:
A) A complete patch has been written and uploaded.
B) It has been tested and approved.
Right now our current path is good but only accomplishes 1/2 the task (it supports confirmation message but not URL).
Comment #26
charlie-s CreditAttribution: charlie-s commentedSubscribing to this topic.
I've just had a thought... What about using template.php to hijack the confirmation page and resend the user to a new page with the SID and NID now in hand?
Comment #27
ikeigenwijs CreditAttribution: ikeigenwijs commentedfollowing
Comment #28
quicksketchIf you wanted to do this in a correct way you'd use a module to set $form_state['redirect'] after the submission is finished processing. template.php is for changing the display of your site, not the functionality.
Comment #29
charlie-s CreditAttribution: charlie-s commentedThanks for the note, quicksketch. You are correct, it definitely belongs in a module.
Comment #30
jaymallison CreditAttribution: jaymallison commentedJust thought I'd drop a note to say that I got webform tokens working against the redirect_url in webform 6x-3.9.
I had to add this line to webform.module:
I added it in the final elseif block in the function webform_client_form_submit().
I'm no patch maker, I just fiddle with code till it works. Hopefully this helps someone out. Maybe a savvy patcher can patch this and get it committed?
Comment #31
quicksketchSorry after looking over this issue again it looks like I really should have kept these patches separate. @jaymallison's patch works just fine but the code in #23 could have some pretty nasty side-effects of showing other user's submission information just by changing the URL.
What I've done is reopen #712060 for the redirect URL and this one can be for the confirmation message.
Comment #32
quicksketchThis particular issue is dependent upon #810160: On confirmation page, use a hash parameter for SID. to prevent access problems. We need to somehow make it so that users can only view their own submission confirmation pages if they're going to contain sensitive information.
Comment #33
mstrelan CreditAttribution: mstrelan commentedI would have thought that
webform_get_submission
would do an access check. Then the patch in #23 would work, although would need a fallback for ifwebform_get_submission
returned FALSE.But I guess this doesn't help with anonymous submissions...
Comment #34
quicksketchNope, no access check here. You don't access check things like node_load() either, the only check is on if the user can actually *view* that content. Since you might have any number of reasons for loading a node (or a submission in this case), even if you don't have access to view it. Usually in fact, loading a piece of content is necessary before checking if access is even available.
Comment #35
sunshinee CreditAttribution: sunshinee commentedsubscribing
Comment #36
rbrownell+1
Comment #37
jaymallison CreditAttribution: jaymallison commentedI don't know if this is just too obvious, but it's easy to have node token support on the page, at least in D7 (yes I know this is a D6 thread). I imagine a minor change to this line will make it work in 6 as well.
1) Copy the webform-confirmation.tpl.php file to your theme's directory.
2) Change
print $confirmation_message;
toprint token_replace($confirmation_message,array('node'=>$node));
3) Clear cache
4) Profit
Comment #38
jjjames CreditAttribution: jjjames commentedFollowing
Comment #39
vernond CreditAttribution: vernond commentedI independently arrived at the same place as the patch in #23 (@mstrelan - either we're in the 'great minds' category, or it's the other thing...). What I did do differently was put a 20 second time limit on the token replacement, so that any submission requested more than 20 server seconds after the original submission will get the default confirmation message of 'Thank you, your submission has been received'.
This measure does not bullet-proof the potential snooping by folk clever enough to play with the sid in the URL, but it should curtail their success rate:
- A busy site with several Webforms would have a certain amount of randomity due to sid's not being sequential for a particular Webform node;
- A site with a single Webform that experiences a fairly low volume of traffic would have some insurance due to the large amount of time between submissions;
- The highest risk is faced by a site hosting an excessively popular single Webform.
In short, I am not certain that sufficient risk is mitigated by the time limit. What do you guys think?
The other alternative I thought of (and was waaayyyyy too lazy to even try implement) was additionally storing a session token on the webform_submissions table and using that as the criteria for deciding whether to do the token replacements or show the default.
Comment #40
vernond CreditAttribution: vernond commented@myself in #39 - why would we need 20 seconds... surely 1 second would be more than enough? Submission is saved, then confirmation is generated. Is there really a hosting solution that would require 20 seconds between those two steps? Doubtful.
Comment #41
bayousoft CreditAttribution: bayousoft commentedPatch in #39 works for me.
Comment #42
vernond CreditAttribution: vernond commented@bayousoft: did you bring the 20 seconds window down to maybe 2 or so? I cannot explain why/how I arrived at that large an interval.
Comment #43
vernond CreditAttribution: vernond commentedComment #44
vernond CreditAttribution: vernond commented@quicksketch: do you have any thoughts (negative or otherwise) on the patches in [#39] (apart from the silly 20 second window which needs to decrease), or may I tidy up and commit?
Comment #45
quicksketchI think as a general approach this looks pretty good. However I'd feel much better about it if we did a "real" check such as comparing the global $user->uid and the submission UID. And in the case that it's anonymous, use our cookie that we set also. I think that in addition to the short window is probably okay. The short window allows for anonymous visitors without a cookie to operate properly after all so I think it's a nice safety check, but I'd prefer it weren't our only check.
Comment #46
joelrosen CreditAttribution: joelrosen commentedQuick question: Is there any reason why this couldn't be properly solved by storing submission data in $_SESSION, and writing a separate menu callback that then grabs the data from $_SESSION to populate a template? This way there's no lookup using the stored SID, and none of this arbitrary time-limit stuff. I figure this ought to be possible by saving the session data using hook_webform_submission_insert in a submodule. I'm going to go ahead and try this for my site but please let me know if it won't work or there's a better way to do it. Thanks.
Comment #47
quicksketch@joelrosen: I suppose we could put the information in a $_SESSION, or at least the submission IDs in a session so that we could reliably and securely know the available SIDs. Storing the whole submission in session seems like its excessive since it's already stored in one place, and things could get messy if a user is allowed to edit their submissions or worse yet, someone *else* edits their submission (like an administrator), but only the copy in the database gets updated, not the one in the $_SESSION variable.
That said, I think there's substantial merit in just using $_SESSION to store SIDs for anonymous users. I'd like to give it some testing to figure out how well it works with the anonymous page caching.
Comment #48
joelrosen CreditAttribution: joelrosen commentedWell, I got it working on my site using this method. Also got it integrated with webform_tokens. I'll look into posting the submodule code somewhere if you're interested. It didn't require any modifications to webform's code. Not sure yet if I will run into issues with anonymous page caching...
Comment #49
joelrosen CreditAttribution: joelrosen commentedOk I set up a sandbox project here: http://drupal.org/sandbox/joelrosen/1490388
Comments are welcome. If other people think this looks like a reasonable solution, I think it might be a nice replacement to what seems to me to be a somewhat hacky and insecure answer here: http://drupal.org/node/1245298
Comment #50
Liam MorlandI know this opens a bigger issue, but why does a regular form submission result in a redirect? Why not take the POST of the form data and serve a 200 status with the confirmation page?
Comment #51
quicksketchThis is to prevent users from accidentally re-submitting the form by using the back button.
Comment #52
Liam MorlandI tried the module in #49 and it works unless the anonymous user has cookies disabled, in which case they get "Access denied" instead of the confirmation page. There needs to be a better solution for that case.
Another suggestion: When the form is submitted, instead of redirecting to
done?sid=#
, redirect todone?session=#
, where # is the PHP session ID. Webform can look up the sid from that and do the appropriate token replacement. Session IDs are so long that guessing them is not really feasible.Comment #53
Liam MorlandIf you agree with my suggestion in #52, I will work on coding a patch.
Comment #54
quicksketchThanks for the offer Liam. :)
There have been a number of requests to *remove* the SID from the URL for a variety of reasons (Analytics code and "it looks ugly" have mostly been the requests), but neither of those complaints are entirely valid. Something that could be problem however is that anonymous users don't even *have* sessions when using Pressflow or Drupal 7. Starting a session for anonymous users could have a performance impact on sites with a lot of anonymous users who are completing Webforms.
That said, I do think the session ID is a good identifier. I would encourage the session ID to be combined with some other information (such as the submission ID) so that users who submit multiple submissions are ensured to get different confirmation pages while within the same session. Usually just about all caching is disabled when a session ID is present, but in the event that some cache *is* enabled, you'd want to make sure that you don't serve up a cached copy of a previous submission.
On most of my sites, any time the user submits a form, I disable caching at the CDN and Varnish layers for 5 minutes (or however long the Drupal page cache lifetime is). I don't think starting a session is such a bad thing either, as long as the session has a short lifetime.
So the question I have here is whether validation of the URL will be done by checking against the user's session cookie (in which case the user will have a limited amount of time in which the URL will work, based on the lifetime of their session), or if we'll simply "confirm" the session ID matches the submission. In which case users could copy/paste links and send them to other users who don't have the same session. If we take the latter route, we'd need to store the session ID in the database. At that point, the point of using the Session ID is lost, since you could just as easily generate a random hash and save that in the database and not use sessions at all, thus circumventing the whole caching problem.
Comment #55
Liam MorlandI did not know this. Now knowing this, I took a different approach.
The attached patch is to Webform 4.x-dev. It applies token replacement to confirmation messages and puts an access callback on the confirmation page. For logged-in users, those with results access and those accessing their own submissions are allowed. Anonymous users are allowed if the requested submission is by an anonymous user form the same IP address in the last 5 seconds. I think this removes any practical ability to view someone else's confirmation message. If this is not good enough, webform_confirmation_page_access() can be adjusted to fix it. I am interested to hear your thoughts.
Comment #56
Liam MorlandThis version is the same as #55, but has a better display for the token list.
Comment #57
quicksketchIP Address sometimes isn't the best indicator either. Say you're in a university classroom filling out a survey, *everyone* in the room has the same ip address because they're going through the same router at the front of the classroom. That's the main reason why #246470: Allow cookies as sole voter validation needs to be addressed, because limiting by IP address only is causing grief for a lot of users.
I don't think the session approach would be a bad idea. You can *give* anonymous users a session just by putting something in the $_SESSION variable. http://api.drupal.org/drupal_set_message is a good example of how sessions can work for anonymous users, though I think it cleans up the $_SESSION in drupal_get_messages(), so maybe a real session isn't being used there at all.
Comment #58
Liam MorlandOK, if it is not too hard to start a session, then I'll work on that approach. It would be a relatively minor change to what is there in the patch already.
The IP address is used as an easy extra check. Security is still reasonable. To see someone else's submission, you would have to share their IP address, then just after they submit their form, submit yours and change the sid to match theirs; you must do this within 5 seconds.
Comment #59
Liam MorlandAs I was working on this, I had another idea. Anything that uses sessions will have a problem with users with cookies disabled. This will probably become a bigger issue with the new EU privacy laws. So, I came up with a no-cookie, no-session solution for anonymous users.
The solution uses a hash. Anonymous users get a hash of their submission data added to the query string of their confirmation page along with sid. When checking access for the confirmation page, the hash of the submission data is recalculated and has to match the hash in the query string. To view someone else's confirmation page, an attacker would have to guess the md5 hash. If brute force is a concern, a maximum age for confirmation pages could be used, like in the previous patch.
Comment #60
quicksketchThis looks pretty good. I was thinking about something like this also over in #810160: On confirmation page, use a hash parameter for SID.. Using the approach you've set out seems pretty effective, though we should add the site-specific "drupal_private_key" into the hash so that other sites can't generate the same hash by building a similar form and then md5ing the values.
Another pseudo-problem is that after the submission has been edited by an administrator the previous token becomes invalid. This probably isn't a huge concern but it's not expected behavior. I'd suggest a complete token similar to this:
The combination of submission ID and submission time are difficult get exactly correct (though not impossible for someone determined), but the addition of the Drupal private key (which is site-specific) makes guessing pretty well impossible. Better yet, all these keys stay permanent, so they won't be affected by edits to the data.
Comment #61
Liam MorlandUpdated as you suggest.
Comment #62
flexgrip CreditAttribution: flexgrip commentedIt seems like this family of patch removes the %webform tokens and uses token.module for all the replacement. Which is cool. But in terms of the confirmation message, this actually removes the ability to use %email_values to print out all submitted values for the form.
That may be what you guys were shooting for. So I don't mean to criticize. I just noticed this because I was using this patch to provide a pdf link to download the submitted form. The issue with that was that now the generated pdf doesn't have these values in it. Just %email_values printed in plain text.
I can get around this using [submission:values:?] as the token. However, with a form that has 50 questions on it. You have to go and find the field key for each individual field submitted. So this does not work when you get into multiple large forms.
Like I said, I am not commenting to say there is an error or bug in the patch. I just wanted others to read this, as this is a common issue.
This issue of making a [submission:values:ALL] token, would need a separate ticket.
Comment #63
quicksketchWe switched the 4.x version of the module to use normal Drupal 7 tokens in #1001798: Rewrite token replacement system to use D7 tokens.
You can already use simply [submission:values] and it will print out all the values, just like the previous %email_values. See http://drupal.org/node/1609324#tokens for conversions. :)
Comment #64
quicksketch@Liam Morland: This patch looks great!
Sorry this recommendation was a little dumb. There's no need to include serialize() in there since these things are all strings.
In webform_confirmation_page_access(), what's the need for this bit?
Is that needed in the event that an administrator is editing some one else's submission?
It'd be good to add PHPdocs to webform_confirmation_page_access(), and also webform_submission_access() even though I realize that's not new code added by this patch.
Comment #65
Liam MorlandYes, I should have caught that. I can roll another patch Friday.
The bit with webform_submission_access() allows an administrator to look at anyone's confirmation message if they want to.
I'll add documentation.
Comment #66
Liam MorlandNew version attached.
Comment #67
quicksketchThis looks great. I'll apply and test when I get a chance. Thanks Liam!
Comment #68
quicksketchAn interesting support/feature request that this issue may help with: #1712378: Allow Anonymous User to delete own entry. With adding permanent hashes that map to the submission, we could also use this hash for editing/viewing/deleting the actual submission itself.
Comment #69
finkdb CreditAttribution: finkdb commentedSubscribing
Comment #70
Liam MorlandThe hash used in this patch could also be used in #277870: Handle retraction of submission based for anonymous responders via email. (active version of #1712378: Allow Anonymous User to delete own entry).
Comment #71
quicksketchYep yep, this is high on my priority list Liam. The current patch looks great I just haven't had time to get it reviewed yet.
Comment #72
quicksketchThanks again Liam, this (and many others you've done) is a great patch!
I've committed this patch with a few changes:
- Removed the "type" of each @param and @return statement, though reading through the doc standards, I see this is now out of date: http://drupal.org/node/1354#param-return-data-type, We'll probably need to clean up Webform across the board for that documentation change.
- Switched your manual call to theme('token_tree') with the theme('webform_token_help') used throughout Webform for those looking to theme Webform's token replacement globally.
- Removed sid=x from *internal redirects*. We'd been doing this to assist in users wanting to replace tokens on pages other than the confirmation page URL, but unless we add the hash to those pages also, I think that method of token replacement should be discouraged since it's not secure. This annoyed people more than it helped anyway.
- Renamed "hash" in the URL to the more typical "token". This is the same string used in Flag and Fivestar modules, it's nice to maintain consistency.
Let me know if you find any problems with these changes. Committed to the 7.x-4.x branch.
Comment #73
Liam MorlandLooks good. Thanks!
Comment #74
chriscalip CreditAttribution: chriscalip commentedThis brought a smile to me. Thanks for the little pleasures and victory. good job everyone.
Comment #75
bayousoft CreditAttribution: bayousoft commentedWoohoo!
Comment #76
mstrelan CreditAttribution: mstrelan commentedGuessing this won't be ported back to Drupal 6?
Comment #77
quicksketch@mstrelan: No unfortunately. We're done adding features to Drupal 6 and the 3.x branch.
Comment #79
adam_b CreditAttribution: adam_b commentedDid this make it into 7.x-3.19? I'm still unable to use any %tokens in the confirmation field.
Comment #80
quicksketchNo, it's only in the 4.x branch.
Comment #81
astrosa530 CreditAttribution: astrosa530 commentedIs it possible to reference the hash token in webform confirmation emails? I'd like to be able to email anonymous users with a link that includes the token, so they can access the confirmation page later on.
Something like this:
http://testurl/node/webform/done?sid=%sid&token=%token or http://testurl/node/webform/done?sid=%sid&token=%get[token]
(noting that the tokens for the hash 'token' don't work right now).
Comment #82
Liam MorlandThe hash could be made available as a token. This should be requested as a new feature request issue.
Comment #83
arondeparon CreditAttribution: arondeparon commentedPlease note that a "simpler" fix is also possible by implementing hook_template_preprocess on the webform confirmation:
Comment #84
beertie CreditAttribution: beertie commentedComment #85
raj45 CreditAttribution: raj45 commentedI was looking for exactly this option (
[submission:values]
), after clicking on "Available tokens", but could only see[submission:values:?]
, where it seemed like I had to define specific fields. Perhaps the[submission:values]
token could be included in the list of avaliable tokens?Comment #86
Liam Morland@raj45: That should be a follow-up issue.
Comment #87
raj45 CreditAttribution: raj45 commentedI created a new issue here: #2496485: Include [submission:values] in the list of avaliable tokens
Comment #88
AnybodyIt would have been nice to have a patch or mini-module available for the webform 3.x branch. Some projects decided not to upgrade because of customizations. If someone has a good solution, please post it here.