Introducing: Gravity Forms Duplicate Prevention Plugin

Recently we had an interesting client support issue: the client was getting an unruly number of identical entries on their Gravity Forms (a popular WordPress form plugin) -based surveys. Typically a duplicate here or there doesn’t really matter, but this particular client was using the surveys in classrooms full of impatient, click-hungry kids. Our client was seeing exact duplicate submissions from the same classroom at the same time, sometimes inflating the number of submissions from a class well over the number of survey respondents.

We were able to purge the existing duplicate survey results but the client needed a way to prevent this problem from cropping up again. Google searches for “Gravity Forms duplicate prevention” yielded nothing useful (the surveys don’t collect things like email addresses that we could use to simply prevent duplicates based on a given field), so we had to think outside the box. The team, full of people who use and love open source software, also decided that we would package up and release our solution back to the WordPress community. As a result, Buckeye Interactive developed its first (public) WordPress plugin, Gravity Forms Duplicate Prevention.

We had three major goals with the plugin:

  • Prevent duplicate submissions
  • Make it flexible enough to work without modification to existing forms
  • Work both with or without javascript

Visual Feedback

There’s a concept within User Experience (UX) design called “Visual Feedback” which, at a high level, is simply responding to user interaction. This could be a progress bar, a hover state on a link, or a depressed state on a button after a user clicks it. Visual feedback is a cornerstone of good interface design and in this instance we found that the survey generated by Gravity Forms was not effective enough in its feedback: the user clicked a submit button and nothing seemed to happen so the user clicked it again.

Our first step to preventing duplicate entries was to fix this obvious flaw in the form submission button’s visual feedback. Using a bit of javascript the plugin disables the submit button after the first click. For the overwhelming majority of users with javascript enabled, this fixes the problem – you can’t double-click a button that quickly disables itself after a single click.

Unfortunately, it’s not acceptable to rely on javascript for everything. What if a user is on a slow system and has disabled javascript for performance reasons? Or, worse yet, what if the user loves javascript but his/her old browser can’t process it quickly enough to be effective? Since this fix was scheduled to be publicly released, we needed a solution that could work for anyone.

Enter the Honeypot

A honeypot is a sort of trap that programmers can set to catch unauthorized users of a system. Gravity Forms has a built-in honeypot mechanism that will randomly add an extra field to a form with instructions for the user to leave that input empty. If the field is not empty upon submission, Gravity Forms will assume the form was filled out by an automated spam script (which likely doesn’t know how to read instructions) and will silently discard the entry (the last part is important and will come into play shortly).

WordPress has nice hooks and filters API that allows plugin developers to hook into different points throughout the execution of a page. Gravity Forms makes excellent use of these hooks to allow third-party developers to tie into the lifecycle of a form submission. In the case of our plugin we used the gform_validation filter, which allows Gravity Forms developers to create custom validation logic.

When a form is submitted, we generate a cryptographic hash of the user data and and store it in a short-lived PHP user session. If the next submission matches the hash we can be almost certain the submission is a duplicate (the chances of an md5 hash collision – two different strings producing the exact same hash – are 1 in 340 undecillion or 340 trillion trillion trillion). If the submitted form’s hash matches our stored value we simply manipulate the form data so that it falls prey to the honeypot, thus tricking Gravity Forms into quietly ignoring the duplicate entry.

The advantage of this approach lies in the fact that we’re not comparing form data to the database (in the case of anonymous surveys it’s perfectly acceptable for two users to have the same answers) but instead to the individual users’ most recent submission. We’re also not penalizing a user for double-clicking (not everyone realizes that it’s not only unnecessary, but problematic, on web forms) nor are we causing site owners to modify their forms.

Wrapping Up

Gravity Forms Duplicate Prevention is available now in the WordPress.org plugin repository and its source is available on Github. If you have any questions, run into any issues, or have any features you’d like to see please get in touch with us or send us a pull request on Github!

Related Posts

Developers collaborate to launch a client-focused site successfully and efficiently.
Having an up-to-date website can be a clear contributor of success.
Life as a developer at Buckeye Innovation: Hear from our team members themselves.

Want to Connect?