Skip to content

Preventing duplicate posts: part 2

2 min read

In a previous article, I wrote about how to use jQuery to remove submit form buttons and replacing it with some “Saving…” text to prevent duplicate form submissions.

While this works well, it only works about 90-95% of the time–rest of the time the user either reloads the page and resubmits or has JavaScript off.

Then what do you do?

Well I originally helped write a patch to prevent duplicate form submissions in Drupal 5 and it lived for a bit but was recently removed because of the complexity and breakage it introduced. And it didn’t work all the time either I discovered :-)

And now, as MothersClick is growing quite fast, we’re hitting this duplicate issue a couple times, which is greatly exacerbated by our integration with groups and email notifications–a duplicate post is now a duplicate email, eek!

So here’s how I solved it for our site. Create a new module for your site, and use hook_nodeapi and hook_comment to catch duplicates before they are saved into the database.

Here’s the code for hook_nodeapi:

/**
 * Implementation of hook_nodeapi().
 */
function YOUR-MODULE_nodeapi(&$node, $op, $teaser, $page) { 
  switch ($op) {  
    case 'validate':
      // find a duplicate node of the same type with the same title
      // compare the created time of the duplicate node to now, if it is within the past 6 minutes this is very likely a duplicate
      $duplicate = db_result(db_query("SELECT nid FROM {node} WHERE type = '%s' AND title = '%s' AND (created >= %d - 360) LIMIT 1", $node->type, $node->title, time()));

      if ($duplicate > 0) {
        // since is most likely a duplicate, set an error so a duplicate isn't created
        form_set_error('title', t('<a href="!url">A duplicate entry has been found</a>. This usually results from clicking the submit button more than once. If you are having trouble, please <a href="!contact">contact us</a>.', array('!url' => url('node/'. $duplicate), '!contact' => url('contact'))));
      }

      break;     
  }
}

And the code for hook_comment:

/**
 * Implementation of hook_comment().
 */
function YOUR-MODULE_comment($a1, $op) {
  switch ($op) {
    case 'validate':
      // find a duplicate comment with the same body, since the subject is not required
      // compare the timestamp of the duplicate comment to now, if it is within the past 6 minutes this is very likely a duplicate
      $duplicate = db_result(db_query("SELECT cid FROM {comments} WHERE nid = %d AND comment = '%s' AND (timestamp >= %d - 360) LIMIT 1", $a1['nid'], $a1['comment'], time()));

      if ($duplicate > 0) {
        // since is most likely a duplicate, set an error so a duplicate isn't created
        form_set_error('comment', t('<a href="!url">A duplicate entry has been found</a>. This usually results from clicking the submit button more than once. If you are having trouble, please <a href="!contact">contact us</a>.', array('!url' => url('node/'. $a1['nid'], NULL, 'comment-'. $duplicate), '!contact' => url('contact'))));
      }

      break;
  }
}

While this isn’t a 100% guarantee to stop duplicate content, it is now stopping all duplicate content we have seen–and, what makes a better usability test case than your mom? :-)

And while you’re at it, why not add a nice performance boost to your site? Remove comment modules duplicate SQL checksince it actually doesn’t do anything but produce a watchdog warning, which isn’t helpful.

Should this go into Drupal 6? Well yes, but this might not be most optimal generic solution for everyone, but for MothersClick and my related projects, it’s good enough for me :-)

codeDrupal

Related Posts

Members Public

The Future of Automotive Mobility will be Powered by Open Source Software

Automotive companies are shifting from bending metal to bending bits. Soon they will be offering software and services to complement their manufactured metal. In order to win in the market, they will need to embrace open-source software to build leverage and enhance their offering.

Members Public

How to Host Your Static Website on Amazon S3: Step-by-Step Guide

1. Login to your Amazon AWS account 2. Create a new hosted zone for your domain using Route 53 3. Copy the NS records for this zone to your domain provider (e.g., GoDaddy) 4. Edit your domain on your domain registrar (e.g., GoDaddy) by clicking Set Nameservers 5.

Members Public

Book Review: Drupal 7 Module Development

Well, it’s been a while my Drupal friends, almost 18 months… dusting off this old Drupal 6 blog and time to start posting again. And what better way to get started again than by talking about Drupal 7, by far the best release of Drupal. And with almost 7