This is tagged as duplicate of #139670: skip duplicate form submits the second.
Original issue description
So apparently it's quite easy in Drupal to post duplicate content. Simply press the "submit" button twice, whether creating a node, replying to a comment, etc...
While it's not easy to reproduce this on a clean install (since the site is so lightweight and fast) it's easy to reproduce this on any real site.
This is quite a problem and I've been encountering this for quite sometime.
So bad in fact that Robert created a module to prevent this: http://drupal.org/project/issues/formsingle
It's a rather simple module and this was before the concept of form tokens were introduced into Drupal. I imagine now it would be rather trivial to write a patch that checks to make a sure a token is only submitted and processed once.
So how about it? Any takers, unfort I have to run right now and can't look into this for a few days, but just wanted to post this to get this out there.
Comment | File | Size | Author |
---|---|---|---|
#99 | t_6.patch | 2.21 KB | m3avrck |
#97 | t_5.patch | 2.2 KB | m3avrck |
#86 | d_26.patch | 2.05 KB | m3avrck |
#81 | d_24.patch | 1.77 KB | m3avrck |
#80 | d_23.patch | 1.75 KB | m3avrck |
Comments
Comment #1
m3avrck CreditAttribution: m3avrck commentedSee this? It's a duplicate comment. Just proving my point :-)
Comment #2
m3avrck CreditAttribution: m3avrck commentedSee this? It's a duplicate comment. Just proving my point :-)
Comment #3
m3avrck CreditAttribution: m3avrck commentedHmm, can I get it more than twice? Depends on how fast the servers are at processing the request, on some very slow sites I've seen things duplicated up to 20 times.
Comment #4
m3avrck CreditAttribution: m3avrck commentedHmm, can I get it more than twice? Depends on how fast the servers are at processing the request, on some very slow sites I've seen things duplicated up to 20 times.
Comment #5
m3avrck CreditAttribution: m3avrck commentedHmm, can I get it more than twice? Depends on how fast the servers are at processing the request, on some very slow sites I've seen things duplicated up to 20 times.
Comment #6
m3avrck CreditAttribution: m3avrck commentedHmm, can I get it more than twice? Depends on how fast the servers are at processing the request, on some very slow sites I've seen things duplicated up to 20 times.
Comment #7
m3avrck CreditAttribution: m3avrck commentedHmm, can I get it more than twice? Depends on how fast the servers are at processing the request, on some very slow sites I've seen things duplicated up to 20 times.
Comment #8
m3avrck CreditAttribution: m3avrck commentedHmm, can I get it more than twice? Depends on how fast the servers are at processing the request, on some very slow sites I've seen things duplicated up to 20 times.
Comment #9
Caleb G2 CreditAttribution: Caleb G2 commentedI don't get it. What's the problem?
Comment #10
Caleb G2 CreditAttribution: Caleb G2 commentedI don't get it. What's the problem?
Comment #11
RobRoy CreditAttribution: RobRoy commentedYou guys, come on! Stop double posting! :P
Comment #12
RobRoy CreditAttribution: RobRoy commentedDang. I even suck a double posting. What's the secret?
Comment #13
m3avrck CreditAttribution: m3avrck commentedHave to a wait a split sec -- so that the web server gets the request, but hasn't responded yet -- then you can nail it, it would not be hard to get up to 100, albeit a bit boring :-)
Comment #14
m3avrck CreditAttribution: m3avrck commentedNow that Drupal.org has been upgrade to 5, just showing that this duplicate problem still persists :-)
Comment #15
m3avrck CreditAttribution: m3avrck commentedNow that Drupal.org has been upgrade to 5, just showing that this duplicate problem still persists :-)
Comment #16
m3avrck CreditAttribution: m3avrck commentedNow that Drupal.org has been upgrade to 5, just showing that this duplicate problem still persists :-)
Comment #17
m3avrck CreditAttribution: m3avrck commentedNow that Drupal.org has been upgrade to 5, just showing that this duplicate problem still persists :-)
Comment #18
m3avrck CreditAttribution: m3avrck commentedNow that Drupal.org has been upgrade to 5, just showing that this duplicate problem still persists :-)
Comment #19
m3avrck CreditAttribution: m3avrck commentedNow that Drupal.org has been upgrade to 5, just showing that this duplicate problem still persists :-)
Comment #20
m3avrck CreditAttribution: m3avrck commentedNow that Drupal.org has been upgrade to 5, just showing that this duplicate problem still persists :-)
Comment #21
Caleb G2 CreditAttribution: Caleb G2 commentedIf paired with something critical like, an ecommerce 'submit payment' function, couldn't this be considered critical? The time to address for 5.0 is quickly falling away (if not already gone).
Comment #22
m3avrck CreditAttribution: m3avrck commentedYes, IMO this is a critical issue. But in the sense of critical for drupal it doesn't break your site. But it opens up a whole other can of worms...
Comment #23
chx CreditAttribution: chx commentedI have doubts. I have seen many, many systems saying 'do no press this button twice' , payment systems using JavaScript to change the submit button to 'Please wait' and pressing it again does nothing. Of course, just because everyone else is wrong we can be right... can we?
If you try to solve this on core levels then you will soon hit fun problems with multiple tabs.
I believe ecommerce and anyone else aspiring can easily solve this by storing foo in session and removing it on submit. I do not mark this won't fix yet, let's discuss.
Comment #24
m3avrck CreditAttribution: m3avrck commentedchx, I agree with said points, here are a few more.
This solution *cannot* use some sort of JS/disable the button on submit. I've tried this and it won't work with Drupal. Reason because is because we rely on the value of the submit button (preview, delete, submit) and having it disabled doesn't send the value. I confirmed this with John Resig. Plus, it's too easy to have JS turned off, so that solution is out.
Yes, next up is the fact that you can have multiple buttons per node, but I don't feel this is a hindrance at all.
And your proposal of a SESSION variable is exactly on target with how Robert solved this issue in the form single module: http://drupal.org/project/issues/formsingle
However, this module was written before tokens were in core, so all of that logic could be removed. And when you remove a bit more because this functionality *could* live in core, you end up with relatively small patch that solves a relatively huge and annoying problem.
Going the route of $_SESSION and storing the form token and making sure it's only set once seems like the most logical route.
I tried looking at form.inc and doing this but my head soon exploded and I had quite an awful mess to clean up on my desk... :-p
Comment #25
robertDouglass CreditAttribution: robertDouglass commentedI can't promise that this will be *easy* to do, but storing the token in $_SESSION and removing it on submit seems the best solution. This is on my list of things to look at but not my top priority atm. I do want this in D6, though.
Comment #26
moshe weitzman CreditAttribution: moshe weitzman commentedUm, I don't see *significant* problems with disabling or hiding the button with JS. Natuarally the form is messed up if it gets submitted in this disabled state. Thats explicitly not allowed. Further, I know that this is not a solution for non js browsers. Thats OK too. A solution does not need to be 100% to be very useful. I see this as simpler than a session based solution, and thus more likely to get into core.
Comment #27
Caleb G2 CreditAttribution: Caleb G2 commentedPlease post a patch and mark this critical so that it has a snowball's chance of making it in D5. :)
Comment #28
m3avrck CreditAttribution: m3avrck commentedWell I wrote in my blog about the JS approach which is working *extremely* well for a high traffic site of mine:
http://tedserbinski.com/2007/01/11/how_to_prevent_duplicate_posts
Comment #29
Caleb G2 CreditAttribution: Caleb G2 commentedI see the blog post which contains part of what is needed to implement this and talk about the other part, but I think the problem is that with out an actual patch for people to test and see it working on their own install - it's just theory.
Comment #30
Stefan Nagtegaal CreditAttribution: Stefan Nagtegaal commented*subscribing*
Comment #31
robertDouglass CreditAttribution: robertDouglass commentedUses a slight variation of the $_SESSION strategy where every form gets a unique random token (which is not the same as #token or #build_id), and upon first submission this gets saved into $_SESSION, along with a timestamp. When the second request to submit that form comes along, it fails (form error "This form has already been submitted") because it matches the token with the token in the session.
There are ways to subvert this (using firebug to change the hidden value, for example), but users can no longer play the game of clicking the Submit button as often as possible and seeing who can submit the most times.
I tested opening a form in multiple tab; not only does this patch not conflict with that in any way, it successfully prevents multiple submissions from each tab.
My two questions are, does the first chunk of the patch hurt multipart forms in any way, and can this be done any more efficiently (fewer if clauses, less data in $_SESSION)?
Comment #32
robertDouglass CreditAttribution: robertDouglass commentedComment #33
robertDouglass CreditAttribution: robertDouglass commentedI should add that this doesn't apply to any form out of the box. You need to add this to a form in order to have it prevent multiple submissions:
$form['#prevent_multiple'] = TRUE;
I've added this to node and comment forms for testing. We need to decide whether other forms should have it too. The reason I didn't apply it to all forms is because some forms are designed for multiple submission (ajaxy forms, for example). Suggestions welcome.
Comment #34
robertDouglass CreditAttribution: robertDouglass commentedSo I screwed up when I changed strategy from putting the token into the session at first build time to putting it in at first submit time. Now, if you take the hidden token out of your form (using firebug, for example), you can still submit multiple times. I'll update the patch to the previous strategy.
Comment #35
robertDouglass CreditAttribution: robertDouglass commentedEaton pointed out that this should not be set if #programmed is TRUE. I'll add that to the next patch.
Comment #36
robertDouglass CreditAttribution: robertDouglass commentedSteef suggests that #prevent_multiple should be TRUE for all forms by default and those forms (like ajax forms) that need it turned off should do so explicitely. Opinions?
Comment #37
Stefan Nagtegaal CreditAttribution: Stefan Nagtegaal commentedThis is getting somewhere...
testing atm..
Comment #38
Zen CreditAttribution: Zen commentedDisable submit buttons after clicking, using JS = +1.
Preventing abuse / edge cases / non JS solution = solve with a contrib module. IMO, this should be handled with flood control using the flood table (that is what it's there for). The current patch appears to handle this similarly, but in a round-about way.
Obscure code = -1.
My 10p.
Thanks,
-K
Comment #39
Zen CreditAttribution: Zen commentedResetting title. I also don't believe that this is a bug. Setting to feature.
Thanks,
-K
Comment #40
robertDouglass CreditAttribution: robertDouglass commentedI disagree that it is a feature (it is a bug... unless you consider multiple submissions of the same form a feature?), and experience in the field shows that the JS solution does not work well enough.
There is a contrib module which solves this problem. I wrote it. But it requires doing a form_alter on every single form and keeping track of the cases where you want the protection and where you don't want the protection is impossible. Using my proposed solution form authors can turn it on or off, and contrib modules can do the same if they feel the need.
The code that I have written is nowhere near as obscure as the code surrounding it. If you want to -1 obscure code you'll probably want to delete the form_builder function from your Drupal installation right now.
Comment #41
Zen CreditAttribution: Zen commentedThis is like calling spam a bug. Nothing is broken. You are introducing a new feature to combat click abuse, that's it.
Your website is just facing momentary click abuse from obnoxious users. This is hardly a common problem. Moreover, as mentioned in my previous post, this can also be adequately controlled by something along the lines of a comment_control module that restricts users to say, 1 comment/node etc. a minute using the flood table. The infrastructure for this is already built into Drupal. Consequently, IMO, the solution being presented in this patch is redundant, overcomplicated and unnecessary.
As for obscurity, mea culpa.. s/obscure code/more obscure code/.
The real world problem is "double clicking" where (usually windows) users are so inured to their OS, that they double click everything. This is solved reasonably successfully via JS. The above mentioned flood control modules can, I believe, also be used in tandem to good benefit.
Thanks,
-K
P.S. Please respond to why you believe a flood control module will not work. In theory, it should be a simple and reasonably sound way to solve this.
Comment #42
m3avrck CreditAttribution: m3avrck commentedI agree that this is indeed a bug. Submitting a form twice for processing causes adverse effects--duplicate entries, potentially duplicate credit card entries so forth. Drupal should be smart to know if a form has been submitted once, that if it's submitted again it shouldn't do anything since it's already in the middle of processing the data.
A JS solution isn't full proof--easy enough to have JS off.
Comment #43
robertDouglass CreditAttribution: robertDouglass commented@Zen: Your proposed solution to this problem creates two extra database queries per form submission. Nobody will consider this as a viable option.
Comment #44
chx CreditAttribution: chx commentedI am not entering the debate whether this is a bug or a feature. I comment on http://drupal.org/files/issues/prevent_multiple.patch instead. First of all, you must not call such a clean up everytime drupal_get_form is called. Make it dependent on your attribute otherwise login form and search box suffers. Second, time is not enough, I beleive. Use microtime.
Comment #45
robertDouglass CreditAttribution: robertDouglass commentednote to self: fix the security hole in this line (thanks chx):
+ '#value' => isset($form['#post']['prevent_multiple']) ? $form['#post']['prevent_multiple'] : md5(mt_rand()),
Comment #46
Zen CreditAttribution: Zen commented@rDouglass - Fair enough. I don't believe Drupal core needs this, but it appears that I'm in the minority. Also, if this does go in, I think the contact form will also need it.
/me crawls back into his hole.
Thanks,
-K
Comment #47
m3avrck CreditAttribution: m3avrck commented// Protect against multiple submissions for an hour.
What if a user needs to create a bunch of nodes and is creating 1 every few minutes? I think a safer route would be a time limit of 1 minute -- enough to prevent duplicate submissions, but short enough to allow multiple postings.
Comment #48
Stefan Nagtegaal CreditAttribution: Stefan Nagtegaal commentedIsn't 8 till 10 sec. long enough??
Comment #49
robertDouglass CreditAttribution: robertDouglass commented@m3avrck, @Steef, that number only governs garbage collection. It is a compromise between a bloated $_SESSIONS table and the realization that a user could press submit, and before the page reloads, press the browsers "Stop" button, leaving the form open. With the 1 hour time for gc, they'd have to leave the window open for an hour, and browse with the same session in another window, before they'd be able to double submit. It is not a limit on how many form submissions they can make.
Comment #50
robertDouglass CreditAttribution: robertDouglass commentedBetter version. Harder to subvert (if at all possible). Now I save a token in the session when the form is first created, and when it gets submitted, that token has to be there for submission to succeed. When submission succeeds, I also save the destination of the form to the session (using the token as the key). This way, if the user multiple submits, instead of giving an ugly form error, I can redirect them to the destination of that form.
I also addressed eatons #programmed and chx's xss concerns.
Some common misunderstandings about this patch:
Problems:
Comment #51
robertDouglass CreditAttribution: robertDouglass commentedsmall cleanup
Comment #52
robertDouglass CreditAttribution: robertDouglass commentedrerolled with -F^f so chx can see what functions are affected =)
The first two hunks are garbage collection and can/should be completely rewritten. The rest (3 chunks) are the actual functionality.
Comment #53
robertDouglass CreditAttribution: robertDouglass commentedThe "need more choices" bit on Poll.module doesn't work. I'm investigating to confirm that this patch is the cause.
Comment #54
robertDouglass CreditAttribution: robertDouglass commentedNo, I was just using poll wrongly. You have to press "Preview" to get more choice fields.
Comment #55
m3avrck CreditAttribution: m3avrck commentedTested patch, works as advertised :-D
A few notes:
The rand isn't really needed, since you only need cleanup if either of those are true. Either that, or move that function call to system_cron() -- perhaps that is the best place.
Otherwise this is shaping up very nicely, great job Robert!
Comment #56
robertDouglass CreditAttribution: robertDouglass commented@m3avrck: The reason for the rand (soon to be mt_rand as per chx) is simply the overhead of doing this every time a form is built. The only reason to do garbage collection at all is to keep the session variable reasonably small, so it isn't a high priority to take care of every time we run this code. The test you propose would do the garbage collection every time any form was built.... which is too often imo. Still looking for a better gc algorithm.
The reason I don't use the #token in the form is because it is the same for every instance of a type of form. For example, every node/add/blog form would have the same token. Furthermore, whole classes of forms don't get this token at all. So unfortunately, it serves a totally different purpose and doesn't help us here.
Comment #57
robertDouglass CreditAttribution: robertDouglass commentedThere's nothing that can be done about the message. If people care about their messages they won't submit more than once.
Comment #58
m3avrck CreditAttribution: m3avrck commented^^ Hahah, ok.
As for cleanup, perhaps cleanup is run *only* when there are more than 10 entries or so in their $_SESSION? Wouldn't count() be faster than a mt_rand()?
Potentially the rand() might not run and it could get out of control, having it run when it reaches a limit might make more sense.
Comment #59
robertDouglass CreditAttribution: robertDouglass commentedWell a limit would be like saying we're willing to always tote around X entries, even if we don't need them. Plus, for active users who look at a lot of forms, it would make it so that they quickly exceed their limit and the gc code would get run every form build (multiple times per request in most cases). So eventually, rand will run the code, and by adjusting the number (1 out of 10, 1 out of 100, 1 out of 1000) we can tune it to what seems to work best. That was my thinking, anyway.
Comment #60
m3avrck CreditAttribution: m3avrck commentedOr, having it so 3 < rand(0,4) to run 20% of the time or something to that affect if we don't want to use the count() approach.
Comment #61
robertDouglass CreditAttribution: robertDouglass commentedMarking this D6 and needs review.
Comment #62
Dries CreditAttribution: Dries commentedThis sounds like a complex solution.
Rather than setting a token on creation, why don't we flatten the $form_values and compute a md5() hash on submit? (i.e. md5(print_r($form_values, TRUE))). We keep the last md5 hash in a $_SESSION variable. When the user submits a new form, we compute the md5 hash and compare it to the last md5-hash stored in a session variable. If they match, we don't call the submit handler. With this solution, we wouldn't need a garbage collection scheme ...
Comment #63
robertDouglass CreditAttribution: robertDouglass commentedI like the suggestion and will try it.
Comment #64
chx CreditAttribution: chx commentedAs usual Dries comes to the rescue. With this we only spend time on submit. And you really can store just one MD5 submit hash in your session because it's not a realistic situation that you have two tabs open, you click submit in one, switch, click submit there too, come back to the first and click submit quick enough again to create a duplicated post. Or, if you want to do this, have fun. The burden of processing falls on submit time not render time. Very nice solution.
Comment #65
m3avrck CreditAttribution: m3avrck commentedThat's a great idea!
Robert, any update on the patch?
Comment #66
robertDouglass CreditAttribution: robertDouglass commentedIt works. Almost. I can't get a duplicate submission on the comment form, but it doesn't have any affect on the Page or Story forms. Maybe someone can help figure out why.
Comment #67
robertDouglass CreditAttribution: robertDouglass commentedComment #68
m3avrck CreditAttribution: m3avrck commented!isset() will be faster than !empty()
Comment #69
Anonymous (not verified) CreditAttribution: Anonymous commentedComing in late to the conversation obviously. Has anyone thunk of a theme modification to disable the submit after the click? Please forgive me if this is a stupid idea, just say so and I'll shut up.
Comment #70
chx CreditAttribution: chx commentedtheme is not harry potter to say 'disappearatio!' it's HTML and we discussed that JS is no good solution.
Comment #71
moshe weitzman CreditAttribution: moshe weitzman commented@Earnie - your idea isn't stupid, so no forgiveness necessary there. But ...
You can answer your own question if you just read this web page. Is that so hard? If you can't even be bothered to that, search for the word javascript and you will get to the exact posts where this is discussed. Your unwillingness to do this and your past similar behavior indicate that you value your own time more than the time of others. Now all of us had to read your repetitive question. And such questions are even more wasteful on the development mail list where over 1000 people are reading. Please be respectful by doing adequate research before posting.
Comment #72
BioALIEN CreditAttribution: BioALIEN commentedWell put moshe. Back on topic, the webform.module uses a few methods to prevent multiple submits, but I believe Dries's suggestion is ultimately the best solution so far.
Just curious, how would this be handled if FAPI3 goes into D6?
Comment #73
Anonymous (not verified) CreditAttribution: Anonymous commentedYea I did that a little later in the night. I missed the JS discussion in the first pass of the thread. Sorry for the noise.
Robert's solution on the surface looks like it should work. I'll have to give it a try. It'll be a while later before I get back to this with results.
Comment #74
m3avrck CreditAttribution: m3avrck commentedHere's an updated patch. Changes:
Comment #75
m3avrck CreditAttribution: m3avrck commentedComment #76
jonfhancock CreditAttribution: jonfhancock commentedsubscribing
Comment #77
chx CreditAttribution: chx commentedwell, empty and isset are the same speed (they are both handled by ZEND_ISSET_ISEMPTY_VAR and only the return values differ). #programmed must be checked because if it's a programmed submit, no such check should occur.
Comment #78
m3avrck CreditAttribution: m3avrck commentedOk updated with the !#programmed check -- I took this out because I didn't think it would matter because $_SESSION wouldn't be set in that case for programmed forms? Or maybe not...
Comment #79
m3avrck CreditAttribution: m3avrck commentedUpdated patch after talking with chx on IRC that $redirect more often than not will be NULL but the form is still submitted so we need to keep track of that for this patch to work in all cases.
Comment #80
m3avrck CreditAttribution: m3avrck commentedOk, let's do the submit check correctly, shall we? Thanks to chx for explaining this to me :-)
Comment #81
m3avrck CreditAttribution: m3avrck commentedFix a possible notice as well, thanks chx again.
Comment #82
chx CreditAttribution: chx commentedAt this time, I would call this RTBC but I really would like two more people to look at it before this gets in: Adrian and Eaton. I do not want to end up with forms that do not get submitted...
Comment #83
webchicksubscribing
Comment #84
eaton CreditAttribution: eaton commentedI just took a slow look over the code and tested it on a number of forms. It seems to be working well and the logic appears sound; bailing out of the check when #programmed is true means that we won't accidentally kill automated programmed forms, and hashing the #post values means that multiple *different* submissions won't cause problems.
chx mentioned wanting two other opinions -- I'll defer to that 'Additional input from Adrian or another guru' and not RTBC it yet, but the patch has my +1.
Comment #85
eaton CreditAttribution: eaton commentedYeah, that should've stayed at 'needs review', not 'needs work.' I think it's RTBC but I too wouldn't mind another set of form eyes on it.
Adrian? Someone, activate th Vertice-Signal. :-)
Comment #86
m3avrck CreditAttribution: m3avrck commentedAfter talking with Heine and chx on IRC, we need a new flag so you can skip duplicate checking in your forms if you want to turn this feature off for whatever reason.
Comment #87
eaton CreditAttribution: eaton commentedWith the presence of that flag, I think it's officially a must-have.
Comment #88
webchickI actually would -1 the introduction of "yet another form API property" for some kind of theoretical 'someday developers might need to use this' kind of thing.
If a legitimate use case comes up, we can always add in the property later. For now, I'd keep it simple.
Comment #89
Heine CreditAttribution: Heine commentedLegitimate use cases:
- Searching twice for the same term.
From the comment_mover promotion block form:
Now, with this patch, one can't promote comments to the same node type in succession.
Comment #90
m3avrck CreditAttribution: m3avrck commentedFrom IRC:
Comment #91
robertDouglass CreditAttribution: robertDouglass commentedHeine, are you sure you can't submit that form twice? It doesn't get rebuilt in between requests? If it gets rebuilt, and you can't resubmit it, then there is a flaw in the patch. Let me know if this is the case, and how to recreate, and I'll see if there is a workaround. As long as a form gets newly built, it should be able to be submitted.
Comment #92
m3avrck CreditAttribution: m3avrck commentedThis patch does not break search from what I can tell. And bonus, it works with poll module :-p
Talked with Robert and he set this to "needs review" because the above wasn't tested--now it appears to be good.
Comment #93
Heine CreditAttribution: Heine commentedRight. I'll retract my comments above.
Comment #94
Dries CreditAttribution: Dries commentedLooks great! Job well done. Committed to CVS HEAD. Thanks all.
Comment #95
m3avrck CreditAttribution: m3avrck commentedI think this should be committed to 5.x too...
Comment #96
webchickDoesn't apply to 5.
Comment #97
m3avrck CreditAttribution: m3avrck commentedNow it applies to 5 :-) I left out the $goto = NULL part since we don't have that notice checking in 5 and that is why the hunk failed because of the extra isset checks.
Comment #98
drummDrupal 5 isn't an excuse for sloppy coding. Define your $goto variable.
Comment #99
m3avrck CreditAttribution: m3avrck commentedOk.
Comment #100
drummCommitted to 5.
Comment #101
(not verified) CreditAttribution: commentedComment #102
fagopeople interested on this, please have a look at this issue, which tries to further improve this
Comment #103
Crimson CreditAttribution: Crimson commentedThe code works well but I didn't see it in Drupal 5.5? Was this scrapped for something else? Or was it not fully committed?
Comment #104
Heine CreditAttribution: Heine commentedIt was removed in http://drupal.org/node/141636
Comment #105
Heine CreditAttribution: Heine commentedhttp://drupal.org/node/139670 is the second attempt to prevent duplicate submissions.
Comment #106
Crimson CreditAttribution: Crimson commentedThanks. It's such a bummer that this isn't solved yet.
How about we implement a time period enforcement between form processes or something like that?
Comment #107
mrgoltra CreditAttribution: mrgoltra commentedsubscribing
Comment #108
m3avrck CreditAttribution: m3avrck commentedBest bet is still the JS method: http://drupal.org/node/107358#comment-487851
This will automatically be built into my new theme that is due out early Feb: http://drupal.org/project/blueprint
Comment #109
Fanaile CreditAttribution: Fanaile commentedOkay, please forgive me. I'm new to drupal and some of this goes completely over my head.
However, I have just spent a couple of hours reading every comment and visiting every link on this page.
A) I downloaded the formsingle module; it does stop users from submitting duplicate posts. However, when I was testing it out on one test site, (using the aforementioned 'click as many times as you can' method) it also prevented me from even seeing the page (or the comment) until after I left the page and clicked back to it. This, I fear, will just frustrate users and they'll retype their comment/blog post and submit again anyway - which negates the entire use of having the module.
B) Go ahead and call me stupid, but where would I put the code found on your blog? I've read through the post on your blog, and the comments here, and the formsingle page/s, and cannot find where it says to the code - only that to date it is the best solution for this problem? Would I place it into a settings.php file? I realize this might seem like a basic question, but I'd appreciate an answer.
Thanks.
Comment #110
m3avrck CreditAttribution: m3avrck commentedYou would need to place it in your theme.
Luckily, my new base/starter theme, http://drupal.org/project/blueprint which is coming out in a week or so, has this functionality, and a lot more built in, all documented. It will all be documented on my blog too: http://tedserbinski.com/ -- seeing the theme and how it is integrated would probably make the most sense.
http://cvs.drupal.org/viewvc.py/drupal/contributions/themes/blueprint/
See the template.php which includes a JS file which source is in the "scripts" directory. That is how you basically use the JS.
Comment #111
Fanaile CreditAttribution: Fanaile commentedThank you for your time and answer :)
I think I will need to wait until your theme is finished. I found the code in your JS files, but couldn't find the lines in your template.php file that called it (I was looking to see a working example). I'll keep checking and will watch for the release :)
I've also bookmarked your blog to help me follow.
Thank you, again!
Naomi
Comment #112
kzuser CreditAttribution: kzuser commentedHi, where exactly put patch code in form.inc?
Comment #114
VM CreditAttribution: VM commentedchanged status and remainder of dropdowns back to what they were before.
_____________________________________________________________________
My posts & comments are usually dripping with sarcasm.
If you ask nicely I'll give you a towel : )
Comment #115
kzuser CreditAttribution: kzuser commentedyeah i read that post but again where put that code in form.inc?
Comment #116
VM CreditAttribution: VM commentedA) there is no need to assign this issue to yourself if you aren't providing a patch
B) the method for applying patches can be found in the handbooks, do a search for applying patches. http://drupal.org/search/node/applying+patches
C) Following the links through out the threads, It seems this has been deemed a "won't fix" at core level. see: http://drupal.org/node/139670 (though this may not be the final discussion on this matter)
Comment #117
kzuser CreditAttribution: kzuser commentedstill not understand
same user again post that js method better than others
but i cant understand how to make it in form.inc?
Comment #118
VM CreditAttribution: VM commentedyou have two choices when it comes to applying patches:
do it by hand + means add a line - means delete a line. I don't suggest this method
To apply patches the best method is : using the handbook page I pointed you to: http://drupal.org/patch/apply
This page will explain in detail how to apply patches to your files. It is done at the command prompt on your local system. You don't explain what OS you are using. That being said I can't explain further what exactly you need to do for what you are running. There is a few videocasts explaining how to set up cygwin on windows. Which is what I use. The videocast was done by addie @ lullabot, see: http://drupal.org/node/181837
Please stop adjusting the drop downs. It's unnecessary. You can comment on this thread without changing any of the dropdowns and those involved in the issue with get emails and have this post bumped up on their tracker without you doing anything more then commenting.
Comment #119
kzuser CreditAttribution: kzuser commentedi use windows on desktop
and linux on hosting
Comment #120
kzuser CreditAttribution: kzuser commentedComment #121
VM CreditAttribution: VM commentedHeine, closed this issue for a reason, I think you should consider respecting this fact.
You've been pointed to the proper documentation for patching on a windows system, including but not limited to a videocast showing you how to accomplish this task.
apply the patch your local system (windows) using the proper documentation and video cast, Then upload the patched files to your installation. Understand that I can't say whether the patches apply cleanly on a 5.7 drupal, if you are even using the lastest release. That being said, you may have to tweak the patch, or wait for a bonafied solution from core developers on how to avoid this type of problem. Until that time, you may choose, as others have to deal with duplicate postings as drupal.org does. By removing them when found.
Comment #122
kzuser CreditAttribution: kzuser commentedim not Heine
Comment #123
drummThat makes more sense without a comma:
Heine closed this issue for a reason, I think you should consider respecting this fact.
This issue is a duplicate of http://drupal.org/node/139670.
kzuser- please stop moving around this issue status. This is not a support forum for applying patches, it is a tool for Drupal contributors to collaborate. Using it improperly wastes time of contributors and could be considered spamming. As mentioned above, there is documentation for applying patches, such as http://drupal.org/patch/apply. More support options are at http://drupal.org/support.
Comment #124
Anonymous (not verified) CreditAttribution: Anonymous commentedCould we not prevent multiple form processing during node_save() as follows ..
function node_save(&$node) {
global $user;
$node->is_new = FALSE;
// Apply filters to some default node fields:
if (empty($node->nid)) {
// Insert a new node.
$node->is_new = TRUE;
$node->nid = db_next_id('{node}_nid');
$node->vid = db_next_id('{node_revisions}_vid');
}
else {
// We need to ensure that all node fields are filled.
$node_current = node_load($node->nid);
foreach ($node as $field => $data) {
$node_current->$field = $data;
}
$node = $node_current;
if ($node->revision) {
$node->old_vid = $node->vid;
$node->vid = db_next_id('{node_revisions}_vid');
}
}
..
$ip = $_SERVER['REMOTE_ADDR'] ;
if (!isset($_SESSION[$ip]) || ( isset($_SESSION[$ip]) && (time() - $_SESSION[$ip]['timestamp'] > TIME_INTERVAL))) {
$_SESSION[$ip] = array('timestamp' => time() , 'node' => $node->vid);
} elseif ( time() - $_SESSION[$ip]['timestamp'] < TIME_INTERVAL) {
drupal_goto('node/'.$_SESSION[$ip]['node']);
}
..
}
Comment #125
james2002 CreditAttribution: james2002 commentedIf an article is accessible via two paths
e.g.
http://sciencelatest.com/node/2
and
http://sciencelatest.com/gene-regulation
point to same page as I change the path via url alias.
It will not be good for SEO.
How do I make first post to disappear or is there any SEO module for this kind of duplicated content?
thanks
Web hosting sites
Comment #126
treksler CreditAttribution: treksler commentedWith the latest jquery, the javascript becomes
what is the best way to ensure that this only gets included in pages that have forms??
i don't want to load jquery on every page if i don't have to
Comment #127
Optalgin CreditAttribution: Optalgin commentedI've created a module to include this jQuery snippet on selected pages
check it out here
You can select the pages you want the script to load
the default pages are node/add/* and node/*/edit
That covers most node creation forms
Comment #128
Dinesh Kumar Sarangapani CreditAttribution: Dinesh Kumar Sarangapani commentedyes
Comment #134
VM CreditAttribution: VM commentedshifting version back from the change in #128. Not sure why Dinesh Kumar altered it.
Comment #135
oliverpolden CreditAttribution: oliverpolden commentedRealise this is an old post but to help others with this issue:
The Global Redirect module does this:
https://drupal.org/project/globalredirect
However I am unsure if the Redirect module, which appears to be Global Redirect's successor, will do this also. Comments?
https://drupal.org/project/redirect
Comment #135.0
oliverpolden CreditAttribution: oliverpolden commentedIssue summary should link to the duplicate
Comment #136
Tromppa CreditAttribution: Tromppa commentedI had the same problem on my site and installed this module. https://drupal.org/project/hide_submit. Now it works perfectly!